Merge "Add pp_propname_page index to page_props"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 25 Feb 2013 22:54:48 +0000 (22:54 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 25 Feb 2013 22:54:48 +0000 (22:54 +0000)
1007 files changed:
.gitignore
CREDITS
HISTORY
INSTALL
RELEASE-NOTES-1.21
StartProfiler.sample
api.php
bin/ulimit5.sh [deleted file]
composer.json [new file with mode: 0644]
docs/hooks.txt
img_auth.php
includes/Action.php
includes/ArrayUtils.php
includes/Article.php
includes/AutoLoader.php
includes/Block.php
includes/Category.php
includes/Categoryfinder.php
includes/Cdb.php
includes/Cdb_PHP.php
includes/ChangeTags.php
includes/ChangesFeed.php
includes/ChangesList.php
includes/Collation.php
includes/ConfEditor.php
includes/Cookie.php
includes/CryptRand.php
includes/DefaultSettings.php
includes/Defines.php
includes/DeprecatedGlobal.php
includes/EditPage.php
includes/Exception.php
includes/Export.php
includes/ExternalEdit.php
includes/ExternalUser.php
includes/FakeTitle.php
includes/Feed.php
includes/FeedUtils.php
includes/FileDeleteForm.php
includes/ForkController.php
includes/GitInfo.php
includes/GlobalFunctions.php
includes/HTMLForm.php
includes/HistoryBlob.php
includes/Hooks.php
includes/Html.php
includes/HttpFunctions.php
includes/IP.php
includes/ImageGallery.php
includes/ImagePage.php
includes/Import.php
includes/LinkFilter.php
includes/Linker.php
includes/LinksUpdate.php
includes/MagicWord.php
includes/Message.php
includes/Metadata.php
includes/MimeMagic.php
includes/Namespace.php
includes/OutputPage.php
includes/PHPVersionError.php
includes/Pager.php
includes/PathRouter.php
includes/Preferences.php
includes/PrefixSearch.php
includes/ProtectionForm.php
includes/ProxyTools.php
includes/RecentChange.php
includes/Revision.php
includes/Sanitizer.php
includes/Setup.php
includes/SiteConfiguration.php
includes/SiteStats.php
includes/Skin.php
includes/SkinLegacy.php
includes/SkinTemplate.php
includes/SpecialPage.php
includes/SpecialPageFactory.php
includes/SqlDataUpdate.php
includes/SquidPurgeClient.php
includes/Status.php
includes/StringUtils.php
includes/StubObject.php
includes/Title.php
includes/UIDGenerator.php [new file with mode: 0644]
includes/User.php
includes/UserMailer.php
includes/WatchedItem.php
includes/WebRequest.php
includes/WebResponse.php
includes/WebStart.php
includes/Wiki.php
includes/WikiFilePage.php
includes/WikiPage.php
includes/Xml.php
includes/ZipDirectoryReader.php
includes/actions/HistoryAction.php
includes/actions/InfoAction.php
includes/actions/PurgeAction.php
includes/actions/RawAction.php
includes/api/ApiBase.php
includes/api/ApiBlock.php
includes/api/ApiComparePages.php
includes/api/ApiCreateAccount.php
includes/api/ApiDelete.php
includes/api/ApiDisabled.php
includes/api/ApiEditPage.php
includes/api/ApiEmailUser.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFeedContributions.php
includes/api/ApiFeedWatchlist.php
includes/api/ApiFileRevert.php
includes/api/ApiFormatBase.php
includes/api/ApiFormatDbg.php
includes/api/ApiFormatDump.php
includes/api/ApiFormatNone.php
includes/api/ApiFormatPhp.php
includes/api/ApiFormatTxt.php
includes/api/ApiFormatWddx.php
includes/api/ApiFormatXml.php
includes/api/ApiHelp.php
includes/api/ApiImport.php
includes/api/ApiLogout.php
includes/api/ApiMain.php
includes/api/ApiModuleManager.php [new file with mode: 0644]
includes/api/ApiMove.php
includes/api/ApiOpenSearch.php
includes/api/ApiOptions.php
includes/api/ApiPageSet.php
includes/api/ApiParamInfo.php
includes/api/ApiParse.php
includes/api/ApiPatrol.php
includes/api/ApiProtect.php
includes/api/ApiPurge.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllMessages.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryBlocks.php
includes/api/ApiQueryCategoryMembers.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryDisabled.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryInfo.php
includes/api/ApiQueryLinks.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryORM.php
includes/api/ApiQueryPageProps.php
includes/api/ApiQueryQueryPage.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryStashImageInfo.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiQueryUsers.php
includes/api/ApiResult.php
includes/api/ApiRollback.php
includes/api/ApiRsd.php
includes/api/ApiSetNotificationTimestamp.php
includes/api/ApiTokens.php
includes/api/ApiUnblock.php
includes/api/ApiUndelete.php
includes/api/ApiUpload.php
includes/api/ApiUserrights.php
includes/api/ApiWatch.php
includes/cache/BacklinkCache.php
includes/cache/CacheDependency.php
includes/cache/FileCacheBase.php
includes/cache/HTMLFileCache.php
includes/cache/LocalisationCache.php
includes/cache/MessageCache.php
includes/cache/SquidUpdate.php
includes/clientpool/RedisConnectionPool.php [new file with mode: 0644]
includes/content/AbstractContent.php
includes/content/Content.php
includes/content/ContentHandler.php
includes/content/WikitextContent.php
includes/context/RequestContext.php
includes/db/CloneDatabase.php
includes/db/Database.php
includes/db/DatabaseError.php
includes/db/DatabaseIbm_db2.php
includes/db/DatabaseMssql.php
includes/db/DatabaseMysql.php
includes/db/DatabaseOracle.php
includes/db/DatabasePostgres.php
includes/db/DatabaseSqlite.php
includes/db/DatabaseUtility.php
includes/db/IORMRow.php
includes/db/LBFactory.php
includes/db/LBFactory_Multi.php
includes/db/LoadBalancer.php
includes/db/LoadMonitor.php
includes/db/ORMIterator.php
includes/db/ORMTable.php
includes/diff/DairikiDiff.php
includes/diff/DifferenceEngine.php
includes/diff/WikiDiff3.php
includes/externalstore/ExternalStore.php
includes/externalstore/ExternalStoreDB.php
includes/externalstore/ExternalStoreHttp.php
includes/externalstore/ExternalStoreMedium.php [new file with mode: 0644]
includes/externalstore/ExternalStoreMwstore.php [new file with mode: 0644]
includes/filebackend/FSFile.php
includes/filebackend/FSFileBackend.php
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendGroup.php
includes/filebackend/FileBackendMultiWrite.php
includes/filebackend/FileOp.php
includes/filebackend/SwiftFileBackend.php
includes/filebackend/lockmanager/DBLockManager.php
includes/filebackend/lockmanager/FSLockManager.php
includes/filebackend/lockmanager/LSLockManager.php
includes/filebackend/lockmanager/LockManager.php
includes/filebackend/lockmanager/LockManagerGroup.php
includes/filebackend/lockmanager/MemcLockManager.php
includes/filebackend/lockmanager/QuorumLockManager.php [new file with mode: 0644]
includes/filerepo/FSRepo.php
includes/filerepo/FileRepo.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/RepoGroup.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/File.php
includes/filerepo/file/ForeignAPIFile.php
includes/filerepo/file/ForeignDBFile.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php
includes/filerepo/file/UnregisteredLocalFile.php
includes/installer/CliInstaller.php
includes/installer/DatabaseInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/InstallDocFormatter.php
includes/installer/Installer.i18n.php
includes/installer/Installer.php
includes/installer/MysqlInstaller.php
includes/installer/MysqlUpdater.php
includes/installer/OracleInstaller.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/WebInstaller.php
includes/installer/WebInstallerOutput.php
includes/installer/WebInstallerPage.php
includes/interwiki/Interwiki.php
includes/job/Job.php
includes/job/JobQueue.php
includes/job/JobQueueAggregator.php [new file with mode: 0644]
includes/job/JobQueueAggregatorMemc.php [new file with mode: 0644]
includes/job/JobQueueAggregatorRedis.php [new file with mode: 0644]
includes/job/JobQueueDB.php
includes/job/JobQueueGroup.php
includes/job/JobQueueRedis.php [new file with mode: 0644]
includes/job/jobs/DoubleRedirectJob.php
includes/job/jobs/DuplicateJob.php
includes/job/jobs/EmaillingJob.php
includes/json/Services_JSON.php
includes/libs/CSSJanus.php
includes/libs/GenericArrayObject.php
includes/libs/IEContentAnalyzer.php
includes/limit.sh [new file with mode: 0644]
includes/logging/LogEventsList.php
includes/logging/LogFormatter.php
includes/logging/LogPage.php
includes/logging/LogPager.php
includes/media/BMP.php
includes/media/BitmapMetadataHandler.php
includes/media/DjVu.php
includes/media/DjVuImage.php
includes/media/Exif.php
includes/media/ExifBitmap.php
includes/media/FormatMetadata.php
includes/media/GIF.php
includes/media/GIFMetadataExtractor.php
includes/media/IPTC.php
includes/media/ImageHandler.php
includes/media/Jpeg.php
includes/media/MediaHandler.php
includes/media/MediaTransformOutput.php
includes/media/PNG.php
includes/media/PNGMetadataExtractor.php
includes/media/SVG.php
includes/media/SVGMetadataExtractor.php
includes/media/Tiff.php
includes/media/XCF.php
includes/media/XMP.php
includes/media/XMPInfo.php
includes/media/XMPValidate.php
includes/normal/RandomTest.php
includes/normal/Utf8CaseGenerate.php
includes/normal/Utf8Test.php
includes/normal/UtfNormal.php
includes/normal/UtfNormalBench.php
includes/normal/UtfNormalDefines.php
includes/normal/UtfNormalGenerate.php
includes/normal/UtfNormalMemStress.php
includes/normal/UtfNormalTest.php
includes/normal/UtfNormalTest2.php
includes/objectcache/BagOStuff.php
includes/objectcache/EhcacheBagOStuff.php
includes/objectcache/HashBagOStuff.php
includes/objectcache/MemcachedBagOStuff.php
includes/objectcache/MemcachedClient.php
includes/objectcache/MemcachedPhpBagOStuff.php
includes/objectcache/ObjectCache.php
includes/objectcache/RedisBagOStuff.php
includes/objectcache/SqlBagOStuff.php
includes/parser/CoreLinkFunctions.php
includes/parser/CoreParserFunctions.php
includes/parser/DateFormatter.php
includes/parser/LinkHolderArray.php
includes/parser/Parser.php
includes/parser/ParserCache.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/parser/Parser_LinkHooks.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php
includes/parser/Preprocessor_HipHop.hphp [deleted file]
includes/parser/StripState.php
includes/parser/Tidy.php
includes/profiler/Profiler.php
includes/profiler/ProfilerSimple.php
includes/profiler/ProfilerSimpleText.php
includes/profiler/ProfilerSimpleTrace.php
includes/profiler/ProfilerSimpleUDP.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevisionDelete.php
includes/search/SearchEngine.php
includes/search/SearchIBM_DB2.php
includes/search/SearchMssql.php
includes/search/SearchMySQL.php
includes/search/SearchOracle.php
includes/search/SearchPostgres.php
includes/search/SearchSqlite.php
includes/search/SearchUpdate.php
includes/site/MediaWikiSite.php
includes/site/Site.php
includes/site/SiteArray.php [deleted file]
includes/site/SiteList.php
includes/site/SiteObject.php [deleted file]
includes/site/SiteSQLStore.php [new file with mode: 0644]
includes/site/SiteStore.php [new file with mode: 0644]
includes/site/Sites.php [deleted file]
includes/site/SitesTable.php [deleted file]
includes/specials/SpecialAllmessages.php
includes/specials/SpecialAllpages.php
includes/specials/SpecialBlankpage.php
includes/specials/SpecialBlock.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialBooksources.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialCategories.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialChangePassword.php
includes/specials/SpecialComparePages.php
includes/specials/SpecialConfirmemail.php
includes/specials/SpecialContributions.php
includes/specials/SpecialDeletedContributions.php
includes/specials/SpecialDisambiguations.php
includes/specials/SpecialDoubleRedirects.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialExport.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialImport.php
includes/specials/SpecialLinkSearch.php
includes/specials/SpecialListfiles.php
includes/specials/SpecialListgrouprights.php
includes/specials/SpecialListusers.php
includes/specials/SpecialMostlinkedtemplates.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialNewimages.php
includes/specials/SpecialNewpages.php
includes/specials/SpecialPasswordReset.php
includes/specials/SpecialPopularpages.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialProtectedtitles.php
includes/specials/SpecialRandompage.php
includes/specials/SpecialRandomredirect.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRecentchangeslinked.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialSearch.php
includes/specials/SpecialSpecialpages.php
includes/specials/SpecialStatistics.php
includes/specials/SpecialUnblock.php
includes/specials/SpecialUncategorizedcategories.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/templates/Usercreate.php
includes/templates/Userlogin.php
includes/upload/PublishStashedFile.php
includes/upload/UploadBase.php
includes/upload/UploadFromChunks.php
includes/upload/UploadStash.php
languages/Language.php
languages/Names.php
languages/classes/LanguageHy.php
languages/classes/LanguageKu.php
languages/classes/LanguageRu.php
languages/classes/LanguageSr.php
languages/data/plurals.xml
languages/messages/MessagesAce.php
languages/messages/MessagesAf.php
languages/messages/MessagesAm.php
languages/messages/MessagesAn.php
languages/messages/MessagesAr.php
languages/messages/MessagesArc.php
languages/messages/MessagesAry.php
languages/messages/MessagesArz.php
languages/messages/MessagesAs.php
languages/messages/MessagesAst.php
languages/messages/MessagesAvk.php
languages/messages/MessagesAz.php
languages/messages/MessagesAzb.php
languages/messages/MessagesBa.php
languages/messages/MessagesBar.php
languages/messages/MessagesBcc.php
languages/messages/MessagesBcl.php
languages/messages/MessagesBe.php
languages/messages/MessagesBe_tarask.php
languages/messages/MessagesBg.php
languages/messages/MessagesBh.php
languages/messages/MessagesBho.php
languages/messages/MessagesBjn.php
languages/messages/MessagesBn.php
languages/messages/MessagesBpy.php
languages/messages/MessagesBr.php
languages/messages/MessagesBs.php
languages/messages/MessagesCa.php
languages/messages/MessagesCeb.php
languages/messages/MessagesCkb.php
languages/messages/MessagesCrh_cyrl.php
languages/messages/MessagesCrh_latn.php
languages/messages/MessagesCs.php
languages/messages/MessagesCu.php
languages/messages/MessagesCy.php
languages/messages/MessagesDa.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesDsb.php
languages/messages/MessagesDv.php
languages/messages/MessagesEl.php
languages/messages/MessagesEn.php
languages/messages/MessagesEo.php
languages/messages/MessagesEs.php
languages/messages/MessagesEt.php
languages/messages/MessagesEu.php
languages/messages/MessagesExt.php
languages/messages/MessagesFa.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrp.php
languages/messages/MessagesFrr.php
languages/messages/MessagesFur.php
languages/messages/MessagesFy.php
languages/messages/MessagesGa.php
languages/messages/MessagesGan.php
languages/messages/MessagesGd.php
languages/messages/MessagesGl.php
languages/messages/MessagesGrc.php
languages/messages/MessagesGsw.php
languages/messages/MessagesGu.php
languages/messages/MessagesHe.php
languages/messages/MessagesHi.php
languages/messages/MessagesHif_latn.php
languages/messages/MessagesHr.php
languages/messages/MessagesHsb.php
languages/messages/MessagesHt.php
languages/messages/MessagesHu.php
languages/messages/MessagesHy.php
languages/messages/MessagesIa.php
languages/messages/MessagesId.php
languages/messages/MessagesIlo.php
languages/messages/MessagesIs.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesJut.php
languages/messages/MessagesJv.php
languages/messages/MessagesKa.php
languages/messages/MessagesKaa.php
languages/messages/MessagesKbd_cyrl.php
languages/messages/MessagesKhw.php
languages/messages/MessagesKiu.php
languages/messages/MessagesKk_cyrl.php
languages/messages/MessagesKm.php
languages/messages/MessagesKn.php
languages/messages/MessagesKo.php
languages/messages/MessagesKrc.php
languages/messages/MessagesKs_arab.php
languages/messages/MessagesKs_deva.php
languages/messages/MessagesKsh.php
languages/messages/MessagesKu_latn.php
languages/messages/MessagesKw.php
languages/messages/MessagesKy.php
languages/messages/MessagesLa.php
languages/messages/MessagesLad.php
languages/messages/MessagesLb.php
languages/messages/MessagesLez.php
languages/messages/MessagesLi.php
languages/messages/MessagesLt.php
languages/messages/MessagesLus.php
languages/messages/MessagesLv.php
languages/messages/MessagesLzh.php
languages/messages/MessagesMai.php
languages/messages/MessagesMdf.php
languages/messages/MessagesMg.php
languages/messages/MessagesMin.php
languages/messages/MessagesMk.php
languages/messages/MessagesMl.php
languages/messages/MessagesMn.php
languages/messages/MessagesMr.php
languages/messages/MessagesMs.php
languages/messages/MessagesMt.php
languages/messages/MessagesMy.php
languages/messages/MessagesMyv.php
languages/messages/MessagesMzn.php
languages/messages/MessagesNb.php
languages/messages/MessagesNds.php
languages/messages/MessagesNds_nl.php
languages/messages/MessagesNe.php
languages/messages/MessagesNl.php
languages/messages/MessagesNn.php
languages/messages/MessagesOc.php
languages/messages/MessagesOr.php
languages/messages/MessagesOs.php
languages/messages/MessagesPa.php
languages/messages/MessagesPcd.php
languages/messages/MessagesPfl.php
languages/messages/MessagesPl.php
languages/messages/MessagesPms.php
languages/messages/MessagesPnb.php
languages/messages/MessagesPrg.php
languages/messages/MessagesPs.php
languages/messages/MessagesPt.php
languages/messages/MessagesPt_br.php
languages/messages/MessagesQqq.php
languages/messages/MessagesQu.php
languages/messages/MessagesRm.php
languages/messages/MessagesRo.php
languages/messages/MessagesRoa_tara.php
languages/messages/MessagesRu.php
languages/messages/MessagesRue.php
languages/messages/MessagesSa.php
languages/messages/MessagesSah.php
languages/messages/MessagesSc.php
languages/messages/MessagesScn.php
languages/messages/MessagesSe.php
languages/messages/MessagesSgs.php
languages/messages/MessagesSh.php
languages/messages/MessagesSi.php
languages/messages/MessagesSk.php
languages/messages/MessagesSl.php
languages/messages/MessagesSli.php
languages/messages/MessagesSo.php
languages/messages/MessagesSq.php
languages/messages/MessagesSr_ec.php
languages/messages/MessagesSr_el.php
languages/messages/MessagesStq.php
languages/messages/MessagesSu.php
languages/messages/MessagesSv.php
languages/messages/MessagesSw.php
languages/messages/MessagesSzl.php
languages/messages/MessagesTa.php
languages/messages/MessagesTe.php
languages/messages/MessagesTet.php
languages/messages/MessagesTg_cyrl.php
languages/messages/MessagesTg_latn.php
languages/messages/MessagesTh.php
languages/messages/MessagesTk.php
languages/messages/MessagesTl.php
languages/messages/MessagesTly.php
languages/messages/MessagesTr.php
languages/messages/MessagesTru.php
languages/messages/MessagesTs.php
languages/messages/MessagesTt_cyrl.php
languages/messages/MessagesTt_latn.php
languages/messages/MessagesTyv.php
languages/messages/MessagesUg_arab.php
languages/messages/MessagesUk.php
languages/messages/MessagesUr.php
languages/messages/MessagesUz.php
languages/messages/MessagesVec.php
languages/messages/MessagesVep.php
languages/messages/MessagesVi.php
languages/messages/MessagesVo.php
languages/messages/MessagesVot.php
languages/messages/MessagesWa.php
languages/messages/MessagesWar.php
languages/messages/MessagesWo.php
languages/messages/MessagesYi.php
languages/messages/MessagesYo.php
languages/messages/MessagesYue.php
languages/messages/MessagesZh_hans.php
languages/messages/MessagesZh_hant.php
maintenance/7zip.inc
maintenance/Maintenance.php
maintenance/Makefile
maintenance/archives/upgradeLogging.php
maintenance/backupPrefetch.inc
maintenance/benchmarks/bench_strtr_str_replace.php
maintenance/changePassword.php
maintenance/checkSyntax.php
maintenance/cleanupSpam.php
maintenance/copyFileBackend.php
maintenance/deleteArchivedFiles.inc
maintenance/deleteArchivedRevisions.inc
maintenance/deleteEqualMessages.php [new file with mode: 0644]
maintenance/deleteOldRevisions.php
maintenance/deleteOrphanedRevisions.php
maintenance/dev/includes/router.php
maintenance/doMaintenance.php
maintenance/dumpLinks.php
maintenance/dumpTextPass.php
maintenance/edit.php
maintenance/eval.php
maintenance/fileOpPerfTest.php
maintenance/formatInstallDoc.php
maintenance/fuzz-tester.php
maintenance/getConfiguration.php [new file with mode: 0644]
maintenance/jsduck/MetaTags.rb [new file with mode: 0644]
maintenance/jsduck/categories.json [new file with mode: 0644]
maintenance/jsduck/config.json [new file with mode: 0644]
maintenance/jsduck/eg-iframe.html [new file with mode: 0644]
maintenance/jsduck/external.js [new file with mode: 0644]
maintenance/lag.php
maintenance/language/generateCollationData.php
maintenance/language/generateNormalizerData.php
maintenance/language/languages.inc
maintenance/language/messageTypes.inc
maintenance/language/messages.inc
maintenance/language/validate.php
maintenance/locking/LockServerDaemon.php
maintenance/mergeMessageFileList.php
maintenance/mwdocgen.php
maintenance/mwjsduck-gen [new file with mode: 0755]
maintenance/nextJobDB.php
maintenance/populateLogUsertext.php
maintenance/postgres/archives/patch-sites.sql [new file with mode: 0644]
maintenance/postgres/tables.sql
maintenance/preprocessDump.php
maintenance/proxy_check.php
maintenance/purgeList.php
maintenance/reassignEdits.php
maintenance/refreshImageMetadata.php
maintenance/runJobs.php
maintenance/showStats.php
maintenance/sql.php
maintenance/storage/blobs.sql
maintenance/storage/fixBug20757.php
maintenance/storage/moveToExternal.php
maintenance/storage/recompressTracked.php
maintenance/storage/resolveStubs.php
maintenance/storage/storageTypeStats.php
maintenance/storage/testCompression.php
maintenance/term/MWTerm.php
maintenance/userDupes.inc
maintenance/userOptions.php
maintenance/waitForSlave.php
opensearch_desc.php
profileinfo.php
resources/Resources.php
resources/jquery/jquery.client.js
resources/jquery/jquery.collapsibleTabs.js [deleted file]
resources/jquery/jquery.localize.js
resources/jquery/jquery.qunit.css
resources/jquery/jquery.qunit.js
resources/jquery/jquery.suggestions.js
resources/jquery/jquery.tablesorter.js
resources/mediawiki.action/mediawiki.action.view.dblClickEdit.js
resources/mediawiki.api/mediawiki.api.category.js
resources/mediawiki.api/mediawiki.api.edit.js
resources/mediawiki.api/mediawiki.api.js
resources/mediawiki.api/mediawiki.api.parse.js
resources/mediawiki.api/mediawiki.api.titleblacklist.js
resources/mediawiki.api/mediawiki.api.watch.js
resources/mediawiki.language/languages/ru.js
resources/mediawiki.special/mediawiki.special.preferences.js
resources/mediawiki.special/mediawiki.special.userLogin.signup.js [new file with mode: 0644]
resources/mediawiki/mediawiki.Title.js
resources/mediawiki/mediawiki.jqueryMsg.js
resources/mediawiki/mediawiki.js
resources/mediawiki/mediawiki.notification.js
resources/mediawiki/mediawiki.notify.js
resources/mediawiki/mediawiki.searchSuggest.css [new file with mode: 0644]
resources/mediawiki/mediawiki.searchSuggest.js
resources/mediawiki/mediawiki.user.js
resources/mediawiki/mediawiki.util.js
serialized/serialize.php
skins/Vector.php
skins/common/shared.css
skins/vector/images/border.png [deleted file]
skins/vector/images/page-base.png [deleted file]
skins/vector/images/preferences-base.png [deleted file]
skins/vector/images/preferences-edge.png [deleted file]
skins/vector/screen.css
tests/RunSeleniumTests.php
tests/TestsAutoLoader.php
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/parser/parserTestsParserHook.php
tests/parser/preprocess/NestedTemplates.expected [new file with mode: 0644]
tests/parser/preprocess/NestedTemplates.txt [new file with mode: 0644]
tests/parserTests.php
tests/phpunit/MediaWikiLangTestCase.php
tests/phpunit/MediaWikiPHPUnitCommand.php
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/StructureTest.php
tests/phpunit/bootstrap.php
tests/phpunit/data/xmp/7.result.php
tests/phpunit/data/xmp/gps.result.php
tests/phpunit/docs/ExportDemoTest.php
tests/phpunit/includes/ArticleTest.php
tests/phpunit/includes/BlockTest.php
tests/phpunit/includes/CdbTest.php
tests/phpunit/includes/DiffHistoryBlobTest.php
tests/phpunit/includes/EditPageTest.php
tests/phpunit/includes/ExternalStoreTest.php
tests/phpunit/includes/ExtraParserTest.php
tests/phpunit/includes/FormOptionsInitializationTest.php
tests/phpunit/includes/FormOptionsTest.php
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php
tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php
tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php
tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php
tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php
tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php
tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php [new file with mode: 0644]
tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php
tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php
tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php
tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
tests/phpunit/includes/HooksTest.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/HttpTest.php
tests/phpunit/includes/IPTest.php
tests/phpunit/includes/JsonTest.php
tests/phpunit/includes/LanguageConverterTest.php
tests/phpunit/includes/LicensesTest.php
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/LinksUpdateTest.php
tests/phpunit/includes/LocalFileTest.php
tests/phpunit/includes/MWFunctionTest.php
tests/phpunit/includes/MWNamespaceTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/ParserOptionsTest.php [deleted file]
tests/phpunit/includes/PathRouterTest.php
tests/phpunit/includes/PreferencesTest.php
tests/phpunit/includes/Providers.php
tests/phpunit/includes/RecentChangeTest.php
tests/phpunit/includes/ResourceLoaderTest.php
tests/phpunit/includes/RevisionStorageTest.php
tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php
tests/phpunit/includes/RevisionTest.php
tests/phpunit/includes/SampleTest.php
tests/phpunit/includes/SanitizerTest.php
tests/phpunit/includes/SanitizerValidateEmailTest.php
tests/phpunit/includes/SeleniumConfigurationTest.php
tests/phpunit/includes/SiteConfigurationTest.php
tests/phpunit/includes/StringUtilsTest.php
tests/phpunit/includes/TimeAdjustTest.php
tests/phpunit/includes/TimestampTest.php
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/UIDGeneratorTest.php [new file with mode: 0644]
tests/phpunit/includes/UserTest.php
tests/phpunit/includes/WebRequestTest.php
tests/phpunit/includes/WikiPageTest.php
tests/phpunit/includes/WikiPageTest_ContentHandlerUseDB.php
tests/phpunit/includes/XmlSelectTest.php
tests/phpunit/includes/XmlTest.php
tests/phpunit/includes/ZipDirectoryReaderTest.php
tests/phpunit/includes/api/ApiAccountCreationTest.php
tests/phpunit/includes/api/ApiBlockTest.php
tests/phpunit/includes/api/ApiEditPageTest.php
tests/phpunit/includes/api/ApiGeneratorTest.php [deleted file]
tests/phpunit/includes/api/ApiParseTest.php
tests/phpunit/includes/api/ApiPurgeTest.php
tests/phpunit/includes/api/ApiQueryRevisionsTest.php [deleted file]
tests/phpunit/includes/api/ApiQueryTest.php [deleted file]
tests/phpunit/includes/api/ApiTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/api/ApiTestCaseUpload.php
tests/phpunit/includes/api/ApiUploadTest.php
tests/phpunit/includes/api/ApiWatchTest.php
tests/phpunit/includes/api/PrefixUniquenessTest.php
tests/phpunit/includes/api/RandomImageGenerator.php
tests/phpunit/includes/api/format/ApiFormatPhpTest.php
tests/phpunit/includes/api/format/ApiFormatTestBase.php
tests/phpunit/includes/api/generateRandomImages.php
tests/phpunit/includes/api/query/ApiQueryBasicTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryTest.php [new file with mode: 0644]
tests/phpunit/includes/cache/GenderCacheTest.php
tests/phpunit/includes/cache/ProcessCacheLRUTest.php
tests/phpunit/includes/content/ContentHandlerTest.php
tests/phpunit/includes/content/CssContentTest.php
tests/phpunit/includes/content/JavaScriptContentTest.php
tests/phpunit/includes/content/TextContentTest.php
tests/phpunit/includes/content/WikitextContentHandlerTest.php
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/db/DatabaseSQLTest.php
tests/phpunit/includes/db/DatabaseSqliteTest.php
tests/phpunit/includes/db/DatabaseTest.php
tests/phpunit/includes/db/ORMRowTest.php
tests/phpunit/includes/debug/MWDebugTest.php
tests/phpunit/includes/filebackend/FileBackendTest.php
tests/phpunit/includes/filerepo/FileRepoTest.php
tests/phpunit/includes/filerepo/StoreBatchTest.php
tests/phpunit/includes/installer/InstallDocFormatterTest.php
tests/phpunit/includes/jobqueue/JobQueueTest.php [new file with mode: 0644]
tests/phpunit/includes/json/ServicesJsonTest.php
tests/phpunit/includes/libs/CSSJanusTest.php
tests/phpunit/includes/libs/GenericArrayObjectTest.php
tests/phpunit/includes/libs/IEUrlExtensionTest.php
tests/phpunit/includes/libs/JavaScriptMinifierTest.php
tests/phpunit/includes/logging/LogFormatterTest.php
tests/phpunit/includes/logging/LogTests.i18n.php
tests/phpunit/includes/media/BitmapMetadataHandlerTest.php
tests/phpunit/includes/media/BitmapScalingTest.php
tests/phpunit/includes/media/ExifBitmapTest.php
tests/phpunit/includes/media/ExifRotationTest.php
tests/phpunit/includes/media/ExifTest.php
tests/phpunit/includes/media/FormatMetadataTest.php
tests/phpunit/includes/media/GIFMetadataExtractorTest.php
tests/phpunit/includes/media/GIFTest.php
tests/phpunit/includes/media/IPTCTest.php
tests/phpunit/includes/media/JpegMetadataExtractorTest.php
tests/phpunit/includes/media/MediaHandlerTest.php
tests/phpunit/includes/media/PNGMetadataExtractorTest.php
tests/phpunit/includes/media/PNGTest.php
tests/phpunit/includes/media/SVGMetadataExtractorTest.php
tests/phpunit/includes/media/XMPTest.php
tests/phpunit/includes/normal/CleanUpTest.php
tests/phpunit/includes/objectcache/BagOStuffTest.php
tests/phpunit/includes/parser/MagicVariableTest.php
tests/phpunit/includes/parser/MediaWikiParserTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/parser/ParserMethodsTest.php
tests/phpunit/includes/parser/ParserOutputTest.php
tests/phpunit/includes/parser/ParserPreloadTest.php
tests/phpunit/includes/parser/PreprocessorTest.php
tests/phpunit/includes/parser/TagHooksTest.php
tests/phpunit/includes/search/SearchEngineTest.php
tests/phpunit/includes/site/MediaWikiSiteTest.php
tests/phpunit/includes/site/SiteArrayTest.php [deleted file]
tests/phpunit/includes/site/SiteListTest.php
tests/phpunit/includes/site/SiteObjectTest.php [deleted file]
tests/phpunit/includes/site/SiteSQLStoreTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SiteTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SitesTest.php [deleted file]
tests/phpunit/includes/site/TestSites.php
tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php
tests/phpunit/includes/specials/SpecialRecentchangesTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/includes/upload/UploadFromUrlTest.php
tests/phpunit/includes/upload/UploadStashTest.php
tests/phpunit/includes/upload/UploadTest.php
tests/phpunit/languages/LanguageAmTest.php
tests/phpunit/languages/LanguageArTest.php
tests/phpunit/languages/LanguageBeTest.php
tests/phpunit/languages/LanguageBe_taraskTest.php
tests/phpunit/languages/LanguageBhoTest.php
tests/phpunit/languages/LanguageBsTest.php
tests/phpunit/languages/LanguageClassesTestCase.php
tests/phpunit/languages/LanguageCsTest.php
tests/phpunit/languages/LanguageCuTest.php
tests/phpunit/languages/LanguageCyTest.php
tests/phpunit/languages/LanguageDsbTest.php
tests/phpunit/languages/LanguageFrTest.php
tests/phpunit/languages/LanguageGaTest.php
tests/phpunit/languages/LanguageGdTest.php
tests/phpunit/languages/LanguageGvTest.php
tests/phpunit/languages/LanguageHeTest.php
tests/phpunit/languages/LanguageHiTest.php
tests/phpunit/languages/LanguageHrTest.php
tests/phpunit/languages/LanguageHsbTest.php
tests/phpunit/languages/LanguageHuTest.php
tests/phpunit/languages/LanguageHyTest.php
tests/phpunit/languages/LanguageKshTest.php
tests/phpunit/languages/LanguageLnTest.php
tests/phpunit/languages/LanguageLtTest.php
tests/phpunit/languages/LanguageLvTest.php
tests/phpunit/languages/LanguageMgTest.php
tests/phpunit/languages/LanguageMkTest.php
tests/phpunit/languages/LanguageMlTest.php
tests/phpunit/languages/LanguageMoTest.php
tests/phpunit/languages/LanguageMtTest.php
tests/phpunit/languages/LanguageNsoTest.php
tests/phpunit/languages/LanguagePlTest.php
tests/phpunit/languages/LanguageRoTest.php
tests/phpunit/languages/LanguageRuTest.php
tests/phpunit/languages/LanguageSeTest.php
tests/phpunit/languages/LanguageSgsTest.php
tests/phpunit/languages/LanguageShTest.php
tests/phpunit/languages/LanguageSkTest.php
tests/phpunit/languages/LanguageSlTest.php
tests/phpunit/languages/LanguageSmaTest.php
tests/phpunit/languages/LanguageSrTest.php
tests/phpunit/languages/LanguageTest.php
tests/phpunit/languages/LanguageTiTest.php
tests/phpunit/languages/LanguageTlTest.php
tests/phpunit/languages/LanguageTrTest.php
tests/phpunit/languages/LanguageUkTest.php
tests/phpunit/languages/LanguageUzTest.php
tests/phpunit/languages/LanguageWaTest.php
tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php
tests/phpunit/maintenance/DumpTestCase.php
tests/phpunit/maintenance/MaintenanceTest.php
tests/phpunit/maintenance/backupPrefetchTest.php
tests/phpunit/maintenance/backupTextPassTest.php
tests/phpunit/maintenance/backup_LogTest.php
tests/phpunit/maintenance/backup_PageTest.php
tests/phpunit/maintenance/fetchTextTest.php
tests/phpunit/maintenance/getSlaveServerTest.php
tests/phpunit/phpunit.php
tests/phpunit/resources/ResourcesTest.php
tests/phpunit/skins/SideBarTest.php
tests/phpunit/suite.xml
tests/phpunit/suites/ExtensionsTestSuite.php
tests/phpunit/suites/UploadFromUrlTestSuite.php
tests/qunit/data/generateJqueryMsgData.php
tests/qunit/data/qunitOkCall.js
tests/qunit/data/styleTest.css.php
tests/qunit/data/testrunner.js
tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js
tests/qunit/suites/resources/jquery/jquery.byteLength.test.js
tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js
tests/qunit/suites/resources/jquery/jquery.client.test.js
tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js
tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js
tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js
tests/qunit/suites/resources/jquery/jquery.hidpi.test.js
tests/qunit/suites/resources/jquery/jquery.localize.test.js
tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js
tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/jquery/jquery.textSelection.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.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.cldr.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.language.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/selenium/Selenium.php
tests/selenium/SeleniumConfig.php
tests/selenium/SeleniumServerManager.php
tests/selenium/SeleniumTestCase.php
tests/selenium/SeleniumTestListener.php
tests/selenium/SeleniumTestSuite.php
tests/selenium/data/SimpleSeleniumTestDB.sql
tests/selenium/installer/MediaWikiButtonsAvailabilityTestCase.php
tests/selenium/installer/MediaWikiDifferentDatabaseAccountTestCase.php
tests/selenium/installer/MediaWikiDifferntDatabasePrefixTestCase.php
tests/selenium/installer/MediaWikiErrorsConnectToDatabasePageTestCase.php
tests/selenium/installer/MediaWikiErrorsNamepageTestCase.php
tests/selenium/installer/MediaWikiHelpFieldHintTestCase.php
tests/selenium/installer/MediaWikiInstallationCommonFunction.php
tests/selenium/installer/MediaWikiInstallationConfig.php
tests/selenium/installer/MediaWikiInstallationMessage.php
tests/selenium/installer/MediaWikiInstallationVariables.php
tests/selenium/installer/MediaWikiInstallerTestSuite.php
tests/selenium/installer/MediaWikiMySQLDataBaseTestCase.php
tests/selenium/installer/MediaWikiMySQLiteDataBaseTestCase.php
tests/selenium/installer/MediaWikiOnAlreadyInstalledTestCase.php
tests/selenium/installer/MediaWikiRestartInstallationTestCase.php
tests/selenium/installer/MediaWikiRightFrameworkLinksTestCase.php
tests/selenium/installer/MediaWikiUpgradeExistingDatabaseTestCase.php
tests/selenium/installer/MediaWikiUserInterfaceTestCase.php
tests/selenium/suites/AddContentToNewPageTestCase.php
tests/selenium/suites/AddNewPageTestCase.php
tests/selenium/suites/CreateAccountTestCase.php
tests/selenium/suites/DeletePageAdminTestCase.php
tests/selenium/suites/EmailPasswordTestCase.php
tests/selenium/suites/MediaWikiEditorConfig.php
tests/selenium/suites/MediaWikiEditorTestSuite.php
tests/selenium/suites/MediaWikiExtraTestSuite.php
tests/selenium/suites/MediawikiCoreSmokeTestCase.php
tests/selenium/suites/MediawikiCoreSmokeTestSuite.php
tests/selenium/suites/MovePageTestCase.php
tests/selenium/suites/MyContributionsTestCase.php
tests/selenium/suites/MyWatchListTestCase.php
tests/selenium/suites/PageDeleteTestSuite.php
tests/selenium/suites/PageSearchTestCase.php
tests/selenium/suites/PreviewPageTestCase.php
tests/selenium/suites/SavePageTestCase.php
tests/selenium/suites/SimpleSeleniumConfig.php
tests/selenium/suites/SimpleSeleniumTestCase.php
tests/selenium/suites/SimpleSeleniumTestSuite.php
tests/selenium/suites/UserPreferencesTestCase.php
tests/testHelpers.inc
thumb.php

index 004ecf4..8dcba4e 100644 (file)
@@ -18,6 +18,7 @@ sublime-*
 
 # MediaWiki install & usage
 cache
+docs/js
 images/[0-9a-f]
 images/archive
 images/deleted
@@ -37,6 +38,11 @@ StartProfiler.php
 # Building & testing
 node_modules/
 
+# Composer
+/vendor
+/composer.lock
+/composer.json
+
 # Operating systems
 ## Mac OS X
 .DS_Store
diff --git a/CREDITS b/CREDITS
index ca5d6d7..9c49a9b 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -6,6 +6,7 @@ following names for their contribution to the product.
 == Developers ==
 * Aaron Schulz
 * Alex Z.
+* Alexander Monk
 * Alexandre Emsenhuber
 * Andrew Garrett
 * Arthur Richards
@@ -26,7 +27,7 @@ following names for their contribution to the product.
 * Derk-Jan Hartman
 * Domas Mituzas
 * Emufarmers
-* Fran McCrory
+* Fran Rogers
 * Greg Sabino Mullane
 * Guy Van den Broeck
 * Happy-melon
@@ -87,10 +88,10 @@ following names for their contribution to the product.
 
 == Patch Contributors ==
 * Aaron Pramana
+* Aaron Ball
 * Agbad
 * Ahmad Sherif
 * Alejandro Mery
-* Alexander Monk
 * Amalthea
 * Amir E. Aharoni
 * Andrew Dunbar
@@ -120,6 +121,7 @@ following names for their contribution to the product.
 * Daniel Werner
 * David Baumgarten
 * Denny Vrandecic
+* Dévai Tamás
 * Edward Z. Yang
 * Elvis Stansvik
 * Erwin Dokter
diff --git a/HISTORY b/HISTORY
index 8d232f3..3a25b97 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -316,6 +316,7 @@ milestone in Bugzilla.
 * (bug 11142) Improve file extension blacklist error reporting in API upload.
 * (bug 39665) List of query generators is now not built using reflection, instead it is
   defined in code.
+* (bug 35993) Deprecated gettoken parameter - support will be removed in 1.22.
 
 === Languages updated in 1.20 ===
 
diff --git a/INSTALL b/INSTALL
index e393631..891be73 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -20,7 +20,8 @@ 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. safe_mode is also
 not tested and unlikely to work.
 
-If you want math support see the instructions in math/README
+Support for rendering mathematical formulas requires installing the Math extension,
+see http://www.mediawiki.org/wiki/Extension:Math
 
 Don't forget to check the RELEASE-NOTES file...
 
@@ -45,12 +46,15 @@ In-place web install
 
 Decompress the MediaWiki installation archive either on your server, or on your
 local machine and upload the directory tree. Rename it from "mediawiki-1.x.x" to
-something nice, like "wiki", since it'll be in your URL.
+something nice, like "wiki", since it will be appearing in your URL,
+ie. /wiki/index.php/Article.
 
   +--------------------------------------------------------------------------+
-  |  Hint: If you plan to use a fancy URL-rewriting scheme to prettify your  |
-  |  URLs, you should put the files in a *different* directory from the      |
-  |  virtual path where page names will appear.                              |
+  |  Note: If you plan to use a fancy URL-rewriting scheme to prettify your  |
+  |  URLs, such as http://www.example.com/wiki/Article, you should put the   |
+  |  files in a *different* directory from the virtual path where page names |
+  |  will appear. It is common in this case to use w as the folder name and  |
+  |  /wiki/ as the virtual article path where your articles pretend to be.   |
   |                                                                          |
   |    See: http://www.mediawiki.org/wiki/Manual:Short_URL                   |
   +--------------------------------------------------------------------------+
index 1f344d4..80266c6 100644 (file)
@@ -16,6 +16,8 @@ production.
   of page watchers required for the number to be accessible to users
   without the unwatchedpages permission.
 * $wgBug34832TransitionalRollback has been removed.
+* (bug 29472) $wgUseDynamicDates has been removed and its functionality
+  disabled.
 
 === New features in 1.21 ===
 * (bug 38110) Schema changes (adding or dropping tables, indicies and
@@ -83,8 +85,23 @@ production.
   in MW 1.20 (saving preferences using Special:Preferences cleared any
   additional fields) and which has been disabled in 1.20.1 as a part of
   a security fix (bug 42202).
-* Added the ability to limit the wall clock time used by shell processes, 
+* Added the ability to limit the wall clock time used by shell processes,
   as well as the CPU time. Configurable with $wgMaxShellWallClockTime.
+* Allow memory of shell subprocesses to be limited using Linux cgroups
+  instead of ulimit -v, which tends to cause deadlocks in recent versions
+  of ImageMagick. Configurable with $wgShellCgroup.
+* Added $wgWhitelistReadRegexp for regex whitelisting.
+* (bug 5346) Categories that are redirects will be displayed italic in
+  the category links section at the bottom of a page.
+* (bug 43915) New maintenance script deleteEqualMessages.php.
+* New collation uppercase-sv, which is like uppercase, but adapted
+  to Swedish sort order.
+* WikiText now permits the use of WAI-ARIA's role="presentation" inside of
+  html elements and tables. This allows presentational markup, especially
+  tables. To be marked up as such.
+* maintenance/sql.php learned the --cluster option. Let you run the script
+  on some external cluster instead of the primary cluster for a given wiki.
+* (bug 20281) test the parsing of inline URLs.
 
 === Bug fixes in 1.21 ===
 * (bug 40353) SpecialDoubleRedirect should support interwiki redirects.
@@ -152,6 +169,15 @@ production.
 * wfMerge() now works if $wgDiff3 contains spaces
 * (bug 43052) mediawiki.action.view.dblClickEdit.dblClickEdit should trigger
   ca-edit click instead opening URL directly.
+* (bug 43964) Invalid value of "link" parameter in <gallery> no longer produces
+  a fatal error.
+* (bug 44775) The username field is not pre-filled when creating an account.
+* (bug 45069) wfParseUrl() no longer produces a PHP notice if passed a "mailto:"
+  URL without address
+* (bug 45012) Creating an account by e-mail can no longer show a
+  "password mismatch" error.
+* (bug 44599) On Special:Version, HEADs for submodule checkouts (e.g. for
+  extensions) performed using Git 1.7.8+ should now appear.
 
 === API changes in 1.21 ===
 * prop=revisions can now report the contentmodel and contentformat.
@@ -181,11 +207,39 @@ production.
 * (bug 35885) Removed version parameter and all getVersion() methods.
 * action=options now takes a "resetkinds" option, which allows only resetting
   certain types of preferences when the "reset" option is set.
+* (bug 36751) ApiQueryImageInfo now returns imageinfo for the redirect target
+  when queried with &redirects=.
+* (bug 31849) ApiQueryImageInfo no longer gets confused when asked for info on
+  a redirect and its target.
+* (bug 43849) ApiQueryImageInfo no longer throws exceptions with ForeignDBRepo
+  redirects.
+* On error, any warnings generated before that error will be shown in the result.
+* action=help suports generalized submodules (modules=query+value), querymodules obsolete
+* ApiQueryImageInfo continuation is more reliable. The only major change is
+  that the imagerepository property will no longer be set on page objects not
+  processed in the current query (i.e. non-images or those skipped due to
+  iicontinue).
+* Add supports for all pageset capabilities - generators, redirects, converttitles to
+  action=purge and action=setnotificationtimestamp.
+* (bug 43251) prop=pageprops&ppprop= now accepts multiple props to query.
+* ApiQueryImageInfo will now limit the number of calls to File::transform made
+  in any one query. If there are too many, iicontinue will be returned.
+* action=query&meta=siteinfo&siprop=general will now return the regexes used for
+  link trails and link prefices. Added for Parsoid support.
 
 === API internal changes in 1.21 ===
 * For debugging only, a new global $wgDebugAPI removes many API restrictions when true.
   Never use on the production servers, as this flag introduces security holes.
   Whenever enabled, a warning will also be added to all output.
+* ApiModuleManager now handles all submodules (actions,props,lists) and instantiation
+* Query stores prop/list/meta as submodules
+* ApiPageSet can now be used in any action to process titles/pageids/revids or any generator.
+* BREAKING CHANGE: ApiPageSet constructor now has two params instead of three, with only the
+  first one keeping its meaning. ApiPageSet is now derived from ApiBase.
+* BREAKING CHANGE: ApiQuery::newGenerator() and executeGeneratorModule() were deleted.
+* ApiQueryGeneratorBase::setGeneratorMode() now requires a pageset param.
+* $wgAPIGeneratorModules is now obsolete and will be ignored.
+* Added flags ApiResult::OVERRIDE and ADD_ON_TOP to setElement() and addValue()
 
 === Languages updated in 1.21 ===
 
@@ -201,6 +255,13 @@ changes to languages because of Bugzilla reports.
   as separators for thousands and decimals respectively.
 
 === Other changes in 1.21 ===
+* BREAKING CHANGE: (bug 44385) Removed the jquery.collapsibleTabs module and
+  moved it to the Vector extension. It was entirely Vector-extension-specific,
+  deeply interconnected with the extension, and this functionality really
+  belongs to the extension instead of the skin anyway. In the unlikely case you
+  were using it, you have to either copy it to your extension, or install the
+  Vector extension (and possibly disable its features using config settings if
+  you don't want them).
 
 == Compatibility ==
 
index ba8fe8b..db5e0ff 100644 (file)
@@ -15,5 +15,3 @@
  *
  * Configuration of the profiler output can be done in LocalSettings.php
  */
-
-
diff --git a/api.php b/api.php
index 7fae373..abf601f 100644 (file)
--- a/api.php
+++ b/api.php
@@ -60,7 +60,7 @@ if ( !$wgEnableAPI ) {
        header( $_SERVER['SERVER_PROTOCOL'] . ' 500 MediaWiki configuration Error', true, 500 );
        echo( 'MediaWiki API is not enabled for this site. Add the following line to your LocalSettings.php'
                . '<pre><b>$wgEnableAPI=true;</b></pre>' );
-       die(1);
+       die( 1 );
 }
 
 // Set a dummy $wgTitle, because $wgTitle == null breaks various things
@@ -87,17 +87,17 @@ wfLogProfilingData();
 // Log the request
 if ( $wgAPIRequestLog ) {
        $items = array(
-                       wfTimestamp( TS_MW ),
-                       $endtime - $starttime,
-                       $wgRequest->getIP(),
-                       $_SERVER['HTTP_USER_AGENT']
+               wfTimestamp( TS_MW ),
+               $endtime - $starttime,
+               $wgRequest->getIP(),
+               $_SERVER['HTTP_USER_AGENT']
        );
        $items[] = $wgRequest->wasPosted() ? 'POST' : 'GET';
        $module = $processor->getModule();
        if ( $module->mustBePosted() ) {
                $items[] = "action=" . $wgRequest->getVal( 'action' );
        } else {
-               $items[] = wfArrayToCGI( $wgRequest->getValues() );
+               $items[] = wfArrayToCgi( $wgRequest->getValues() );
        }
        wfErrorLog( implode( ',', $items ) . "\n", $wgAPIRequestLog );
        wfDebug( "Logged API request to $wgAPIRequestLog\n" );
@@ -107,4 +107,3 @@ if ( $wgAPIRequestLog ) {
 // get here to worry about whether this should be = or =&, but the file has to parse properly.
 $lb = wfGetLBFactory();
 $lb->shutdown();
-
diff --git a/bin/ulimit5.sh b/bin/ulimit5.sh
deleted file mode 100644 (file)
index 3f24172..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-if [ "$1" -gt 0 ]; then
-       ulimit -t "$1"
-fi
-if [ "$2" -gt 0 ]; then
-       ulimit -v "$2"
-fi
-if [ "$3" -gt 0 ]; then
-       ulimit -f "$3"
-fi
-if [ "$4" -gt 0 ]; then
-       timeout $4 /bin/bash -c "$5"
-       STATUS="$?"
-       if [ "$STATUS" == 124 ]; then
-               echo "ulimit5.sh: timed out." 1>&2
-       fi
-       exit "$STATUS"
-else
-       eval "$5"
-fi
diff --git a/composer.json b/composer.json
new file mode 100644 (file)
index 0000000..fa42c29
--- /dev/null
@@ -0,0 +1,36 @@
+{
+       "name": "mediawiki/core",
+       "description": "Free software wiki application developed by the Wikimedia Foundation and others",
+       "keywords": ["mediawiki", "wiki"],
+       "homepage": "https://www.mediawiki.org/",
+       "authors": [
+               {
+                       "name": "MediaWiki Community",
+                       "homepage": "https://www.mediawiki.org/wiki/Special:Version/Credits"
+               }
+       ],
+       "license": "GPL-2.0",
+       "repositories": [
+               {
+                       "type": "vcs",
+                       "url": "https://gerrit.wikimedia.org/r/p/mediawiki/core.git"
+               }
+       ],
+       "support": {
+               "issues": "https://bugzilla.wikimedia.org/",
+               "irc": "irc://irc.freenode.net/mediawiki",
+               "wiki": "https://www.mediawiki.org/"
+       },
+       "require": {
+               "php": ">=5.3.2"
+       },
+       "require-dev": {
+               "phpunit/phpunit": "*"
+       },
+       "suggest": {
+               "ext-fileinfo": "*",
+               "ext-mbstring": "*",
+               "ext-wikidiff2": "*",
+               "ext-apc": "*"
+       }
+}
index 6574c17..28eedf4 100644 (file)
@@ -295,7 +295,7 @@ ob_get_clean().
 $title: Title under which the revisions were imported
 $origTitle: Title provided by the XML file
 $revCount: Number of revisions in the XML file
-$sRevCount: Number of sucessfully imported revisions
+$sRevCount: Number of successfully imported revisions
 $pageInfo: associative array of page information
 
 'AfterFinalPageOutput': Nearly at the end of OutputPage::output() but
@@ -355,6 +355,7 @@ $text : the new text of the article (has yet to be saved)
 'APIGetAllowedParams': Use this hook to modify a module's parameters.
 &$module: ApiBase Module object
 &$params: Array of parameters
+$flags: int zero or OR-ed flags like ApiBase::GET_VALUES_FOR_HELP
 
 'APIGetDescription': Use this hook to modify a module's description.
 &$module: ApiBase Module object
@@ -365,7 +366,7 @@ descriptions.
 &$module: ApiBase Module object
 &$desc: Array of parameter descriptions
 
-'APIGetResultProperties': Use this hook to mofify the propertiesin a module's
+'APIGetResultProperties': Use this hook to modify the properties in a module's
 result.
 &$module: ApiBase Module object
 &$properties: Array of properties
@@ -521,7 +522,7 @@ $row: row (object) returned from the database server
 
 'ArticlePageDataBefore': Before loading data of an article from the database.
 $wikiPage: WikiPage (object) that data will be loaded
-$fields: fileds (array) to load from the database
+$fields: fields (array) to load from the database
 
 'ArticlePrepareTextForEdit': Called when preparing text to be saved.
 $wikiPage: the WikiPage being saved
@@ -616,14 +617,14 @@ $article: target article (object)
 
 'ArticleViewCustom': Allows to output the text of the article in a different
 format than wikitext. DEPRECATED, use ArticleContentViewCustom instead. Note
-that it is preferrable to implement proper handing for a custom data type using
+that it is preferable to implement proper handing for a custom data type using
 the ContentHandler facility.
 $text: text of the page
 $title: title of the page
 $output: reference to $wgOut
 
 'ArticleContentViewCustom': Allows to output the text of the article in a
-different format than wikitext. Note that it is preferrable to implement proper
+different format than wikitext. Note that it is preferable to implement proper
 handing for a custom data type using the ContentHandler facility.
 $content: content of the page, as a Content object
 $title: title of the page
@@ -634,7 +635,7 @@ in from an external authentication method.
 $user: User object created locally
 
 'AuthPluginSetup': Update or replace authentication plugin object ($wgAuth).
-Gives a chance for an extension to set it programattically to a variable class.
+Gives a chance for an extension to set it programmatically to a variable class.
 &$auth: the $wgAuth object, probably a stub
 
 'AutopromoteCondition': Check autopromote condition for user.
@@ -643,7 +644,7 @@ $args: arguments
 $user: user
 $result: result of checking autopromote condition
 
-'BacklinkCacheGetPrefix': Allows to set prefix for a spefific link table.
+'BacklinkCacheGetPrefix': Allows to set prefix for a specific link table.
 $table: table name
 &$prefix: prefix
 
@@ -769,7 +770,7 @@ $collationName: Name of the collation in question
 successfully.
 $user: user (object) whose email is being confirmed
 
-'ContentHandlerDefaultModelFor': Called when the default content model is determiend
+'ContentHandlerDefaultModelFor': Called when the default content model is determined
 for a given title. May be used to assign a different model for that title.
 $title: the Title in question
 &$model: the model name. Use with CONTENT_MODEL_XXX constants.
@@ -954,27 +955,27 @@ $title: title of page being edited
 
 'EditPageGetDiffText': DEPRECATED. Use EditPageGetDiffContent instead. Allow
 modifying the wikitext that will be used in "Show changes". Note that it is
-preferrable to implement diff handling for different data types using the
+preferable to implement diff handling for different data types using the
 ContentHandler facility.
 $editPage: EditPage object
 &$newtext: wikitext that will be used as "your version"
 
 'EditPageGetDiffContent': Allow modifying the wikitext that will be used in
-"Show changes". Note that it is preferrable to implement diff handling for
+"Show changes". Note that it is preferable to implement diff handling for
 different data types using the ContentHandler facility.
 $editPage: EditPage object
 &$newtext: wikitext that will be used as "your version"
 
 'EditPageGetPreviewText': DEPRECATED. Use EditPageGetPreviewContent instead.
-Allow modifying the wikitext that will be previewed. Note that it is preferrable
-to implement previews for different data types using the COntentHandler
+Allow modifying the wikitext that will be previewed. Note that it is preferable
+to implement previews for different data types using the ContentHandler
 facility.
 $editPage: EditPage object
 &$toparse: wikitext that will be parsed
 
 'EditPageGetPreviewContent': Allow modifying the wikitext that will be
-previewed. Note that it is preferrable to implement previews for different data
-types using the COntentHandler facility.
+previewed. Note that it is preferable to implement previews for different data
+types using the ContentHandler facility.
 $editPage: EditPage object
 &$content: Content object to be previewed (may be replaced by hook function)
 
@@ -1151,7 +1152,7 @@ $title: Title object of page
 &$url: string value as output (out parameter, can modify)
 
 'GetMetadataVersion': Modify the image metadata version currently in use. This
-is used when requesting image metadata from a ForiegnApiRepo. Media handlers
+is used when requesting image metadata from a ForeignApiRepo. Media handlers
 that need to have versioned metadata should add an element to the end of the
 version array of the form 'handler_name=version'. Most media handlers won't need
 to do this unless they broke backwards compatibility with a previous version of
@@ -1215,7 +1216,7 @@ page is built.
 $imagePage: ImagePage object ($this)
 &$html: HTML for the hook to add
 
-'ImagePageFileHistoryLine': Called when a file history line is contructed.
+'ImagePageFileHistoryLine': Called when a file history line is constructed.
 $file: the file
 $line: the HTML of the history line
 $css: the line CSS class
@@ -1338,13 +1339,13 @@ CanonicalNamespaces for that.
 $wgExtensionMessagesFiles instead.
 Use this to define synonyms of magic words depending of the language
 $magicExtensions: associative array of magic words synonyms
-$lang: laguage code (string)
+$lang: language code (string)
 
 'LanguageGetSpecialPageAliases': DEPRECATED, use $specialPageAliases in a file
 listed in $wgExtensionMessagesFiles instead.
 Use to define aliases of special pages names depending of the language
 $specialPageAliases: associative array of magic words synonyms
-$lang: laguage code (string)
+$lang: language code (string)
 
 'LanguageGetTranslatedLanguageNames': Provide translated language names.
 &$names: array of language code => language name
@@ -1375,8 +1376,8 @@ $target: the Title object that the link is pointing to
 $options: the options.  Will always include either 'known' or 'broken', and may
   include 'noclasses'.
 &$html: the final (raw HTML) contents of the <a> tag, after processing.
-&$attribs: the final HTML attributes of the <a> tag, after processing, in asso-
-  ciative array form.
+&$attribs: the final HTML attributes of the <a> tag, after processing, in
+  associative array form.
 &$ret: the value to return if your hook returns false.
 
 'LinkerMakeExternalImage': At the end of Linker::makeExternalImage() just
@@ -1401,13 +1402,13 @@ actual update.
 each link table insert.  For example, pagelinks, imagelinks, externallinks.
 $linksUpdate: LinksUpdate object
 $table: the table to insert links to
-$insertions: an arry of links to insert
+$insertions: an array of links to insert
 
 'LinksUpdateComplete': At the end of LinksUpdate::doUpdate() when updating,
 including delete and insert, has completed for all link tables
 &$linksUpdate: the LinksUpdate object
 
-'LinksUpdateConstructed': At the end of LinksUpdate() is contruction.
+'LinksUpdateConstructed': At the end of LinksUpdate() is construction.
 &$linksUpdate: the LinksUpdate object
 
 'ListDefinedTags': When trying to find all defined tags.
@@ -1481,7 +1482,7 @@ $time: timestamp of the log entry (added in 1.12)
 script.
 $refreshLinks: RefreshLinks object
 
-'MagicWordwgVariableIDs': When definig new magic words IDs.
+'MagicWordwgVariableIDs': When defining new magic words IDs.
 $variableIDs: array of strings
 
 'MakeGlobalVariablesScript': Called right before Skin::makeVariablesScript is
@@ -1492,7 +1493,7 @@ ResourceLoaderGetConfigVars instead.
   Skin::makeVariablesScript
 $out: The OutputPage which called the hook, can be used to get the real title.
 
-'MarkPatrolled': Aefore an edit is marked patrolled.
+'MarkPatrolled': Before an edit is marked patrolled.
 $rcid: ID of the revision to be marked patrolled
 $user: the user (object) marking the revision as patrolled
 $wcOnlySysopsCanPatrol: config setting indicating whether the user needs to be a
@@ -1689,7 +1690,7 @@ $stripState: stripState used (object)
 
 'ParserAfterTidy': Called after Parser::tidy() in Parser::parse()
 $parser: Parser object being used
-$text: text that'll be returned
+$text: text that will be returned
 
 'ParserBeforeInternalParse': Called at the beginning of Parser::internalParse().
 $parser: Parser object
@@ -1732,7 +1733,7 @@ $time: actual time (timestamp)
 'ParserGetVariableValueVarCache': use this to change the value of the variable
 cache or return false to not use it.
 $parser: Parser object
-$varCache: varaiable cache (array)
+$varCache: variable cache (array)
 
 'ParserLimitReport': Called at the end of Parser:parse() when the parser will
 include comments about size of the text parsed.
@@ -1807,7 +1808,7 @@ $oldaddr: old email address (string)
 $newaddr: new email address (string)
 
 'PrefsPasswordAudit': Called when user changes his password.
-$user: User (object) changing his passoword
+$user: User (object) changing his password
 $newPass: new password
 $error: error (string) 'badretype', 'wrongpassword', 'error' or 'success'
 
@@ -2170,7 +2171,7 @@ go to the existing page.
 $t: title object searched for
 &$params: an array of the default message name and page title (as parameter)
 
-'SpecialSearchGo': Valled when user clicked the "Go".
+'SpecialSearchGo': Called when user clicked the "Go".
 &$title: title object generated from the text entered by the user
 &$term: the search term entered by the user
 
@@ -2264,7 +2265,7 @@ $output: OutputPage object
 'ThumbnailBeforeProduceHTML': Called before an image HTML is about to be
 rendered (by ThumbnailImage:toHtml method).
 $thumbnail: the ThumbnailImage object
-&$attribs: image attibute array
+&$attribs: image attribute array
 &$linkAttribs: image link attribute array
 
 'TitleArrayFromResult': Called when creating an TitleArray object from a
@@ -2299,7 +2300,7 @@ $result: Boolean; whether MediaWiki currently thinks this page is movable.
   Title::isMovable().
 
 'TitleIsWikitextPage': Called when determining if a page is a wikitext or should
-be handled by seperate handler (via ArticleViewCustom).
+be handled by separate handler (via ArticleViewCustom).
 $title: Title object that is being checked
 $result: Boolean; whether MediaWiki currently thinks this is a wikitext page.
   Hooks may change this value to override the return value of
@@ -2340,7 +2341,7 @@ $title: Title object of the page that we're about to undelete
 $title: title object related to the revision
 $rev: revision (object) that will be viewed
 
-'UnknownAction': An unknown "action" has occured (useful for defining your own
+'UnknownAction': An unknown "action" has occurred (useful for defining your own
 actions).
 $action: action name
 $article: article "acted on"
@@ -2437,7 +2438,7 @@ $user: User (object) whose permission is being checked
 
 'UserClearNewTalkNotification': Called when clearing the "You have new
 messages!" message, return false to not delete it.
-$user: User (object) that'll clear the message
+$user: User (object) that will clear the message
 
 'UserComparePasswords': Called when checking passwords, return false to
 override the default password checks.
@@ -2478,9 +2479,9 @@ $user: User object
 &$email: email, change this to override local email
 
 'UserGetEmailAuthenticationTimestamp': Called when getting the timestamp of
-email authentification.
+email authentication.
 $user: User object
-&$timestamp: timestamp, change this to override local email authentification
+&$timestamp: timestamp, change this to override local email authentication
   timestamp
 
 'UserGetImplicitGroups': Called in User::getImplicitGroups().
@@ -2488,7 +2489,7 @@ $user: User object
 
 'UserGetLanguageObject': Called when getting user's interface language object.
 $user: User object
-&$code: Langauge code that will be used to create the object
+&$code: Language code that will be used to create the object
 $context: RequestContext object
 
 'UserGetReservedNames': Allows to modify $wgReservedUsernames at run time.
@@ -2526,7 +2527,7 @@ $user: user object
 'UserLoadFromSession': Called to authenticate users on external/environmental
 means; occurs before session is loaded.
 $user: user object being loaded
-&$result: set this to a boolean value to abort the normal authentification
+&$result: set this to a boolean value to abort the normal authentication
   process
 
 'UserLoadOptions': When user options/preferences are being loaded from the
@@ -2581,10 +2582,10 @@ $user: User object
 &$email: new email, change this to override new email address
 
 'UserSetEmailAuthenticationTimestamp': Called when setting the timestamp of
-email authentification.
+email authentication.
 $user: User object
 &$timestamp: new timestamp, change this to override local email
-authentification timestamp
+authentication timestamp
 
 'UserToolLinksEdit': Called when generating a list of user tool links, e.g.
 "Foobar (Talk | Contribs | Block)".
index b04974b..ccaa8af 100644 (file)
@@ -60,8 +60,8 @@ function wfImageAuthMain() {
 
        // See if this is a public Wiki (no protections).
        if ( $wgImgAuthPublicTest
-               && in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) )
-       {
+               && in_array( 'read', User::getGroupPermissions( array( '*' ) ), true )
+       {
                // This is a public wiki, so disable this script (for private wikis only)
                wfForbidden( 'img-auth-accessdenied', 'img-auth-public' );
                return;
@@ -106,7 +106,7 @@ function wfImageAuthMain() {
 
        // Check to see if the file exists
        if ( !$repo->fileExists( $filename ) ) {
-               wfForbidden( 'img-auth-accessdenied','img-auth-nofile', $filename );
+               wfForbidden( 'img-auth-accessdenied', 'img-auth-nofile', $filename );
                return;
        }
 
@@ -130,7 +130,7 @@ function wfImageAuthMain() {
        }
 
        // Stream the requested file
-       wfDebugLog( 'img_auth', "Streaming `".$filename."`." );
+       wfDebugLog( 'img_auth', "Streaming `" . $filename . "`." );
        $repo->streamFile( $filename, array( 'Cache-Control: private', 'Vary: Cookie' ) );
 }
 
@@ -153,8 +153,8 @@ function wfForbidden( $msg1, $msg2 ) {
        $detailMsg = wfMessage( $detailMsgKey, $args )->escaped();
 
        wfDebugLog( 'img_auth',
-               "wfForbidden Hdr:" . wfMessage( $msg1 )->inLanguage( 'en' )->text() . " Msg: ".
-               wfMessage( $msg2, $args )->inLanguage( 'en' )->text()
+               "wfForbidden Hdr: " . wfMessage( $msg1 )->inLanguage( 'en' )->text() . " Msg: " .
+                       wfMessage( $msg2, $args )->inLanguage( 'en' )->text()
        );
 
        header( 'HTTP/1.0 403 Forbidden' );
index 8201763..40ce478 100644 (file)
@@ -38,7 +38,7 @@ abstract class Action {
 
        /**
         * Page on which we're performing the action
-        * @var Page $page
+        * @var WikiPage|Article|ImagePage|CategoryPage|Page $page
         */
        protected $page;
 
@@ -61,7 +61,7 @@ abstract class Action {
         * @param $overrides Array
         * @return bool|null|string
         */
-       private final static function getClass( $action, array $overrides ) {
+       final private static function getClass( $action, array $overrides ) {
                global $wgActions;
                $action = strtolower( $action );
 
@@ -88,7 +88,7 @@ abstract class Action {
         * @return Action|bool|null false if the action is disabled, null
         *     if it is not recognised
         */
-       public final static function factory( $action, Page $page, IContextSource $context = null ) {
+       final public static function factory( $action, Page $page, IContextSource $context = null ) {
                $class = self::getClass( $action, $page->getActionOverrides() );
                if ( $class ) {
                        $obj = new $class( $page, $context );
@@ -106,7 +106,7 @@ abstract class Action {
         * @param $context IContextSource
         * @return string: action name
         */
-       public final static function getActionName( IContextSource $context ) {
+       final public static function getActionName( IContextSource $context ) {
                global $wgActions;
 
                $request = $context->getRequest();
@@ -150,7 +150,7 @@ abstract class Action {
         * @param $name String: name of an action
         * @return Bool
         */
-       public final static function exists( $name ) {
+       final public static function exists( $name ) {
                return self::getClass( $name, array() ) !== null;
        }
 
@@ -158,7 +158,7 @@ abstract class Action {
         * Get the IContextSource in use here
         * @return IContextSource
         */
-       public final function getContext() {
+       final public function getContext() {
                if ( $this->context instanceof IContextSource ) {
                        return $this->context;
                }
@@ -170,7 +170,7 @@ abstract class Action {
         *
         * @return WebRequest
         */
-       public final function getRequest() {
+       final public function getRequest() {
                return $this->getContext()->getRequest();
        }
 
@@ -179,7 +179,7 @@ abstract class Action {
         *
         * @return OutputPage
         */
-       public final function getOutput() {
+       final public function getOutput() {
                return $this->getContext()->getOutput();
        }
 
@@ -188,7 +188,7 @@ abstract class Action {
         *
         * @return User
         */
-       public final function getUser() {
+       final public function getUser() {
                return $this->getContext()->getUser();
        }
 
@@ -197,7 +197,7 @@ abstract class Action {
         *
         * @return Skin
         */
-       public final function getSkin() {
+       final public function getSkin() {
                return $this->getContext()->getSkin();
        }
 
@@ -206,7 +206,7 @@ abstract class Action {
         *
         * @return Language
         */
-       public final function getLanguage() {
+       final public function getLanguage() {
                return $this->getContext()->getLanguage();
        }
 
@@ -216,7 +216,7 @@ abstract class Action {
         * @deprecated 1.19 Use getLanguage instead
         * @return Language
         */
-       public final function getLang() {
+       final public function getLang() {
                wfDeprecated( __METHOD__, '1.19' );
                return $this->getLanguage();
        }
@@ -225,7 +225,7 @@ abstract class Action {
         * Shortcut to get the Title object from the page
         * @return Title
         */
-       public final function getTitle() {
+       final public function getTitle() {
                return $this->page->getTitle();
        }
 
@@ -235,7 +235,7 @@ abstract class Action {
         *
         * @return Message object
         */
-       public final function msg() {
+       final public function msg() {
                $params = func_get_args();
                return call_user_func_array( array( $this->getContext(), 'msg' ), $params );
        }
@@ -255,7 +255,7 @@ abstract class Action {
         * Return the name of the action this object responds to
         * @return String lowercase
         */
-       public abstract function getName();
+       abstract public function getName();
 
        /**
         * Get the permission required to perform this action.  Often, but not always,
@@ -350,13 +350,13 @@ abstract class Action {
         * $this->getOutput(), etc.
         * @throws ErrorPageError
         */
-       public abstract function show();
+       abstract public function show();
 
        /**
         * Execute the action in a silent fashion: do not display anything or release any errors.
         * @return Bool whether execution was successful
         */
-       public abstract function execute();
+       abstract public function execute();
 }
 
 /**
@@ -368,7 +368,7 @@ abstract class FormAction extends Action {
         * Get an HTMLForm descriptor array
         * @return Array
         */
-       protected abstract function getFormFields();
+       abstract protected function getFormFields();
 
        /**
         * Add pre- or post-text to the form
@@ -406,7 +406,7 @@ abstract class FormAction extends Action {
                        $this->getRequest()->getQueryValues(),
                        array( 'action' => null, 'title' => null )
                );
-               $form->addHiddenField( 'redirectparams', wfArrayToCGI( $params ) );
+               $form->addHiddenField( 'redirectparams', wfArrayToCgi( $params ) );
 
                $form->addPreText( $this->preText() );
                $form->addPostText( $this->postText() );
@@ -425,14 +425,14 @@ abstract class FormAction extends Action {
         * @param  $data Array
         * @return Bool|Array true for success, false for didn't-try, array of errors on failure
         */
-       public abstract function onSubmit( $data );
+       abstract public function onSubmit( $data );
 
        /**
         * Do something exciting on successful processing of the form.  This might be to show
         * a confirmation message (watch, rollback, etc) or to redirect somewhere else (edit,
         * protect, etc).
         */
-       public abstract function onSuccess();
+       abstract public function onSuccess();
 
        /**
         * The basic pattern for actions is to display some sort of HTMLForm UI, maybe with
@@ -508,7 +508,7 @@ abstract class FormlessAction extends Action {
         * @return String|null will be added to the HTMLForm if present, or just added to the
         *     output if not.  Return null to not add anything
         */
-       public abstract function onView();
+       abstract public function onView();
 
        /**
         * We don't want an HTMLForm
index 4ff31b8..d1b72a0 100644 (file)
@@ -13,11 +13,11 @@ class ArrayUtils {
         * since the function call overhead dominates. So there's not much
         * justification for breaking compatibility with installations
         * compiled with ./configure --disable-hash.
-        * 
+        *
         * @param $array The array to sort
         * @param $key The string key
         * @param $separator A separator used to delimit the array elements and the
-        *     key. This can be chosen to provide backwards compatibility with 
+        *     key. This can be chosen to provide backwards compatibility with
         *     various consistent hash implementations that existed before this
         *     function was introduced.
         */
@@ -31,4 +31,3 @@ class ArrayUtils {
                } );
        }
 }
-
index 10cbac7..ed9c305 100644 (file)
@@ -33,7 +33,7 @@
  *
  * @internal documentation reviewed 15 Mar 2010
  */
-class Article extends Page {
+class Article implements Page {
        /**@{{
         * @private
         */
@@ -420,7 +420,7 @@ class Article extends Page {
                # Pre-fill content with error message so that if something
                # fails we'll have something telling us what we intended.
                //XXX: this isn't page content but a UI message. horrible.
-               $this->mContentObject = new MessageContent( 'missing-revision', array( $oldid ), array() ) ;
+               $this->mContentObject = new MessageContent( 'missing-revision', array( $oldid ), array() );
 
                if ( $oldid ) {
                        # $this->mRevision might already be fetched by getOldIDFromRequest()
@@ -1089,6 +1089,7 @@ class Article extends Page {
        public function showMissingArticle() {
                global $wgSend404Code;
                $outputPage = $this->getContext()->getOutput();
+               $validUserPage = false;
 
                # Show info in user (talk) namespace. Does the user exist? Is he blocked?
                if ( $this->getTitle()->getNamespace() == NS_USER || $this->getTitle()->getNamespace() == NS_USER_TALK ) {
@@ -1115,6 +1116,9 @@ class Article extends Page {
                                                )
                                        )
                                );
+                               $validUserPage = true;
+                       } else {
+                               $validUserPage = true;
                        }
                }
 
@@ -1122,13 +1126,13 @@ class Article extends Page {
 
                # Show delete and move logs
                LogEventsList::showLogExtract( $outputPage, array( 'delete', 'move' ), $this->getTitle(), '',
-                       array(  'lim' => 10,
+                       array( 'lim' => 10,
                                'conds' => array( "log_action != 'revision'" ),
                                'showIfEmpty' => false,
                                'msgKey' => array( 'moveddeleted-notice' ) )
                );
 
-               if ( !$this->mPage->hasViewableContent() && $wgSend404Code ) {
+               if ( !$this->mPage->hasViewableContent() && $wgSend404Code && !$validUserPage ) {
                        // If there's no backing content, send a 404 Not Found
                        // for better machine handling of broken links.
                        $this->getContext()->getRequest()->response()->header( "HTTP/1.1 404 Not Found" );
@@ -1268,7 +1272,7 @@ class Article extends Page {
                                        'oldid' => $oldid
                                ) + $extraParams
                        );
-               $prev = $this->getTitle()->getPreviousRevisionID( $oldid ) ;
+               $prev = $this->getTitle()->getPreviousRevisionID( $oldid );
                $prevlink = $prev
                        ? Linker::linkKnown(
                                $this->getTitle(),
@@ -1483,7 +1487,7 @@ class Article extends Page {
                                $reason = $this->generateReason( $hasHistory );
                        } catch ( MWException $e ) {
                                # if a page is horribly broken, we still want to be able to delete it. so be lenient about errors here.
-                               wfDebug("Error while building auto delete summary: $e");
+                               wfDebug( "Error while building auto delete summary: $e" );
                                $reason = '';
                        }
                }
index 5eb497d..e0b7c8f 100644 (file)
@@ -94,6 +94,8 @@ $wgAutoloadLocalClasses = array(
        'ExternalStore' => 'includes/externalstore/ExternalStore.php',
        'ExternalStoreDB' => 'includes/externalstore/ExternalStoreDB.php',
        'ExternalStoreHttp' => 'includes/externalstore/ExternalStoreHttp.php',
+       'ExternalStoreMedium' => 'includes/externalstore/ExternalStoreMedium.php',
+       'ExternalStoreMwstore' => 'includes/externalstore/ExternalStoreMwstore.php',
        'ExternalUser' => 'includes/ExternalUser.php',
        'FakeTitle' => 'includes/FakeTitle.php',
        'Fallback' => 'includes/Fallback.php',
@@ -252,9 +254,11 @@ $wgAutoloadLocalClasses = array(
        'TitleArray' => 'includes/TitleArray.php',
        'TitleArrayFromResult' => 'includes/TitleArray.php',
        'ThrottledError' => 'includes/Exception.php',
+       'UIDGenerator' => 'includes/UIDGenerator.php',
        'UnlistedSpecialPage' => 'includes/SpecialPage.php',
        'UploadSourceAdapter' => 'includes/Import.php',
        'UppercaseCollation' => 'includes/Collation.php',
+       'UppercaseSvCollation' => 'includes/Collation.php',
        'User' => 'includes/User.php',
        'UserArray' => 'includes/UserArray.php',
        'UserArrayFromResult' => 'includes/UserArray.php',
@@ -362,6 +366,7 @@ $wgAutoloadLocalClasses = array(
        'ApiLogin' => 'includes/api/ApiLogin.php',
        'ApiLogout' => 'includes/api/ApiLogout.php',
        'ApiMain' => 'includes/api/ApiMain.php',
+       'ApiModuleManager' => 'includes/api/ApiModuleManager.php',
        'ApiMove' => 'includes/api/ApiMove.php',
        'ApiOpenSearch' => 'includes/api/ApiOpenSearch.php',
        'ApiOptions' => 'includes/api/ApiOptions.php',
@@ -449,6 +454,10 @@ $wgAutoloadLocalClasses = array(
        'TitleDependency' => 'includes/cache/CacheDependency.php',
        'TitleListDependency' => 'includes/cache/CacheDependency.php',
 
+       # includes/clientpool
+       'RedisConnectionPool' => 'includes/clientpool/RedisConnectionPool.php',
+       'RedisConnRef' => 'includes/clientpool/RedisConnectionPool.php',
+
        # includes/context
        'ContextSource' => 'includes/context/ContextSource.php',
        'DerivativeContext' => 'includes/context/DerivativeContext.php',
@@ -572,8 +581,9 @@ $wgAutoloadLocalClasses = array(
        'DBLockManager' => 'includes/filebackend/lockmanager/DBLockManager.php',
        'LSLockManager' => 'includes/filebackend/lockmanager/LSLockManager.php',
        'MemcLockManager' => 'includes/filebackend/lockmanager/MemcLockManager.php',
-       'QuorumLockManager' => 'includes/filebackend/lockmanager/LockManager.php',
+       'QuorumLockManager' => 'includes/filebackend/lockmanager/QuorumLockManager.php',
        'MySqlLockManager'=> 'includes/filebackend/lockmanager/DBLockManager.php',
+       'PostgreSqlLockManager'=> 'includes/filebackend/lockmanager/DBLockManager.php',
        'NullLockManager' => 'includes/filebackend/lockmanager/LockManager.php',
        'FileOp' => 'includes/filebackend/FileOp.php',
        'FileOpBatch' => 'includes/filebackend/FileOpBatch.php',
@@ -651,8 +661,12 @@ $wgAutoloadLocalClasses = array(
        # includes/job
        'Job' => 'includes/job/Job.php',
        'JobQueue' => 'includes/job/JobQueue.php',
+       'JobQueueAggregator' => 'includes/job/JobQueueAggregator.php',
+       'JobQueueAggregatorMemc' => 'includes/job/JobQueueAggregatorMemc.php',
+       'JobQueueAggregatorRedis' => 'includes/job/JobQueueAggregatorRedis.php',
        'JobQueueDB' => 'includes/job/JobQueueDB.php',
        'JobQueueGroup' => 'includes/job/JobQueueGroup.php',
+       'JobQueueRedis' => 'includes/job/JobQueueRedis.php',
 
        # includes/job/jobs
        'DoubleRedirectJob' => 'includes/job/jobs/DoubleRedirectJob.php',
@@ -774,35 +788,24 @@ $wgAutoloadLocalClasses = array(
        'MWTidyWrapper' => 'includes/parser/Tidy.php',
        'PPCustomFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPCustomFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPCustomFrame_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDAccum_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDAccum_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDPart' => 'includes/parser/Preprocessor_DOM.php',
        'PPDPart_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDPart_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDStack' => 'includes/parser/Preprocessor_DOM.php',
        'PPDStackElement' => 'includes/parser/Preprocessor_DOM.php',
        'PPDStackElement_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDStackElement_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDStack_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDStack_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPFrame' => 'includes/parser/Preprocessor.php',
        'PPFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPFrame_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPNode' => 'includes/parser/Preprocessor.php',
        'PPNode_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPNode_Hash_Array' => 'includes/parser/Preprocessor_Hash.php',
        'PPNode_Hash_Attr' => 'includes/parser/Preprocessor_Hash.php',
        'PPNode_Hash_Text' => 'includes/parser/Preprocessor_Hash.php',
        'PPNode_Hash_Tree' => 'includes/parser/Preprocessor_Hash.php',
-       'PPNode_HipHop_Array' => 'includes/parser/Preprocessor_HipHop.hphp',
-       'PPNode_HipHop_Attr' => 'includes/parser/Preprocessor_HipHop.hphp',
-       'PPNode_HipHop_Text' => 'includes/parser/Preprocessor_HipHop.hphp',
-       'PPNode_HipHop_Tree' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPTemplateFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPTemplateFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPTemplateFrame_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'Parser' => 'includes/parser/Parser.php',
        'ParserCache' => 'includes/parser/ParserCache.php',
        'ParserOptions' => 'includes/parser/ParserOptions.php',
@@ -812,7 +815,6 @@ $wgAutoloadLocalClasses = array(
        'Preprocessor' => 'includes/parser/Preprocessor.php',
        'Preprocessor_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'Preprocessor_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'Preprocessor_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'StripState' => 'includes/parser/StripState.php',
 
        # includes/profiler
@@ -883,11 +885,12 @@ $wgAutoloadLocalClasses = array(
        # includes/site
        'MediaWikiSite' => 'includes/site/MediaWikiSite.php',
        'Site' => 'includes/site/Site.php',
-       'SiteArray' => 'includes/site/SiteArray.php',
+       'SiteObject' => 'includes/site/Site.php',
+       'SiteArray' => 'includes/site/SiteList.php',
        'SiteList' => 'includes/site/SiteList.php',
-       'SiteObject' => 'includes/site/SiteObject.php',
-       'Sites' => 'includes/site/Sites.php',
-       'SitesTable' => 'includes/site/SitesTable.php',
+       'SiteSQLStore' => 'includes/site/SiteSQLStore.php',
+       'Sites' => 'includes/site/SiteSQLStore.php',
+       'SiteStore' => 'includes/site/SiteStore.php',
 
        # includes/specials
        'ActiveUsersPager' => 'includes/specials/SpecialActiveusers.php',
@@ -1079,7 +1082,7 @@ $wgAutoloadLocalClasses = array(
        'wikiStatsOutput' => 'maintenance/language/StatOutputs.php',
 
        # maintenance/term
-       'AnsiTermColorer'  => 'maintenance/term/MWTerm.php',
+       'AnsiTermColorer' => 'maintenance/term/MWTerm.php',
        'DummyTermColorer' => 'maintenance/term/MWTerm.php',
 
        # mw-config
index b81cf3a..1d1e2c0 100644 (file)
@@ -65,7 +65,7 @@ class Block {
                $timestamp = 0, $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
                $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = '' )
        {
-               if( $timestamp === 0 ){
+               if( $timestamp === 0 ) {
                        $timestamp = wfTimestampNow();
                }
 
@@ -206,16 +206,16 @@ class Block {
         */
        public function load( $address = '', $user = 0 ) {
                wfDeprecated( __METHOD__, '1.18' );
-               if( $user ){
+               if( $user ) {
                        $username = User::whoIs( $user );
                        $block = self::newFromTarget( $username, $address );
                } else {
                        $block = self::newFromTarget( null, $address );
                }
 
-               if( $block instanceof Block ){
+               if( $block instanceof Block ) {
                        # This is mildly evil, but hey, it's B/C :D
-                       foreach( $block as $variable => $value ){
+                       foreach( $block as $variable => $value ) {
                                $this->$variable = $value;
                        }
                        return true;
@@ -237,7 +237,7 @@ class Block {
        protected function newLoad( $vagueTarget = null ) {
                $db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
 
-               if( $this->type !== null ){
+               if( $this->type !== null ) {
                        $conds = array(
                                'ipb_address' => array( (string)$this->target ),
                        );
@@ -247,7 +247,7 @@ class Block {
 
                # Be aware that the != '' check is explicit, since empty values will be
                # passed by some callers (bug 29116)
-               if( $vagueTarget != ''){
+               if( $vagueTarget != '' ) {
                        list( $target, $type ) = self::parseTarget( $vagueTarget );
                        switch( $type ) {
                                case self::TYPE_USER:
@@ -285,20 +285,20 @@ class Block {
                # This is begging for $this = $bestBlock, but that's not allowed in PHP :(
                $bestBlockPreventsEdit = null;
 
-               foreach( $res as $row ){
+               foreach( $res as $row ) {
                        $block = self::newFromRow( $row );
 
                        # Don't use expired blocks
-                       if( $block->deleteIfExpired() ){
+                       if( $block->deleteIfExpired() ) {
                                continue;
                        }
 
                        # Don't use anon only blocks on users
-                       if( $this->type == self::TYPE_USER && !$block->isHardblock() ){
+                       if( $this->type == self::TYPE_USER && !$block->isHardblock() ) {
                                continue;
                        }
 
-                       if( $block->getType() == self::TYPE_RANGE ){
+                       if( $block->getType() == self::TYPE_RANGE ) {
                                # This is the number of bits that are allowed to vary in the block, give
                                # or take some floating point errors
                                $end = wfBaseconvert( $block->getRangeEnd(), 16, 10 );
@@ -313,14 +313,14 @@ class Block {
                                $score = $block->getType();
                        }
 
-                       if( $score < $bestBlockScore ){
+                       if( $score < $bestBlockScore ) {
                                $bestBlockScore = $score;
                                $bestRow = $row;
                                $bestBlockPreventsEdit = $block->prevents( 'edit' );
                        }
                }
 
-               if( $bestRow !== null ){
+               if( $bestRow !== null ) {
                        $this->initFromRow( $bestRow );
                        $this->prevents( 'edit', $bestBlockPreventsEdit );
                        return true;
@@ -371,9 +371,9 @@ class Block {
        protected static function getIpFragment( $hex ) {
                global $wgBlockCIDRLimit;
                if ( substr( $hex, 0, 3 ) == 'v6-' ) {
-                       return 'v6-' . substr( substr( $hex, 3 ), 0,  floor( $wgBlockCIDRLimit['IPv6'] / 4 ) );
+                       return 'v6-' . substr( substr( $hex, 3 ), 0, floor( $wgBlockCIDRLimit['IPv6'] / 4 ) );
                } else {
-                       return substr( $hex, 0,  floor( $wgBlockCIDRLimit['IPv4'] / 4 ) );
+                       return substr( $hex, 0, floor( $wgBlockCIDRLimit['IPv4'] / 4 ) );
                }
        }
 
@@ -465,7 +465,7 @@ class Block {
                Block::purgeExpired();
 
                $row = $this->getDatabaseArray();
-               $row['ipb_id'] = $dbw->nextSequenceValue("ipblocks_ipb_id_seq");
+               $row['ipb_id'] = $dbw->nextSequenceValue( "ipblocks_ipb_id_seq" );
 
                $dbw->insert(
                        'ipblocks',
@@ -511,7 +511,7 @@ class Block {
         * @return Array
         */
        protected function getDatabaseArray( $db = null ) {
-               if( !$db ){
+               if( !$db ) {
                        $db = wfGetDB( DB_SLAVE );
                }
                $expiry = $db->encodeExpiry( $this->mExpiry );
@@ -592,7 +592,7 @@ class Block {
                $options['LIMIT'] = 1;
 
                $res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds,
-                       __METHOD__ ,  $options );
+                       __METHOD__, $options );
 
                if ( !$res->numRows() ) {
                        # No results, don't autoblock anything
@@ -1050,10 +1050,10 @@ class Block {
        public static function newFromTarget( $specificTarget, $vagueTarget = null, $fromMaster = false ) {
 
                list( $target, $type ) = self::parseTarget( $specificTarget );
-               if( $type == Block::TYPE_ID || $type == Block::TYPE_AUTO ){
+               if( $type == Block::TYPE_ID || $type == Block::TYPE_AUTO ) {
                        return Block::newFromID( $target );
 
-               } elseif( $target === null && $vagueTarget == '' ){
+               } elseif( $target === null && $vagueTarget == '' ) {
                        # We're not going to find anything useful here
                        # Be aware that the == '' check is explicit, since empty values will be
                        # passed by some callers (bug 29116)
@@ -1063,11 +1063,11 @@ class Block {
                        $block = new Block();
                        $block->fromMaster( $fromMaster );
 
-                       if( $type !== null ){
+                       if( $type !== null ) {
                                $block->setTarget( $target );
                        }
 
-                       if( $block->newLoad( $vagueTarget ) ){
+                       if( $block->newLoad( $vagueTarget ) ) {
                                return $block;
                        }
                }
@@ -1085,13 +1085,13 @@ class Block {
         */
        public static function parseTarget( $target ) {
                # We may have been through this before
-               if( $target instanceof User ){
-                       if( IP::isValid( $target->getName() ) ){
+               if( $target instanceof User ) {
+                       if( IP::isValid( $target->getName() ) ) {
                                return array( $target, self::TYPE_IP );
                        } else {
                                return array( $target, self::TYPE_USER );
                        }
-               } elseif( $target === null ){
+               } elseif( $target === null ) {
                        return array( null, null );
                }
 
@@ -1112,7 +1112,7 @@ class Block {
 
                # Consider the possibility that this is not a username at all
                # but actually an old subpage (bug #29797)
-               if( strpos( $target, '/' ) !== false ){
+               if( strpos( $target, '/' ) !== false ) {
                        # An old subpage, drill down to the user behind it
                        $parts = explode( '/', $target );
                        $target = $parts[0];
index b9c9609..53e44d7 100644 (file)
@@ -75,11 +75,11 @@ class Category {
                        # Okay, there were no contents.  Nothing to initialize.
                        if ( $this->mTitle ) {
                                # If there is a title object but no record in the category table, treat this as an empty category
-                               $this->mID      = false;
-                               $this->mName    = $this->mTitle->getDBkey();
-                               $this->mPages   = 0;
+                               $this->mID = false;
+                               $this->mName = $this->mTitle->getDBkey();
+                               $this->mPages = 0;
                                $this->mSubcats = 0;
-                               $this->mFiles   = 0;
+                               $this->mFiles = 0;
 
                                return true;
                        } else {
@@ -87,11 +87,11 @@ class Category {
                        }
                }
 
-               $this->mID      = $row->cat_id;
-               $this->mName    = $row->cat_title;
-               $this->mPages   = $row->cat_pages;
+               $this->mID = $row->cat_id;
+               $this->mName = $row->cat_title;
+               $this->mPages = $row->cat_pages;
                $this->mSubcats = $row->cat_subcats;
-               $this->mFiles   = $row->cat_files;
+               $this->mFiles = $row->cat_files;
 
                # (bug 13683) If the count is negative, then 1) it's obviously wrong
                # and should not be kept, and 2) we *probably* don't have to scan many
@@ -179,16 +179,16 @@ class Category {
                                $cat->mName = $title->getDBkey(); # if we have a title object, fetch the category name from there
                        }
 
-                       $cat->mID =   false;
+                       $cat->mID = false;
                        $cat->mSubcats = 0;
-                       $cat->mPages   = 0;
-                       $cat->mFiles   = 0;
+                       $cat->mPages = 0;
+                       $cat->mFiles = 0;
                } else {
-                       $cat->mName    = $row->cat_title;
-                       $cat->mID      = $row->cat_id;
+                       $cat->mName = $row->cat_title;
+                       $cat->mID = $row->cat_id;
                        $cat->mSubcats = $row->cat_subcats;
-                       $cat->mPages   = $row->cat_pages;
-                       $cat->mFiles   = $row->cat_files;
+                       $cat->mPages = $row->cat_pages;
+                       $cat->mFiles = $row->cat_files;
                }
 
                return $cat;
@@ -350,9 +350,9 @@ class Category {
                wfProfileOut( __METHOD__ );
 
                # Now we should update our local counts.
-               $this->mPages   = $result->pages;
+               $this->mPages = $result->pages;
                $this->mSubcats = $result->subcats;
-               $this->mFiles   = $result->files;
+               $this->mFiles = $result->files;
 
                return $ret;
        }
index 589950f..cb67aa8 100644 (file)
@@ -211,7 +211,7 @@ class Categoryfinder {
                        $res = $this->dbr->select(
                                /* FROM   */ 'page',
                                /* SELECT */ array( 'page_id', 'page_title' ),
-                               /* WHERE  */ array( 'page_namespace' => NS_CATEGORY , 'page_title' => $layer ),
+                               /* WHERE  */ array( 'page_namespace' => NS_CATEGORY, 'page_title' => $layer ),
                                __METHOD__ . '-2'
                        );
                        foreach ( $res as $o ) {
index 2a6a3d2..1c4587a 100644 (file)
@@ -133,7 +133,7 @@ class CdbReader_DBA {
        }
 
        function close() {
-               if( isset($this->handle) ) {
+               if( isset( $this->handle ) ) {
                        dba_close( $this->handle );
                }
                unset( $this->handle );
@@ -165,7 +165,7 @@ class CdbWriter_DBA {
        }
 
        function close() {
-               if( isset($this->handle) ) {
+               if( isset( $this->handle ) ) {
                        dba_close( $this->handle );
                }
                if ( wfIsWindows() ) {
@@ -183,4 +183,3 @@ class CdbWriter_DBA {
                }
        }
 }
-
index f58e07e..71b55f8 100644 (file)
@@ -332,10 +332,10 @@ class CdbWriter_PHP extends CdbWriter {
         */
        public function close() {
                $this->finish();
-               if( isset($this->handle) ) {
+               if( isset( $this->handle ) ) {
                        fclose( $this->handle );
                }
-               if ( wfIsWindows() && file_exists($this->realFileName) ) {
+               if ( wfIsWindows() && file_exists( $this->realFileName ) ) {
                        unlink( $this->realFileName );
                }
                if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
@@ -351,7 +351,7 @@ class CdbWriter_PHP extends CdbWriter {
        protected function write( $buf ) {
                $len = fwrite( $this->handle, $buf );
                if ( $len !== strlen( $buf ) ) {
-                       $this->throwException( 'Error writing to CDB file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Error writing to CDB file "' . $this->tmpFileName . '".' );
                }
        }
 
@@ -363,7 +363,7 @@ class CdbWriter_PHP extends CdbWriter {
                $newpos = $this->pos + $len;
                if ( $newpos > 0x7fffffff ) {
                        $this->throwException(
-                               'A value in the CDB file "'.$this->tmpFileName.'" is too large.' );
+                               'A value in the CDB file "' . $this->tmpFileName . '" is too large.' );
                }
                $this->pos = $newpos;
        }
@@ -392,10 +392,10 @@ class CdbWriter_PHP extends CdbWriter {
         */
        protected function addbegin( $keylen, $datalen ) {
                if ( $keylen > 0x7fffffff ) {
-                       $this->throwException( 'Key length too long in file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Key length too long in file "' . $this->tmpFileName . '".' );
                }
                if ( $datalen > 0x7fffffff ) {
-                       $this->throwException( 'Data length too long in file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Data length too long in file "' . $this->tmpFileName . '".' );
                }
                $buf = pack( 'VV', $keylen, $datalen );
                $this->write( $buf );
@@ -470,7 +470,7 @@ class CdbWriter_PHP extends CdbWriter {
                // Write the pointer array at the start of the file
                rewind( $this->handle );
                if ( ftell( $this->handle ) != 0 ) {
-                       $this->throwException( 'Error rewinding to start of file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Error rewinding to start of file "' . $this->tmpFileName . '".' );
                }
                $this->write( $final );
        }
index 18f425a..1dd9b59 100644 (file)
@@ -169,7 +169,7 @@ class ChangeTags {
         *
         * @throws MWException When unable to determine appropriate JOIN condition for tagging
         */
-       static function modifyDisplayQuery( &$tables, &$fields,  &$conds,
+       static function modifyDisplayQuery( &$tables, &$fields, &$conds,
                                                                                &$join_conds, &$options, $filter_tag = false ) {
                global $wgRequest, $wgUseTagFilter;
 
@@ -221,7 +221,7 @@ class ChangeTags {
         *        - if $fullForm is false: Array with
         *        - if $fullForm is true: String, html fragment
         */
-       public static function buildTagFilterSelector( $selected='', $fullForm = false, Title $title = null ) {
+       public static function buildTagFilterSelector( $selected = '', $fullForm = false, Title $title = null ) {
                global $wgUseTagFilter;
 
                if ( !$wgUseTagFilter || !count( self::listDefinedTags() ) ) {
index ee4c2d6..ae30272 100644 (file)
@@ -135,7 +135,7 @@ class ChangesFeed {
                $feedLastmod = $messageMemc->get( $timekey );
 
                if( ( $wgFeedCacheTimeout > 0 ) && $feedLastmod ) {
-                   /**
+                       /**
                         * If the cached feed was rendered very recently, we may
                         * go ahead and use it even if there have been edits made
                         * since it was rendered. This keeps a swarm of requests
index e98fcac..a9b9c31 100644 (file)
@@ -30,7 +30,7 @@
  */
 class RCCacheEntry extends RecentChange {
        var $secureName, $link;
-       var $curlink , $difflink, $lastlink, $usertalklink, $versionlink;
+       var $curlink, $difflink, $lastlink, $usertalklink, $versionlink;
        var $userlink, $timestamp, $watched;
 
        /**
@@ -136,7 +136,7 @@ class ChangesList extends ContextSource {
         */
        protected function recentChangesFlags( $flags, $nothing = '&#160;' ) {
                $f = '';
-               foreach( array( 'newpage', 'minor', 'bot', 'unpatrolled' ) as $flag ){
+               foreach( array( 'newpage', 'minor', 'bot', 'unpatrolled' ) as $flag ) {
                        $f .= isset( $flags[$flag] ) && $flags[$flag]
                                ? self::flag( $flag )
                                : $nothing;
@@ -217,7 +217,7 @@ class ChangesList extends ContextSource {
                $lang = $context->getLanguage();
                $code = $lang->getCode();
                static $fastCharDiff = array();
-               if ( !isset($fastCharDiff[$code]) ) {
+               if ( !isset( $fastCharDiff[$code] ) ) {
                        $fastCharDiff[$code] = $wgMiserMode || $context->msg( 'rc-change-size' )->plain() === '$1';
                }
 
@@ -328,7 +328,7 @@ class ChangesList extends ContextSource {
                } else {
                        $query = array(
                                'curid' => $rc->mAttribs['rc_cur_id'],
-                               'diff'  => $rc->mAttribs['rc_this_oldid'],
+                               'diff' => $rc->mAttribs['rc_this_oldid'],
                                'oldid' => $rc->mAttribs['rc_last_oldid']
                        );
 
@@ -378,7 +378,7 @@ class ChangesList extends ContextSource {
                        array( 'class' => 'mw-changeslist-title' ),
                        $params
                );
-               if( $this->isDeleted($rc,Revision::DELETED_TEXT) ) {
+               if( $this->isDeleted( $rc, Revision::DELETED_TEXT ) ) {
                        $articlelink = '<span class="history-deleted">' . $articlelink . '</span>';
                }
                # To allow for boldening pages watched by this user
@@ -387,7 +387,7 @@ class ChangesList extends ContextSource {
                $articlelink .= $this->getLanguage()->getDirMark();
 
                wfRunHooks( 'ChangesListInsertArticleLink',
-                       array(&$this, &$articlelink, &$s, &$rc, $unpatrolled, $watched) );
+                       array( &$this, &$articlelink, &$s, &$rc, $unpatrolled, $watched ) );
 
                $s .= " $articlelink";
        }
@@ -534,14 +534,14 @@ class ChangesList extends ContextSource {
                        $page = $rc->getTitle();
                        /** Check for rollback and edit permissions, disallow special pages, and only
                          * show a link on the top-most revision */
-                       if ( $this->getUser()->isAllowed('rollback') && $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid'] )
+                       if ( $this->getUser()->isAllowed( 'rollback' ) && $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid'] )
                        {
                                $rev = new Revision( array(
-                                       'title'     => $page,
-                                       'id'        => $rc->mAttribs['rc_this_oldid'],
-                                       'user'      => $rc->mAttribs['rc_user'],
+                                       'title' => $page,
+                                       'id' => $rc->mAttribs['rc_this_oldid'],
+                                       'user' => $rc->mAttribs['rc_user'],
                                        'user_text' => $rc->mAttribs['rc_user_text'],
-                                       'deleted'   => $rc->mAttribs['rc_deleted']
+                                       'deleted' => $rc->mAttribs['rc_deleted']
                                ) );
                                $s .= ' '.Linker::generateRollback( $rev, $this->getContext() );
                        }
@@ -554,10 +554,10 @@ class ChangesList extends ContextSource {
         * @param $classes
         */
        public function insertTags( &$s, &$rc, &$classes ) {
-               if ( empty($rc->mAttribs['ts_tags']) )
+               if ( empty( $rc->mAttribs['ts_tags'] ) )
                        return;
 
-               list($tagSummary, $newClasses) = ChangeTags::formatSummaryRow( $rc->mAttribs['ts_tags'], 'changeslist' );
+               list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow( $rc->mAttribs['ts_tags'], 'changeslist' );
                $classes = array_merge( $classes, $newClasses );
                $s .= ' ' . $tagSummary;
        }
@@ -679,7 +679,7 @@ class OldChangesList extends ChangesList {
                }
 
                if( $this->watchlist ) {
-                       $classes[] = Sanitizer::escapeClass( 'watchlist-'.$rc->mAttribs['rc_namespace'].'-'.$rc->mAttribs['rc_title'] );
+                       $classes[] = Sanitizer::escapeClass( 'watchlist-' . $rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] );
                }
 
                if ( !wfRunHooks( 'OldChangesListRecentChangesLine', array( &$this, &$s, $rc, &$classes ) ) ) {
@@ -688,7 +688,7 @@ class OldChangesList extends ChangesList {
                }
 
                wfProfileOut( __METHOD__ );
-               return "$dateheader<li class=\"".implode( ' ', $classes )."\">".$s."</li>\n";
+               return "$dateheader<li class=\"" . implode( ' ', $classes ) . "\">" . $s . "</li>\n";
        }
 }
 
@@ -822,7 +822,7 @@ class EnhancedChangesList extends ChangesList {
                        $lastLink = $this->message['last'];
                } else {
                        $lastLink = Linker::linkKnown( $rc->getTitle(), $this->message['last'],
-                               array(), $curIdEq + array('diff' => $thisOldid, 'oldid' => $lastOldid) + $rcIdQuery );
+                               array(), $curIdEq + array( 'diff' => $thisOldid, 'oldid' => $lastOldid ) + $rcIdQuery );
                }
 
                # Make user links
@@ -834,7 +834,7 @@ class EnhancedChangesList extends ChangesList {
                }
 
                $rc->lastlink = $lastLink;
-               $rc->curlink  = $curLink;
+               $rc->curlink = $curLink;
                $rc->difflink = $diffLink;
 
                # Put accumulated information into the cache, for later display
@@ -843,10 +843,10 @@ class EnhancedChangesList extends ChangesList {
                $secureName = $title->getPrefixedDBkey();
                if( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
                        # Use an @ character to prevent collision with page names
-                       $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
+                       $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array( $rc );
                } else {
                        # Logs are grouped by type
-                       if( $type == RC_LOG ){
+                       if( $type == RC_LOG ) {
                                $secureName = SpecialPage::getTitleFor( 'Log', $logType )->getPrefixedDBkey();
                        }
                        if( !isset( $this->rc_cache[$secureName] ) ) {
@@ -964,7 +964,7 @@ class EnhancedChangesList extends ChangesList {
                ) );
 
                # Timestamp
-               $r .= '&#160;'.$block[0]->timestamp.'&#160;</td><td>';
+               $r .= '&#160;' . $block[0]->timestamp . '&#160;</td><td>';
 
                # Article link
                if( $namehidden ) {
@@ -979,7 +979,7 @@ class EnhancedChangesList extends ChangesList {
 
                $queryParams['curid'] = $curId;
                # Changes message
-               $n = count($block);
+               $n = count( $block );
                static $nchanges = array();
                if ( !isset( $nchanges[$n] ) ) {
                        $nchanges[$n] = $this->msg( 'nchanges' )->numParams( $n )->escaped();
@@ -1034,7 +1034,7 @@ class EnhancedChangesList extends ChangesList {
                # Character difference (does not apply if only log items)
                if( $wgRCShowChangedSize && !$allLogs ) {
                        $last = 0;
-                       $first = count($block) - 1;
+                       $first = count( $block ) - 1;
                        # Some events (like logs) have an "empty" size, so we need to skip those...
                        while( $last < $first && $block[$last]->mAttribs['rc_new_len'] === null ) {
                                $last++;
@@ -1053,7 +1053,7 @@ class EnhancedChangesList extends ChangesList {
                }
 
                $r .= $users;
-               $r .= $this->numberofWatchingusers($block[0]->numberofWatchingusers);
+               $r .= $this->numberofWatchingusers( $block[0]->numberofWatchingusers );
 
                # Sub-entries
                foreach( $block as $rcObj ) {
@@ -1081,7 +1081,7 @@ class EnhancedChangesList extends ChangesList {
                                $link = $rcObj->timestamp;
                        # Revision link
                        } elseif( !ChangesList::userCan( $rcObj, Revision::DELETED_TEXT, $this->getUser() ) ) {
-                               $link = '<span class="history-deleted">'.$rcObj->timestamp.'</span> ';
+                               $link = '<span class="history-deleted">' . $rcObj->timestamp . '</span> ';
                        } else {
                                if ( $rcObj->unpatrolled && $type == RC_NEW) {
                                        $params['rcid'] = $rcObj->mAttribs['rc_id'];
@@ -1094,7 +1094,7 @@ class EnhancedChangesList extends ChangesList {
                                                $params
                                        );
                                if( $this->isDeleted( $rcObj, Revision::DELETED_TEXT ) ) {
-                                       $link = '<span class="history-deleted">'.$link.'</span> ';
+                                       $link = '<span class="history-deleted">' . $link . '</span> ';
                                }
                        }
                        $r .= $link . '</span>';
@@ -1144,7 +1144,7 @@ class EnhancedChangesList extends ChangesList {
         * @param $title String: text
         * @return String: HTML "<img>" tag
         */
-       protected function arrow( $dir, $alt='', $title='' ) {
+       protected function arrow( $dir, $alt = '', $title = '' ) {
                global $wgStylePath;
                $encUrl = htmlspecialchars( $wgStylePath . '/common/images/Arr_' . $dir . '.png' );
                $encAlt = htmlspecialchars( $alt );
@@ -1218,7 +1218,7 @@ class EnhancedChangesList extends ChangesList {
                                'bot' => $rcObj->mAttribs['rc_bot'],
                        ) );
                }
-               $r .= '&#160;'.$rcObj->timestamp.'&#160;</td><td>';
+               $r .= '&#160;' . $rcObj->timestamp . '&#160;</td><td>';
                # Article or log link
                if( $logType ) {
                        $logPage = new LogPage( $logType );
@@ -1250,7 +1250,7 @@ class EnhancedChangesList extends ChangesList {
                if ( $type == RC_LOG ) {
                        $r .= $this->insertLogEntry( $rcObj );
                } else {
-                       $r .= ' '.$rcObj->userlink . $rcObj->usertalklink;
+                       $r .= ' ' . $rcObj->userlink . $rcObj->usertalklink;
                        $r .= $this->insertComment( $rcObj );
                        $this->insertRollback( $r, $rcObj );
                }
@@ -1258,7 +1258,7 @@ class EnhancedChangesList extends ChangesList {
                # Tags
                $this->insertTags( $r, $rcObj, $classes );
                # Show how many people are watching this if enabled
-               $r .= $this->numberofWatchingusers($rcObj->numberofWatchingusers);
+               $r .= $this->numberofWatchingusers( $rcObj->numberofWatchingusers );
 
                $r .= "</td></tr></table>\n";
 
@@ -1291,7 +1291,7 @@ class EnhancedChangesList extends ChangesList {
 
                wfProfileOut( __METHOD__ );
 
-               return '<div>'.$blockOut.'</div>';
+               return '<div>' . $blockOut . '</div>';
        }
 
        /**
index 3cc7902..301904e 100644 (file)
@@ -43,6 +43,8 @@ abstract class Collation {
                switch( $collationName ) {
                        case 'uppercase':
                                return new UppercaseCollation;
+                       case 'uppercase-sv':
+                               return new UppercaseSvCollation;
                        case 'identity':
                                return new IdentityCollation;
                        case 'uca-default':
@@ -121,6 +123,22 @@ class UppercaseCollation extends Collation {
        }
 }
 
+/**
+ * Like UppercaseCollation but swaps Ä and Æ.
+ *
+ * This provides an ordering suitable for Swedish.
+ * @author Lejonel
+ */
+class UppercaseSvCollation extends UppercaseCollation {
+
+       /* Unicode code point order is ÄÅÆÖ, Swedish order is ÅÄÖ and Æ is often sorted as Ä.
+        * Replacing Ä for Æ should give a better collation. */
+       function getSortKey( $string ) {
+               $uppercase = $this->lang->uc( $string );
+               return strtr( $uppercase, array( 'Ä' => 'Æ', 'Æ' => 'Ä' ) );
+       }
+}
+
 /**
  * Collation class that's essentially a no-op.
  *
@@ -374,5 +392,55 @@ class IcuCollation extends Collation {
                }
                return false;
        }
-}
 
+       /**
+        * Return the version of ICU library used by PHP's intl extension,
+        * or false when the extension is not installed of the version
+        * can't be determined.
+        *
+        * The constant INTL_ICU_VERSION this function refers to isn't really
+        * documented. It is available since PHP 5.3.7 (see PHP bug 54561).
+        * This function will return false on older PHPs.
+        *
+        * @since 1.21
+        * @return string|false
+        */
+       static function getICUVersion() {
+               return defined( 'INTL_ICU_VERSION' ) ? INTL_ICU_VERSION : false;
+       }
+
+       /**
+        * Return the version of Unicode appropriate for the version of ICU library
+        * currently in use, or false when it can't be determined.
+        *
+        * @since 1.21
+        * @return string|false
+        */
+       static function getUnicodeVersionForICU() {
+               $icuVersion = IcuCollation::getICUVersion();
+               if ( !$icuVersion ) {
+                       return false;
+               }
+
+               $versionPrefix = substr( $icuVersion, 0, 3 );
+               // Source: http://site.icu-project.org/download
+               $map = array(
+                       '50.' => '6.2',
+                       '49.' => '6.1',
+                       '4.8' => '6.0',
+                       '4.6' => '6.0',
+                       '4.4' => '5.2',
+                       '4.2' => '5.1',
+                       '4.0' => '5.1',
+                       '3.8' => '5.0',
+                       '3.6' => '5.0',
+                       '3.4' => '4.1',
+               );
+
+               if ( isset( $map[$versionPrefix] ) ) {
+                       return $map[$versionPrefix];
+               } else {
+                       return false;
+               }
+       }
+}
index e563416..699e83a 100644 (file)
@@ -1095,4 +1095,3 @@ class ConfEditorToken {
                return $this->type == 'END';
        }
 }
-
index 48216f0..a6eb79a 100644 (file)
@@ -113,7 +113,7 @@ class Cookie {
                }
 
                // Don't allow cookies for "co.uk" or "gov.uk", etc, but allow "supermarket.uk"
-               if ( strrpos( $domain, "." ) - strlen( $domain )  == -3 ) {
+               if ( strrpos( $domain, "." ) - strlen( $domain ) == -3 ) {
                        if ( ( count( $dc ) == 2 && strlen( $dc[0] ) <= 2 )
                                || ( count( $dc ) == 3 && strlen( $dc[0] ) == "" && strlen( $dc[1] ) <= 2 ) ) {
                                return false;
@@ -165,8 +165,8 @@ class Cookie {
        protected function canServeDomain( $domain ) {
                if ( $domain == $this->domain
                        || ( strlen( $domain ) > strlen( $this->domain )
-                                && substr( $this->domain, 0, 1 ) == '.'
-                                && substr_compare( $domain, $this->domain, -strlen( $this->domain ),
+                               && substr( $this->domain, 0, 1 ) == '.'
+                               && substr_compare( $domain, $this->domain, -strlen( $this->domain ),
                                                                        strlen( $this->domain ), true ) == 0 ) ) {
                        return true;
                }
index fcf6a39..4255d56 100644 (file)
@@ -106,7 +106,11 @@ class MWCryptRand {
                                        }
                                }
                                // The absolute filename itself will differ from install to install so don't leave it out
-                               $state .= realpath( $file );
+                               if( ( $path = realpath( $file ) ) !== false ) {
+                                       $state .= $path;
+                               } else {
+                                       $state .= $file;
+                               }
                                $state .= implode( '', $stat );
                        } else {
                                // The fact that the file isn't there is worth at least a
index a6d745f..a6eed69 100644 (file)
@@ -47,7 +47,7 @@
  * This is not a valid entry point, perform no further processing unless
  * MEDIAWIKI is defined
  */
-if( !defined( 'MEDIAWIKI' ) ) {
+if ( !defined( 'MEDIAWIKI' ) ) {
        echo "This file is part of MediaWiki and is not a valid entry point\n";
        die( 1 );
 }
@@ -104,7 +104,7 @@ $wgCanonicalServer = false;
  * Other paths will be set to defaults based on it unless they are directly
  * set in LocalSettings.php
  */
-$wgScriptPath       = '/wiki';
+$wgScriptPath = '/wiki';
 
 /**
  * Whether to support URLs like index.php/Page_title These often break when PHP
@@ -122,10 +122,9 @@ $wgScriptPath       = '/wiki';
  * you have customized it, having this incorrectly set to true can cause
  * redirect loops when "pretty URLs" are used.
  */
-$wgUsePathInfo =
-       ( strpos( php_sapi_name(), 'cgi' ) === false ) &&
-       ( strpos( php_sapi_name(), 'apache2filter' ) === false ) &&
-       ( strpos( php_sapi_name(), 'isapi' ) === false );
+$wgUsePathInfo = ( strpos( PHP_SAPI, 'cgi' ) === false ) &&
+       ( strpos( PHP_SAPI, 'apache2filter' ) === false ) &&
+       ( strpos( PHP_SAPI, 'isapi' ) === false );
 
 /**
  * The extension to append to script names by default. This can either be .php
@@ -134,7 +133,7 @@ $wgUsePathInfo =
  * Some hosting providers use PHP 4 for *.php files, and PHP 5 for *.php5. This
  * variable is provided to support those providers.
  */
-$wgScriptExtension  = '.php';
+$wgScriptExtension = '.php';
 
 
 /**@}*/
@@ -438,14 +437,34 @@ $wgUseInstantCommons = false;
 
 /**
  * File backend structure configuration.
+ *
  * This is an array of file backend configuration arrays.
  * Each backend configuration has the following parameters:
- *  - 'name'        : A unique name for the backend
- *  - 'class'       : The file backend class to use
- *  - 'wikiId'      : A unique string that identifies the wiki (container prefix)
- *  - 'lockManager' : The name of a lock manager (see $wgLockManagers)
- *
- * Additional parameters are specific to the class used.
+ *  - 'name'         : A unique name for the backend
+ *  - 'class'        : The file backend class to use
+ *  - 'wikiId'       : A unique string that identifies the wiki (container prefix)
+ *  - 'lockManager'  : The name of a lock manager (see $wgLockManagers)
+ *
+ * See FileBackend::__construct() for more details.
+ * Additional parameters are specific to the file backend class used.
+ * These settings should be global to all wikis when possible.
+ *
+ * There are two particularly important aspects about each backend:
+ *   - a) Whether it is fully qualified or wiki-relative.
+ *        By default, the paths of files are relative to the current wiki,
+ *        which works via prefixing them with the current wiki ID when accessed.
+ *        Setting 'wikiId' forces the backend to be fully qualified by prefixing
+ *        all paths with the specified value instead. This can be useful if
+ *        multiple wikis need to share the same data. Note that 'name' is *not*
+ *        part of any prefix and thus should not be relied upon for namespacing.
+ *   - b) Whether it is only defined for some wikis or is defined on all
+ *        wikis in the wiki farm. Defining a backend globally is useful
+ *        if multiple wikis need to share the same data.
+ * One should be aware of these aspects when configuring a backend for use with
+ * any basic feature or plugin. For example, suppose an extension stores data for
+ * different wikis in different directories and sometimes needs to access data from
+ * a foreign wiki's directory in order to render a page on given wiki. The extension
+ * would need a fully qualified backend that is defined on all wikis in the wiki farm.
  */
 $wgFileBackends = array();
 
@@ -454,7 +473,10 @@ $wgFileBackends = array();
  * Each backend configuration has the following parameters:
  *  - 'name'        : A unique name for the lock manager
  *  - 'class'       : The lock manger class to use
- * Additional parameters are specific to the class used.
+ *
+ * See LockManager::__construct() for more details.
+ * Additional parameters are specific to the lock manager class used.
+ * These settings should be global to all wikis.
  */
 $wgLockManagers = array();
 
@@ -562,7 +584,7 @@ $wgCopyUploadProxy = false;
  * will have a maximum of 500 kB.
  *
  */
-$wgMaxUploadSize = 1024*1024*100; # 100MB
+$wgMaxUploadSize = 1024 * 1024 * 100; # 100MB
 
 /**
  * Point the upload navigation link to an external URL
@@ -663,7 +685,7 @@ $wgFileBlacklist = array(
  */
 $wgMimeTypeBlacklist = array(
        # HTML may contain cookie-stealing JavaScript and web bugs
-       'text/html', 'text/javascript', 'text/x-javascript',  'application/x-shellscript',
+       'text/html', 'text/javascript', 'text/x-javascript', 'application/x-shellscript',
        # PHP scripts may execute arbitrary code on the server
        'application/x-php', 'text/x-php',
        # Other types that may be interpreted by some servers
@@ -721,10 +743,10 @@ $wgUploadSizeWarning = false;
  */
 $wgTrustedMediaFormats = array(
        MEDIATYPE_BITMAP, //all bitmap formats
-       MEDIATYPE_AUDIO,  //all audio formats
-       MEDIATYPE_VIDEO,  //all plain video formats
-       "image/svg+xml",  //svg (only needed if inline rendering of svg is not supported)
-       "application/pdf",  //PDF files
+       MEDIATYPE_AUDIO, //all audio formats
+       MEDIATYPE_VIDEO, //all plain video formats
+       "image/svg+xml", //svg (only needed if inline rendering of svg is not supported)
+       "application/pdf", //PDF files
        #"application/x-shockwave-flash", //flash/shockwave movie
 );
 
@@ -733,18 +755,18 @@ $wgTrustedMediaFormats = array(
  * Each entry in the array maps a MIME type to a class name
  */
 $wgMediaHandlers = array(
-       'image/jpeg'     => 'JpegHandler',
-       'image/png'      => 'PNGHandler',
-       'image/gif'      => 'GIFHandler',
-       'image/tiff'     => 'TiffHandler',
+       'image/jpeg' => 'JpegHandler',
+       'image/png' => 'PNGHandler',
+       'image/gif' => 'GIFHandler',
+       'image/tiff' => 'TiffHandler',
        'image/x-ms-bmp' => 'BmpHandler',
-       'image/x-bmp'    => 'BmpHandler',
-       'image/x-xcf'    => 'XCFHandler',
-       'image/svg+xml'  => 'SvgHandler', // official
-       'image/svg'      => 'SvgHandler', // compat
+       'image/x-bmp' => 'BmpHandler',
+       'image/x-xcf' => 'XCFHandler',
+       'image/svg+xml' => 'SvgHandler', // official
+       'image/svg' => 'SvgHandler', // compat
        'image/vnd.djvu' => 'DjVuHandler', // official
-       'image/x.djvu'   => 'DjVuHandler', // compat
-       'image/x-djvu'   => 'DjVuHandler', // compat
+       'image/x.djvu' => 'DjVuHandler', // compat
+       'image/x-djvu' => 'DjVuHandler', // compat
 );
 
 /**
@@ -827,7 +849,7 @@ $wgSVGConverters = array(
        'rsvg' => '$path/rsvg -w$width -h$height $input $output',
        'imgserv' => '$path/imgserv-wrapper -i svg -o png -w$width $input $output',
        'ImagickExt' => array( 'SvgHandler::rasterizeImagickExt' ),
-       );
+);
 
 /** Pick a converter defined in $wgSVGConverters */
 $wgSVGConverter = 'ImageMagick';
@@ -890,7 +912,7 @@ $wgMaxAnimatedGifArea = 1.25e7;
  *  $wgTiffThumbnailType = array( 'jpg', 'image/jpeg' );
  * @endcode
  */
- $wgTiffThumbnailType = false;
+$wgTiffThumbnailType = false;
 
 /**
  * If rendered thumbnail files are older than this timestamp, they
@@ -923,8 +945,8 @@ $wgIgnoreImageErrors = false;
 $wgGenerateThumbnailOnParse = true;
 
 /**
-* Show thumbnails for old images on the image description page
-*/
+ * Show thumbnails for old images on the image description page
+ */
 $wgShowArchiveThumbnails = true;
 
 /** Obsolete, always true, kept for compatibility with extensions */
@@ -981,16 +1003,14 @@ $wgAntivirus = null;
 $wgAntivirusSetup = array(
 
        #setup for clamav
-       'clamav' => array (
-               'command' => "clamscan --no-summary ",
-
-               'codemap' => array (
-                       "0" =>  AV_NO_VIRUS, # no virus
-                       "1" =>  AV_VIRUS_FOUND, # virus found
+       'clamav' => array(
+               'command' => 'clamscan --no-summary ',
+               'codemap' => array(
+                       "0" => AV_NO_VIRUS, # no virus
+                       "1" => AV_VIRUS_FOUND, # virus found
                        "52" => AV_SCAN_ABORTED, # unsupported file format (probably imune)
-                       "*" =>  AV_SCAN_FAILED, # else scan failed
+                       "*" => AV_SCAN_FAILED, # else scan failed
                ),
-
                'messagepattern' => '/.*?:(.*)/sim',
        ),
 );
@@ -1003,13 +1023,13 @@ $wgAntivirusRequired = true;
 $wgVerifyMimeType = true;
 
 /** Sets the mime type definition file to use by MimeMagic.php. */
-$wgMimeTypeFile = "includes/mime.types";
-#$wgMimeTypeFile= "/etc/mime.types";
-#$wgMimeTypeFile= null; #use built-in defaults only.
+$wgMimeTypeFile = 'includes/mime.types';
+#$wgMimeTypeFile = '/etc/mime.types';
+#$wgMimeTypeFile = null; #use built-in defaults only.
 
 /** Sets the mime type info file to use by MimeMagic.php. */
-$wgMimeInfoFile= "includes/mime.info";
-#$wgMimeInfoFile= null; #use built-in defaults only.
+$wgMimeInfoFile = 'includes/mime.info';
+#$wgMimeInfoFile = null; #use built-in defaults only.
 
 /**
  * Switch for loading the FileInfo extension by PECL at runtime.
@@ -1042,11 +1062,11 @@ $wgTrivialMimeDetection = false;
  * array = ( 'rootElement' => 'associatedMimeType' )
  */
 $wgXMLMimeTypes = array(
-       'http://www.w3.org/2000/svg:svg'               => 'image/svg+xml',
-       'svg'                                          => 'image/svg+xml',
+       '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?
+       'http://www.w3.org/1999/xhtml:html' => 'text/html', // application/xhtml+xml?
+       'html' => 'text/html', // application/xhtml+xml?
 );
 
 /**
@@ -1082,7 +1102,7 @@ $wgThumbLimits = array(
 /**
  * Default parameters for the "<gallery>" tag
  */
-$wgGalleryOptions = array (
+$wgGalleryOptions = array(
        'imagesPerRow' => 0, // Default number of images per-row in the gallery. 0 -> Adapt to screensize
        'imageWidth' => 120, // Width of the cells containing images in galleries (in "px")
        'imageHeight' => 120, // Height of the cells containing images in galleries (in "px")
@@ -1247,12 +1267,12 @@ $wgUserEmailConfirmationTokenExpiry = 7 * 24 * 60 * 60;
  *
  * @code
  * $wgSMTP = array(
- *     'host'     => 'SMTP domain',
- *     'IDHost'   => 'domain for MessageID',
- *     'port'     => '25',
- *     'auth'     => [true|false],
- *     'username' => [SMTP username],
- *     'password' => [SMTP password],
+ *     'host'     => 'SMTP domain',
+ *     'IDHost'   => 'domain for MessageID',
+ *     'port'     => '25',
+ *     'auth'     => [true|false],
+ *     'username' => [SMTP username],
+ *     'password' => [SMTP password],
  * );
  * @endcode
  */
@@ -1606,7 +1626,7 @@ $wgExternalStores = false;
  * Create a cluster named 'cluster1' containing three servers:
  * @code
  * $wgExternalServers = array(
- *     'cluster1' => array( 'srv28', 'srv29', 'srv30' )
+ *     'cluster1' => array( 'srv28', 'srv29', 'srv30' )
  * );
  * @endcode
  *
@@ -2168,7 +2188,21 @@ $wgUsePrivateIPs = false;
  * @{
  */
 
-/** Site language code, should be one of ./languages/Language(.*).php */
+/**
+ * Site language code. See languages/Names.php for languages supported by
+ * MediaWiki out of the box. Not all languages listed there have translations,
+ * see languages/messages/ for the list of languages with some localisation.
+ *
+ * Warning: Don't use language codes listed in $wgDummyLanguageCodes like "no"
+ * for Norwegian (use "nb" instead), or things will break unexpectedly.
+ *
+ * This defines the default interface language for all users, but users can
+ * change it in their preferences.
+ *
+ * This also defines the language of pages in the wiki. The content is wrapped
+ * in a html element with lang=XX attribute. This behaviour can be overriden
+ * via hooks, see Title::getPageLanguage.
+ */
 $wgLanguageCode = 'en';
 
 /**
@@ -2331,16 +2365,11 @@ $wgBrowserBlackList = array(
  */
 $wgLegacySchemaConversion = false;
 
-/**
- * Enable to allow rewriting dates in page text.
- * DOES NOT FORMAT CORRECTLY FOR MOST LANGUAGES.
- */
-$wgUseDynamicDates  = false;
 /**
  * Enable dates like 'May 12' instead of '12 May', this only takes effect if
  * the interface is set to English.
  */
-$wgAmericanDates    = false;
+$wgAmericanDates = false;
 /**
  * For Hindi and Arabic use local numerals instead of Western style (0-9)
  * numerals in interface.
@@ -2393,9 +2422,9 @@ $wgDisabledVariants = array();
  *
  * @par Example:
  * @code
- *     $wgLanguageCode = 'sr';
- *     $wgVariantArticlePath = '/$2/$1';
- *     $wgArticlePath = '/wiki/$1';
+ *     $wgLanguageCode = 'sr';
+ *     $wgVariantArticlePath = '/$2/$1';
+ *     $wgArticlePath = '/wiki/$1';
  * @endcode
  *
  * A link to /wiki/ would be redirected to /sr/Главна_страна
@@ -2428,7 +2457,7 @@ $wgLoginLanguageSelector = false;
  * To allow language-specific main page and community
  * portal:
  * @code
- *     $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
+ *     $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
  * @endcode
  */
 $wgForceUIMsgAsContentMsg = array();
@@ -2962,21 +2991,21 @@ $wgPreloadJavaScriptMwUtil = false;
  *
  * @par Example of legacy code:
  * @code{,js}
- *     if ( window.wgRestrictionEdit ) { ... }
+ *     if ( window.wgRestrictionEdit ) { ... }
  * @endcode
  * or:
  * @code{,js}
- *     if ( wgIsArticle ) { ... }
+ *     if ( wgIsArticle ) { ... }
  * @endcode
  *
  * Instead, one needs to use mw.config.
  * @par Example using mw.config global configuration:
  * @code{,js}
- *     if ( mw.config.exists('wgRestrictionEdit') ) { ... }
+ *     if ( mw.config.exists('wgRestrictionEdit') ) { ... }
  * @endcode
  * or:
  * @code{,js}
- *     if ( mw.config.get('wgIsArticle') ) { ... }
+ *     if ( mw.config.get('wgIsArticle') ) { ... }
  * @endcode
  */
 $wgLegacyJavaScriptGlobals = true;
@@ -3157,13 +3186,13 @@ $wgInterwikiExpiry = 10800;
 $wgInterwikiCache = false;
 /**
  * Specify number of domains to check for messages.
- *     - 1: Just wiki(db)-level
- *     - 2: wiki and global levels
- *     - 3: site levels
+ *    - 1: Just wiki(db)-level
+ *    - 2: wiki and global levels
+ *    - 3: site levels
  */
 $wgInterwikiScopes = 3;
 /**
- *     $wgInterwikiFallbackSite - if unable to resolve from cache
+ *    $wgInterwikiFallbackSite - if unable to resolve from cache
  */
 $wgInterwikiFallbackSite = 'wiki';
 /** @} */ # end of Interwiki caching settings.
@@ -3205,7 +3234,7 @@ $wgCapitalLinks = true;
  *
  * @par Example:
  * @code
- *     $wgCapitalLinkOverrides[ NS_FILE ] = false;
+ *     $wgCapitalLinkOverrides[ NS_FILE ] = false;
  * @endcode
  */
 $wgCapitalLinkOverrides = array();
@@ -3214,16 +3243,18 @@ $wgCapitalLinkOverrides = array();
  * See Language.php for a list of namespaces.
  */
 $wgNamespacesWithSubpages = array(
-       NS_TALK           => true,
-       NS_USER           => true,
-       NS_USER_TALK      => true,
-       NS_PROJECT_TALK   => true,
-       NS_FILE_TALK      => true,
-       NS_MEDIAWIKI      => true,
+       NS_TALK => true,
+       NS_USER => true,
+       NS_USER_TALK => true,
+       NS_PROJECT => true,
+       NS_PROJECT_TALK => true,
+       NS_FILE_TALK => true,
+       NS_MEDIAWIKI => true,
        NS_MEDIAWIKI_TALK => true,
-       NS_TEMPLATE_TALK  => true,
-       NS_HELP_TALK      => true,
-       NS_CATEGORY_TALK  => true
+       NS_TEMPLATE_TALK => true,
+       NS_HELP => true,
+       NS_HELP_TALK => true,
+       NS_CATEGORY_TALK => true
 );
 
 /**
@@ -3325,7 +3356,7 @@ $wgUrlProtocols = array(
        'https://',
        'ftp://',
        'irc://',
-       'ircs://',  // @bug 28503
+       'ircs://', // @bug 28503
        'gopher://',
        'telnet://', // Well if we're going to support the above.. -ævar
        'nntp://', // @bug 3808 RFC 1738
@@ -3401,7 +3432,7 @@ $wgAlwaysUseTidy = false;
 /** @see $wgUseTidy */
 $wgTidyBin = 'tidy';
 /** @see $wgUseTidy */
-$wgTidyConf = $IP.'/includes/tidy.conf';
+$wgTidyConf = $IP . '/includes/tidy.conf';
 /** @see $wgUseTidy */
 $wgTidyOpts = '';
 /** @see $wgUseTidy */
@@ -3597,68 +3628,68 @@ $wgReservedUsernames = array(
  *
  */
 $wgDefaultUserOptions = array(
-       'ccmeonemails'            => 0,
-       'cols'                    => 80,
-       'date'                    => 'default',
-       'diffonly'                => 0,
-       'disablemail'             => 0,
-       'disablesuggest'          => 0,
-       'editfont'                => 'default',
-       'editondblclick'          => 0,
-       'editsection'             => 1,
+       'ccmeonemails' => 0,
+       'cols' => 80,
+       'date' => 'default',
+       'diffonly' => 0,
+       'disablemail' => 0,
+       'disablesuggest' => 0,
+       'editfont' => 'default',
+       'editondblclick' => 0,
+       'editsection' => 1,
        'editsectiononrightclick' => 0,
-       'enotifminoredits'        => 0,
-       'enotifrevealaddr'        => 0,
-       'enotifusertalkpages'     => 1,
-       'enotifwatchlistpages'    => 0,
-       'extendwatchlist'         => 0,
-       'externaldiff'            => 0,
-       'externaleditor'          => 0,
-       'fancysig'                => 0,
-       'forceeditsummary'        => 0,
-       'gender'                  => 'unknown',
-       'hideminor'               => 0,
-       'hidepatrolled'           => 0,
-       'imagesize'               => 2,
-       'justify'                 => 0,
-       'math'                    => 1,
-       'minordefault'            => 0,
-       'newpageshidepatrolled'   => 0,
-       'nocache'                 => 0,
-       'noconvertlink'           => 0,
-       'norollbackdiff'          => 0,
-       'numberheadings'          => 0,
-       'previewonfirst'          => 0,
-       'previewontop'            => 1,
-       'quickbar'                => 5,
-       'rcdays'                  => 7,
-       'rclimit'                 => 50,
-       'rememberpassword'        => 0,
-       'rows'                    => 25,
-       'searchlimit'             => 20,
-       'showhiddencats'          => 0,
-       'showjumplinks'           => 1,
-       'shownumberswatching'     => 1,
-       'showtoc'                 => 1,
-       'showtoolbar'             => 1,
-       'skin'                    => false,
-       'stubthreshold'           => 0,
-       'thumbsize'               => 2,
-       'underline'               => 2,
-       'uselivepreview'          => 0,
-       'usenewrc'                => 0,
-       'watchcreations'          => 0,
-       'watchdefault'            => 0,
-       'watchdeletion'           => 0,
-       'watchlistdays'           => 3.0,
-       'watchlisthideanons'      => 0,
-       'watchlisthidebots'       => 0,
-       'watchlisthideliu'        => 0,
-       'watchlisthideminor'      => 0,
-       'watchlisthideown'        => 0,
-       'watchlisthidepatrolled'  => 0,
-       'watchmoves'              => 0,
-       'wllimit'                 => 250,
+       'enotifminoredits' => 0,
+       'enotifrevealaddr' => 0,
+       'enotifusertalkpages' => 1,
+       'enotifwatchlistpages' => 0,
+       'extendwatchlist' => 0,
+       'externaldiff' => 0,
+       'externaleditor' => 0,
+       'fancysig' => 0,
+       'forceeditsummary' => 0,
+       'gender' => 'unknown',
+       'hideminor' => 0,
+       'hidepatrolled' => 0,
+       'imagesize' => 2,
+       'justify' => 0,
+       'math' => 1,
+       'minordefault' => 0,
+       'newpageshidepatrolled' => 0,
+       'nocache' => 0,
+       'noconvertlink' => 0,
+       'norollbackdiff' => 0,
+       'numberheadings' => 0,
+       'previewonfirst' => 0,
+       'previewontop' => 1,
+       'quickbar' => 5,
+       'rcdays' => 7,
+       'rclimit' => 50,
+       'rememberpassword' => 0,
+       'rows' => 25,
+       'searchlimit' => 20,
+       'showhiddencats' => 0,
+       'showjumplinks' => 1,
+       'shownumberswatching' => 1,
+       'showtoc' => 1,
+       'showtoolbar' => 1,
+       'skin' => false,
+       'stubthreshold' => 0,
+       'thumbsize' => 2,
+       'underline' => 2,
+       'uselivepreview' => 0,
+       'usenewrc' => 0,
+       'watchcreations' => 0,
+       'watchdefault' => 0,
+       'watchdeletion' => 0,
+       'watchlistdays' => 3.0,
+       'watchlisthideanons' => 0,
+       'watchlisthidebots' => 0,
+       'watchlisthideliu' => 0,
+       'watchlisthideminor' => 0,
+       'watchlisthideown' => 0,
+       'watchlisthidepatrolled' => 0,
+       'watchmoves' => 0,
+       'wllimit' => 250,
 );
 
 /** An array of preferences to not show for the user */
@@ -3747,6 +3778,13 @@ $wgAllowPrefChange = array();
  */
 $wgSecureLogin = false;
 
+/**
+ * By default, keep users logged in via HTTPS when $wgSecureLogin is also
+ * true. Users opt-out of HTTPS when they login by de-selecting the checkbox.
+ * @since 1.21
+ */
+$wgSecureLoginDefaultHTTPS = true;
+
 /** @} */ # end user accounts }
 
 /************************************************************************//**
@@ -3814,6 +3852,34 @@ $wgBlockDisablesLogin = false;
  */
 $wgWhitelistRead = false;
 
+/**
+ * Pages anonymous user may see, set as an array of regular expressions.
+ *
+ * This function will match the regexp against the title name, which
+ * is without underscore.
+ *
+ * @par Example:
+ * To whitelist [[Main Page]]:
+ * @code
+ * $wgWhitelistReadRegexp = array( "/Main Page/" );
+ * @endcode
+ *
+ * @note Unless ^ and/or $ is specified, a regular expression might match
+ * pages not intended to be whitelisted.  The above example will also
+ * whitelist a page named 'Security Main Page'.
+ *
+ * @par Example:
+ * To allow reading any page starting with 'User' regardless of the case:
+ * @code
+ * $wgWhitelistReadRegexp = array( "@^UsEr.*@i" );
+ * @endcode
+ * Will allow both [[User is banned]] and [[User:JohnDoe]]
+ *
+ * @note This will only work if $wgGroupPermissions['*']['read'] is false --
+ * see below. Otherwise, ALL pages are accessible, regardless of this setting.
+ */
+$wgWhitelistReadRegexp = false;
+
 /**
  * Should editors be required to have a validated e-mail
  * address before being allowed to edit?
@@ -3848,85 +3914,85 @@ $wgGroupPermissions = array();
 
 /** @cond file_level_code */
 // Implicit group for all visitors
-$wgGroupPermissions['*']['createaccount']    = true;
-$wgGroupPermissions['*']['read']             = true;
-$wgGroupPermissions['*']['edit']             = true;
-$wgGroupPermissions['*']['createpage']       = true;
-$wgGroupPermissions['*']['createtalk']       = true;
-$wgGroupPermissions['*']['writeapi']         = true;
+$wgGroupPermissions['*']['createaccount'] = true;
+$wgGroupPermissions['*']['read'] = true;
+$wgGroupPermissions['*']['edit'] = true;
+$wgGroupPermissions['*']['createpage'] = true;
+$wgGroupPermissions['*']['createtalk'] = true;
+$wgGroupPermissions['*']['writeapi'] = true;
 //$wgGroupPermissions['*']['patrolmarks']      = false; // let anons see what was patrolled
 
 // Implicit group for all logged-in accounts
-$wgGroupPermissions['user']['move']             = true;
-$wgGroupPermissions['user']['move-subpages']    = true;
+$wgGroupPermissions['user']['move'] = true;
+$wgGroupPermissions['user']['move-subpages'] = true;
 $wgGroupPermissions['user']['move-rootuserpages'] = true; // can move root userpages
-$wgGroupPermissions['user']['movefile']         = true;
-$wgGroupPermissions['user']['read']             = true;
-$wgGroupPermissions['user']['edit']             = true;
-$wgGroupPermissions['user']['createpage']       = true;
-$wgGroupPermissions['user']['createtalk']       = true;
-$wgGroupPermissions['user']['writeapi']         = true;
-$wgGroupPermissions['user']['upload']           = true;
-$wgGroupPermissions['user']['reupload']         = true;
-$wgGroupPermissions['user']['reupload-shared']  = true;
-$wgGroupPermissions['user']['minoredit']        = true;
-$wgGroupPermissions['user']['purge']            = true; // can use ?action=purge without clicking "ok"
-$wgGroupPermissions['user']['sendemail']        = true;
+$wgGroupPermissions['user']['movefile'] = true;
+$wgGroupPermissions['user']['read'] = true;
+$wgGroupPermissions['user']['edit'] = true;
+$wgGroupPermissions['user']['createpage'] = true;
+$wgGroupPermissions['user']['createtalk'] = true;
+$wgGroupPermissions['user']['writeapi'] = true;
+$wgGroupPermissions['user']['upload'] = true;
+$wgGroupPermissions['user']['reupload'] = true;
+$wgGroupPermissions['user']['reupload-shared'] = true;
+$wgGroupPermissions['user']['minoredit'] = true;
+$wgGroupPermissions['user']['purge'] = true; // can use ?action=purge without clicking "ok"
+$wgGroupPermissions['user']['sendemail'] = true;
 
 // Implicit group for accounts that pass $wgAutoConfirmAge
 $wgGroupPermissions['autoconfirmed']['autoconfirmed'] = true;
 
 // Users with bot privilege can have their edits hidden
 // from various log pages by default
-$wgGroupPermissions['bot']['bot']              = true;
-$wgGroupPermissions['bot']['autoconfirmed']    = true;
-$wgGroupPermissions['bot']['nominornewtalk']   = true;
-$wgGroupPermissions['bot']['autopatrol']       = true;
+$wgGroupPermissions['bot']['bot'] = true;
+$wgGroupPermissions['bot']['autoconfirmed'] = true;
+$wgGroupPermissions['bot']['nominornewtalk'] = true;
+$wgGroupPermissions['bot']['autopatrol'] = true;
 $wgGroupPermissions['bot']['suppressredirect'] = true;
-$wgGroupPermissions['bot']['apihighlimits']    = true;
-$wgGroupPermissions['bot']['writeapi']         = true;
+$wgGroupPermissions['bot']['apihighlimits'] = true;
+$wgGroupPermissions['bot']['writeapi'] = true;
 #$wgGroupPermissions['bot']['editprotected']    = true; // can edit all protected pages without cascade protection enabled
 
 // Most extra permission abilities go to this group
-$wgGroupPermissions['sysop']['block']            = true;
-$wgGroupPermissions['sysop']['createaccount']    = true;
-$wgGroupPermissions['sysop']['delete']           = true;
-$wgGroupPermissions['sysop']['bigdelete']        = true; // can be separately configured for pages with > $wgDeleteRevisionsLimit revs
-$wgGroupPermissions['sysop']['deletedhistory']   = true; // can view deleted history entries, but not see or restore the text
-$wgGroupPermissions['sysop']['deletedtext']      = true; // can view deleted revision text
-$wgGroupPermissions['sysop']['undelete']         = true;
-$wgGroupPermissions['sysop']['editinterface']    = true;
-$wgGroupPermissions['sysop']['editusercss']      = true;
-$wgGroupPermissions['sysop']['edituserjs']       = true;
-$wgGroupPermissions['sysop']['import']           = true;
-$wgGroupPermissions['sysop']['importupload']     = true;
-$wgGroupPermissions['sysop']['move']             = true;
-$wgGroupPermissions['sysop']['move-subpages']    = true;
+$wgGroupPermissions['sysop']['block'] = true;
+$wgGroupPermissions['sysop']['createaccount'] = true;
+$wgGroupPermissions['sysop']['delete'] = true;
+$wgGroupPermissions['sysop']['bigdelete'] = true; // can be separately configured for pages with > $wgDeleteRevisionsLimit revs
+$wgGroupPermissions['sysop']['deletedhistory'] = true; // can view deleted history entries, but not see or restore the text
+$wgGroupPermissions['sysop']['deletedtext'] = true; // can view deleted revision text
+$wgGroupPermissions['sysop']['undelete'] = true;
+$wgGroupPermissions['sysop']['editinterface'] = true;
+$wgGroupPermissions['sysop']['editusercss'] = true;
+$wgGroupPermissions['sysop']['edituserjs'] = true;
+$wgGroupPermissions['sysop']['import'] = true;
+$wgGroupPermissions['sysop']['importupload'] = true;
+$wgGroupPermissions['sysop']['move'] = true;
+$wgGroupPermissions['sysop']['move-subpages'] = true;
 $wgGroupPermissions['sysop']['move-rootuserpages'] = true;
-$wgGroupPermissions['sysop']['patrol']           = true;
-$wgGroupPermissions['sysop']['autopatrol']       = true;
-$wgGroupPermissions['sysop']['protect']          = true;
-$wgGroupPermissions['sysop']['proxyunbannable']  = true;
-$wgGroupPermissions['sysop']['rollback']         = true;
-$wgGroupPermissions['sysop']['upload']           = true;
-$wgGroupPermissions['sysop']['reupload']         = true;
-$wgGroupPermissions['sysop']['reupload-shared']  = true;
-$wgGroupPermissions['sysop']['unwatchedpages']   = true;
-$wgGroupPermissions['sysop']['autoconfirmed']    = true;
-$wgGroupPermissions['sysop']['ipblock-exempt']   = true;
-$wgGroupPermissions['sysop']['blockemail']       = true;
-$wgGroupPermissions['sysop']['markbotedits']     = true;
-$wgGroupPermissions['sysop']['apihighlimits']    = true;
-$wgGroupPermissions['sysop']['browsearchive']    = true;
-$wgGroupPermissions['sysop']['noratelimit']      = true;
-$wgGroupPermissions['sysop']['movefile']         = true;
-$wgGroupPermissions['sysop']['unblockself']      = true;
+$wgGroupPermissions['sysop']['patrol'] = true;
+$wgGroupPermissions['sysop']['autopatrol'] = true;
+$wgGroupPermissions['sysop']['protect'] = true;
+$wgGroupPermissions['sysop']['proxyunbannable'] = true;
+$wgGroupPermissions['sysop']['rollback'] = true;
+$wgGroupPermissions['sysop']['upload'] = true;
+$wgGroupPermissions['sysop']['reupload'] = true;
+$wgGroupPermissions['sysop']['reupload-shared'] = true;
+$wgGroupPermissions['sysop']['unwatchedpages'] = true;
+$wgGroupPermissions['sysop']['autoconfirmed'] = true;
+$wgGroupPermissions['sysop']['ipblock-exempt'] = true;
+$wgGroupPermissions['sysop']['blockemail'] = true;
+$wgGroupPermissions['sysop']['markbotedits'] = true;
+$wgGroupPermissions['sysop']['apihighlimits'] = true;
+$wgGroupPermissions['sysop']['browsearchive'] = true;
+$wgGroupPermissions['sysop']['noratelimit'] = true;
+$wgGroupPermissions['sysop']['movefile'] = true;
+$wgGroupPermissions['sysop']['unblockself'] = true;
 $wgGroupPermissions['sysop']['suppressredirect'] = true;
 #$wgGroupPermissions['sysop']['upload_by_url']    = true;
 #$wgGroupPermissions['sysop']['mergehistory']     = true;
 
 // Permission to change users' group assignments
-$wgGroupPermissions['bureaucrat']['userrights']  = true;
+$wgGroupPermissions['bureaucrat']['userrights'] = true;
 $wgGroupPermissions['bureaucrat']['noratelimit'] = true;
 // Permission to change users' groups assignments across wikis
 #$wgGroupPermissions['bureaucrat']['userrights-interwiki'] = true;
@@ -4107,11 +4173,11 @@ $wgAutopromote = array(
  *
  * The format is:
  * @code
- *     array( event => criteria, ... )
+ *    array( event => criteria, ... )
  * @endcode
  * Where event is either:
- *     - 'onEdit' (when user edits)
- *     - 'onView' (when user views the wiki)
+ *    - 'onEdit' (when user edits)
+ *    - 'onView' (when user views the wiki)
  *
  * Criteria has the same format as $wgAutopromote
  *
@@ -4170,7 +4236,8 @@ $wgDeleteRevisionsLimit = 0;
 /**
  * Number of accounts each IP address may create, 0 to disable.
  *
- * @warning Requires memcached */
+ * @warning Requires memcached
+ */
 $wgAccountCreationThrottle = 0;
 
 /**
@@ -4261,25 +4328,25 @@ $wgProxyWhitelist = array();
  */
 $wgRateLimits = array(
        'edit' => array(
-               'anon'   => null, // for any and all anonymous edits (aggregate)
-               'user'   => null, // for each logged-in user
+               'anon' => null, // for any and all anonymous edits (aggregate)
+               'user' => null, // for each logged-in user
                'newbie' => null, // for each recent (autoconfirmed) account; overrides 'user'
-               'ip'     => null, // for each anon and recent account
+               'ip' => null, // for each anon and recent account
                'subnet' => null, // ... with final octet removed
-               ),
+       ),
        'move' => array(
-               'user'   => null,
+               'user' => null,
                'newbie' => null,
-               'ip'     => null,
+               'ip' => null,
                'subnet' => null,
-               ),
+       ),
        'mailpassword' => array(
                'anon' => null,
-               ),
+       ),
        'emailuser' => array(
                'user' => null,
-               ),
-       );
+       ),
+);
 
 /**
  * Set to a filename to log rate limiter hits.
@@ -4364,7 +4431,7 @@ $wgProxyKey = false;
 /**
  * Default cookie expiration time. Setting to 0 makes all cookies session-only.
  */
-$wgCookieExpiration = 180*86400;
+$wgCookieExpiration = 180 * 86400;
 
 /**
  * Set to set an explicit domain on the login cookies eg, "justthis.domain.org"
@@ -4426,7 +4493,7 @@ $wgCacheVaryCookies = array();
 /** Override to customise the session name */
 $wgSessionName = false;
 
-/** @} */  # end of cookie settings }
+/** @} */ # end of cookie settings }
 
 /************************************************************************//**
  * @name   LaTeX (mathematical formulas)
@@ -4816,7 +4883,7 @@ $wgNamespacesToBeSearchedDefault = array(
  */
 $wgNamespacesToBeSearchedHelp = array(
        NS_PROJECT => true,
-       NS_HELP    => true,
+       NS_HELP => true,
 );
 
 /**
@@ -4843,10 +4910,10 @@ $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' .
- *     '&ie=utf-8&oe=utf-8';
+ *     'http://www.google.com/search?q=$1' .
+ *     '&domains=http://example.com' .
+ *     '&sitesearch=http://example.com' .
+ *     '&ie=utf-8&oe=utf-8';
  * @endcode
  */
 $wgSearchForwardUrl = null;
@@ -4950,7 +5017,7 @@ $wgUseAutomaticEditSummaries = true;
  * @cond file_level_code
  * Set $wgCommandLineMode if it's not set already, to avoid notices
  */
-if( !isset( $wgCommandLineMode ) ) {
+if ( !isset( $wgCommandLineMode ) ) {
        $wgCommandLineMode = false;
 }
 /** @endcond */
@@ -5007,8 +5074,8 @@ $wgUpgradeKey = false;
  * @since 1.20
  */
 $wgGitRepositoryViewers = array(
-    'https://gerrit.wikimedia.org/r/p/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
-    'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
+       'https://gerrit.wikimedia.org/r/p/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
+       'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
 );
 
 /** @} */ # End of maintenance }
@@ -5124,7 +5191,7 @@ $wgOverrideSiteFeed = array();
  * $wgOut->isSyndicated() is true.
  */
 $wgFeedClasses = array(
-       'rss'  => 'RSSFeed',
+       'rss' => 'RSSFeed',
        'atom' => 'AtomFeed',
 );
 
@@ -5281,8 +5348,8 @@ $wgExportAllowHistory = true;
 $wgExportMaxHistory = 0;
 
 /**
-* Return distinct author list (when not returning full history)
-*/
+ * Return distinct author list (when not returning full history)
+ */
 $wgExportAllowListContributors = false;
 
 /**
@@ -5299,13 +5366,13 @@ $wgExportAllowListContributors = false;
 $wgExportMaxLinkDepth = 0;
 
 /**
-* Whether to allow the "export all pages in namespace" option
-*/
+ * Whether to allow the "export all pages in namespace" option
+ */
 $wgExportFromNamespaces = false;
 
 /**
-* Whether to allow exporting the entire wiki into a single file
-*/
+ * Whether to allow exporting the entire wiki into a single file
+ */
 $wgExportAllowAll = false;
 
 /** @} */ # end of import/export }
@@ -5440,19 +5507,18 @@ $wgHooks = array();
  * can add to this to provide custom jobs
  */
 $wgJobClasses = array(
-       'refreshLinks'      => 'RefreshLinksJob',
-       'refreshLinks2'     => 'RefreshLinksJob2',
-       'htmlCacheUpdate'   => 'HTMLCacheUpdateJob',
+       'refreshLinks' => 'RefreshLinksJob',
+       'refreshLinks2' => 'RefreshLinksJob2',
+       'htmlCacheUpdate' => 'HTMLCacheUpdateJob',
        'html_cache_update' => 'HTMLCacheUpdateJob', // backwards-compatible
-       'sendMail'          => 'EmaillingJob',
-       'enotifNotify'      => 'EnotifNotifyJob',
+       'sendMail' => 'EmaillingJob',
+       'enotifNotify' => 'EnotifNotifyJob',
        'fixDoubleRedirect' => 'DoubleRedirectJob',
-       'uploadFromUrl'     => 'UploadFromUrlJob',
-       'null'              => 'NullJob'
+       'uploadFromUrl' => 'UploadFromUrlJob',
+       'null' => 'NullJob'
 );
 
 /**
-
  * Jobs that must be explicitly requested, i.e. aren't run by job runners unless
  * special flags are set. The values here are keys of $wgJobClasses.
  *
@@ -5472,6 +5538,14 @@ $wgJobTypeConf = array(
        'default' => array( 'class' => 'JobQueueDB', 'order' => 'random' ),
 );
 
+/**
+ * Which aggregator to use for tracking which queues have jobs.
+ * These settings should be global to all wikis.
+ */
+$wgJobQueueAggregator = array(
+       'class' => 'JobQueueAggregatorMemc'
+);
+
 /**
  * Additional functions to be performed with updateSpecialPages.
  * Expensive Querypages are already updated.
@@ -5597,7 +5671,7 @@ $wgLogRestrictions = array(
  *
  * @par Example:
  * @code
- *   $wgFilterLogTypes => array(
+ *   $wgFilterLogTypes = array(
  *      'move' => true,
  *      'import' => false,
  *   );
@@ -5624,16 +5698,16 @@ $wgFilterLogTypes = array(
  * where TYPE is your log type, yoy don't need to use this array.
  */
 $wgLogNames = array(
-       ''        => 'all-logs-page',
-       'block'   => 'blocklogpage',
+       '' => 'all-logs-page',
+       'block' => 'blocklogpage',
        'protect' => 'protectlogpage',
-       'rights'  => 'rightslog',
-       'delete'  => 'dellogpage',
-       'upload'  => 'uploadlogpage',
-       'move'    => 'movelogpage',
-       'import'  => 'importlogpage',
-       'patrol'  => 'patrol-log-page',
-       'merge'   => 'mergelog',
+       'rights' => 'rightslog',
+       'delete' => 'dellogpage',
+       'upload' => 'uploadlogpage',
+       'move' => 'movelogpage',
+       'import' => 'importlogpage',
+       'patrol' => 'patrol-log-page',
+       'merge' => 'mergelog',
        'suppress' => 'suppressionlog',
 );
 
@@ -5647,16 +5721,16 @@ $wgLogNames = array(
  * where TYPE is your log type, yoy don't need to use this array.
  */
 $wgLogHeaders = array(
-       ''        => 'alllogstext',
-       'block'   => 'blocklogtext',
+       '' => 'alllogstext',
+       'block' => 'blocklogtext',
        'protect' => 'protectlogtext',
-       'rights'  => 'rightslogtext',
-       'delete'  => 'dellogpagetext',
-       'upload'  => 'uploadlogpagetext',
-       'move'    => 'movelogpagetext',
-       'import'  => 'importlogpagetext',
-       'patrol'  => 'patrol-log-header',
-       'merge'   => 'mergelogpagetext',
+       'rights' => 'rightslogtext',
+       'delete' => 'dellogpagetext',
+       'upload' => 'uploadlogpagetext',
+       'move' => 'movelogpagetext',
+       'import' => 'importlogpagetext',
+       'patrol' => 'patrol-log-header',
+       'merge' => 'mergelogpagetext',
        'suppress' => 'suppressionlogtext',
 );
 
@@ -5667,21 +5741,21 @@ $wgLogHeaders = array(
  * Extensions with custom log types may add to this array.
  */
 $wgLogActions = array(
-       'block/block'        => 'blocklogentry',
-       'block/unblock'      => 'unblocklogentry',
-       'block/reblock'      => 'reblock-logentry',
-       'protect/protect'    => 'protectedarticle',
-       'protect/modify'     => 'modifiedarticleprotection',
-       'protect/unprotect'  => 'unprotectedarticle',
-       'protect/move_prot'  => 'movedarticleprotection',
-       'upload/upload'      => 'uploadedimage',
-       'upload/overwrite'   => 'overwroteimage',
-       'upload/revert'      => 'uploadedimage',
-       'import/upload'      => 'import-logentry-upload',
-       'import/interwiki'   => 'import-logentry-interwiki',
-       'merge/merge'        => 'pagemerge-logentry',
-       'suppress/block'     => 'blocklogentry',
-       'suppress/reblock'   => 'reblock-logentry',
+       'block/block' => 'blocklogentry',
+       'block/unblock' => 'unblocklogentry',
+       'block/reblock' => 'reblock-logentry',
+       'protect/protect' => 'protectedarticle',
+       'protect/modify' => 'modifiedarticleprotection',
+       'protect/unprotect' => 'unprotectedarticle',
+       'protect/move_prot' => 'movedarticleprotection',
+       'upload/upload' => 'uploadedimage',
+       'upload/overwrite' => 'overwroteimage',
+       'upload/revert' => 'uploadedimage',
+       'import/upload' => 'import-logentry-upload',
+       'import/interwiki' => 'import-logentry-interwiki',
+       'merge/merge' => 'pagemerge-logentry',
+       'suppress/block' => 'blocklogentry',
+       'suppress/reblock' => 'reblock-logentry',
 );
 
 /**
@@ -5691,17 +5765,17 @@ $wgLogActions = array(
  * @see LogFormatter
  */
 $wgLogActionsHandlers = array(
-       'move/move'          => 'MoveLogFormatter',
-       'move/move_redir'    => 'MoveLogFormatter',
-       'delete/delete'      => 'DeleteLogFormatter',
-       'delete/restore'     => 'DeleteLogFormatter',
-       'delete/revision'    => 'DeleteLogFormatter',
-       'delete/event'       => 'DeleteLogFormatter',
-       'suppress/revision'  => 'DeleteLogFormatter',
-       'suppress/event'     => 'DeleteLogFormatter',
-       'suppress/delete'    => 'DeleteLogFormatter',
-       'patrol/patrol'      => 'PatrolLogFormatter',
-       'rights/rights'      => 'RightsLogFormatter',
+       'move/move' => 'MoveLogFormatter',
+       'move/move_redir' => 'MoveLogFormatter',
+       'delete/delete' => 'DeleteLogFormatter',
+       'delete/restore' => 'DeleteLogFormatter',
+       'delete/revision' => 'DeleteLogFormatter',
+       'delete/event' => 'DeleteLogFormatter',
+       'suppress/revision' => 'DeleteLogFormatter',
+       'suppress/event' => 'DeleteLogFormatter',
+       'suppress/delete' => 'DeleteLogFormatter',
+       'patrol/patrol' => 'PatrolLogFormatter',
+       'rights/rights' => 'RightsLogFormatter',
        'rights/autopromote' => 'RightsLogFormatter',
 );
 
@@ -5733,107 +5807,107 @@ $wgDisableQueryPageUpdate = false;
  * at Special:SpecialPages
  */
 $wgSpecialPageGroups = array(
-       'DoubleRedirects'           => 'maintenance',
-       'BrokenRedirects'           => 'maintenance',
-       'Lonelypages'               => 'maintenance',
-       'Uncategorizedpages'        => 'maintenance',
-       'Uncategorizedcategories'   => 'maintenance',
-       'Uncategorizedimages'       => 'maintenance',
-       'Uncategorizedtemplates'    => 'maintenance',
-       'Unusedcategories'          => 'maintenance',
-       'Unusedimages'              => 'maintenance',
-       'Protectedpages'            => 'maintenance',
-       'Protectedtitles'           => 'maintenance',
-       'Unusedtemplates'           => 'maintenance',
-       'Withoutinterwiki'          => 'maintenance',
-       'Longpages'                 => 'maintenance',
-       'Shortpages'                => 'maintenance',
-       'Ancientpages'              => 'maintenance',
-       'Deadendpages'              => 'maintenance',
-       'Wantedpages'               => 'maintenance',
-       'Wantedcategories'          => 'maintenance',
-       'Wantedfiles'               => 'maintenance',
-       'Wantedtemplates'           => 'maintenance',
-       'Unwatchedpages'            => 'maintenance',
-       'Fewestrevisions'           => 'maintenance',
-
-       'Userlogin'                 => 'login',
-       'Userlogout'                => 'login',
-       'CreateAccount'             => 'login',
-
-       'Recentchanges'             => 'changes',
-       'Recentchangeslinked'       => 'changes',
-       'Watchlist'                 => 'changes',
-       'Newimages'                 => 'changes',
-       'Newpages'                  => 'changes',
-       'Log'                       => 'changes',
-       'Tags'                      => 'changes',
-
-       'Upload'                    => 'media',
-       'Listfiles'                 => 'media',
-       'MIMEsearch'                => 'media',
-       'FileDuplicateSearch'       => 'media',
-       'Filepath'                  => 'media',
-
-       'Listusers'                 => 'users',
-       'Activeusers'               => 'users',
-       'Listgrouprights'           => 'users',
-       'BlockList'                 => 'users',
-       'Contributions'             => 'users',
-       'Emailuser'                 => 'users',
-       'Listadmins'                => 'users',
-       'Listbots'                  => 'users',
-       'Userrights'                => 'users',
-       'Block'                     => 'users',
-       'Unblock'                   => 'users',
-       'Preferences'               => 'users',
-       'ChangeEmail'               => 'users',
-       'ChangePassword'            => 'users',
-       'DeletedContributions'      => 'users',
-       'PasswordReset'             => 'users',
-
-       'Mostlinked'                => 'highuse',
-       'Mostlinkedcategories'      => 'highuse',
-       'Mostlinkedtemplates'       => 'highuse',
-       'Mostcategories'            => 'highuse',
-       'Mostimages'                => 'highuse',
-       'Mostinterwikis'            => 'highuse',
-       'Mostrevisions'             => 'highuse',
-
-       'Allpages'                  => 'pages',
-       'Prefixindex'               => 'pages',
-       'Listredirects'             => 'pages',
-       'Categories'                => 'pages',
-       'Disambiguations'           => 'pages',
-
-       'Randompage'                => 'redirects',
-       'Randomredirect'            => 'redirects',
-       'Mypage'                    => 'redirects',
-       'Mytalk'                    => 'redirects',
-       'Mycontributions'           => 'redirects',
-       'Search'                    => 'redirects',
-       'LinkSearch'                => 'redirects',
-
-       'ComparePages'              => 'pagetools',
-       'Movepage'                  => 'pagetools',
-       'MergeHistory'              => 'pagetools',
-       'Revisiondelete'            => 'pagetools',
-       'Undelete'                  => 'pagetools',
-       'Export'                    => 'pagetools',
-       'Import'                    => 'pagetools',
-       'Whatlinkshere'             => 'pagetools',
-
-       'Statistics'                => 'wiki',
-       'Version'                   => 'wiki',
-       'Lockdb'                    => 'wiki',
-       'Unlockdb'                  => 'wiki',
-       'Allmessages'               => 'wiki',
-       'Popularpages'              => 'wiki',
-
-       'Specialpages'              => 'other',
-       'Blockme'                   => 'other',
-       'Booksources'               => 'other',
-       'JavaScriptTest'            => 'other',
+       'DoubleRedirects' => 'maintenance',
+       'BrokenRedirects' => 'maintenance',
+       'Lonelypages' => 'maintenance',
+       'Uncategorizedpages' => 'maintenance',
+       'Uncategorizedcategories' => 'maintenance',
+       'Uncategorizedimages' => 'maintenance',
+       'Uncategorizedtemplates' => 'maintenance',
+       'Unusedcategories' => 'maintenance',
+       'Unusedimages' => 'maintenance',
+       'Protectedpages' => 'maintenance',
+       'Protectedtitles' => 'maintenance',
+       'Unusedtemplates' => 'maintenance',
+       'Withoutinterwiki' => 'maintenance',
+       'Longpages' => 'maintenance',
+       'Shortpages' => 'maintenance',
+       'Ancientpages' => 'maintenance',
+       'Deadendpages' => 'maintenance',
+       'Wantedpages' => 'maintenance',
+       'Wantedcategories' => 'maintenance',
+       'Wantedfiles' => 'maintenance',
+       'Wantedtemplates' => 'maintenance',
+       'Unwatchedpages' => 'maintenance',
+       'Fewestrevisions' => 'maintenance',
+
+       'Userlogin' => 'login',
+       'Userlogout' => 'login',
+       'CreateAccount' => 'login',
+
+       'Recentchanges' => 'changes',
+       'Recentchangeslinked' => 'changes',
+       'Watchlist' => 'changes',
+       'Newimages' => 'changes',
+       'Newpages' => 'changes',
+       'Log' => 'changes',
+       'Tags' => 'changes',
+
+       'Upload' => 'media',
+       'Listfiles' => 'media',
+       'MIMEsearch' => 'media',
+       'FileDuplicateSearch' => 'media',
+       'Filepath' => 'media',
+
+       'Listusers' => 'users',
+       'Activeusers' => 'users',
+       'Listgrouprights' => 'users',
+       'BlockList' => 'users',
+       'Contributions' => 'users',
+       'Emailuser' => 'users',
+       'Listadmins' => 'users',
+       'Listbots' => 'users',
+       'Userrights' => 'users',
+       'Block' => 'users',
+       'Unblock' => 'users',
+       'Preferences' => 'users',
+       'ChangeEmail' => 'users',
+       'ChangePassword' => 'users',
+       'DeletedContributions' => 'users',
+       'PasswordReset' => 'users',
+
+       'Mostlinked' => 'highuse',
+       'Mostlinkedcategories' => 'highuse',
+       'Mostlinkedtemplates' => 'highuse',
+       'Mostcategories' => 'highuse',
+       'Mostimages' => 'highuse',
+       'Mostinterwikis' => 'highuse',
+       'Mostrevisions' => 'highuse',
+
+       'Allpages' => 'pages',
+       'Prefixindex' => 'pages',
+       'Listredirects' => 'pages',
+       'Categories' => 'pages',
+       'Disambiguations' => 'pages',
+
+       'Randompage' => 'redirects',
+       'Randomredirect' => 'redirects',
+       'Mypage' => 'redirects',
+       'Mytalk' => 'redirects',
+       'Mycontributions' => 'redirects',
+       'Search' => 'redirects',
+       'LinkSearch' => 'redirects',
+
+       'ComparePages' => 'pagetools',
+       'Movepage' => 'pagetools',
+       'MergeHistory' => 'pagetools',
+       'Revisiondelete' => 'pagetools',
+       'Undelete' => 'pagetools',
+       'Export' => 'pagetools',
+       'Import' => 'pagetools',
+       'Whatlinkshere' => 'pagetools',
+
+       'Statistics' => 'wiki',
+       'Version' => 'wiki',
+       'Lockdb' => 'wiki',
+       'Unlockdb' => 'wiki',
+       'Allmessages' => 'wiki',
+       'Popularpages' => 'wiki',
+
+       'Specialpages' => 'other',
+       'Blockme' => 'other',
+       'Booksources' => 'other',
+       'JavaScriptTest' => 'other',
 );
 
 /** Whether or not to sort special pages in Special:Specialpages */
@@ -5870,24 +5944,24 @@ $wgMaxRedirectLinksRetrieved = 500;
  * Unsetting core actions will probably cause things to complain loudly.
  */
 $wgActions = array(
-       'credits'        => true,
-       'delete'         => true,
-       'edit'           => true,
-       'history'        => true,
-       'info'           => true,
-       'markpatrolled'  => true,
-       'protect'        => true,
-       'purge'          => true,
-       'raw'            => true,
-       'render'         => true,
-       'revert'         => true,
+       'credits' => true,
+       'delete' => true,
+       'edit' => true,
+       'history' => true,
+       'info' => true,
+       'markpatrolled' => true,
+       'protect' => true,
+       'purge' => true,
+       'raw' => true,
+       'render' => true,
+       'revert' => true,
        'revisiondelete' => true,
-       'rollback'       => true,
-       'submit'         => true,
-       'unprotect'      => true,
-       'unwatch'        => true,
-       'view'           => true,
-       'watch'          => true,
+       'rollback' => true,
+       'submit' => true,
+       'unprotect' => true,
+       'unwatch' => true,
+       'view' => true,
+       'watch' => true,
 );
 
 /**
@@ -5935,8 +6009,8 @@ $wgNamespaceRobotPolicies = array();
  * @par Example:
  * @code
  * $wgArticleRobotPolicies = array(
- *             'Main Page' => 'noindex,follow',
- *             'User:Bob' => 'index,follow',
+ *         'Main Page' => 'noindex,follow',
+ *         'User:Bob' => 'index,follow',
  * );
  * @endcode
  *
@@ -6018,6 +6092,11 @@ $wgAPIModules = array();
 $wgAPIMetaModules = array();
 $wgAPIPropModules = array();
 $wgAPIListModules = array();
+
+/**
+ * This variable is ignored. To add your module to the API, please add it to $wgAPI*Modules
+ * @deprecated since 1.21
+ */
 $wgAPIGeneratorModules = array();
 
 /**
@@ -6047,7 +6126,7 @@ $wgAPIRequestLog = false;
 /**
  * Set the timeout for the API help text cache. If set to 0, caching disabled
  */
-$wgAPICacheHelpTimeout = 60*60;
+$wgAPICacheHelpTimeout = 60 * 60;
 
 /**
  * Enable AJAX framework
@@ -6089,10 +6168,10 @@ $wgAjaxLicensePreview = true;
  * @par Example:
  * @code
  * $wgCrossSiteAJAXdomains = array(
- *     'www.mediawiki.org',
- *     '*.wikipedia.org',
- *     '*.wikimedia.org',
- *     '*.wiktionary.org',
+ *     'www.mediawiki.org',
+ *     '*.wikipedia.org',
+ *     '*.wikimedia.org',
+ *     '*.wiktionary.org',
  * );
  * @endcode
  */
@@ -6135,6 +6214,31 @@ $wgMaxShellTime = 180;
  */
 $wgMaxShellWallClockTime = 180;
 
+/**
+ * Under Linux: a cgroup directory used to constrain memory usage of shell
+ * commands. The directory must be writable by the user which runs MediaWiki.
+ *
+ * If specified, this is used instead of ulimit, which is inaccurate, and
+ * causes malloc() to return NULL, which exposes bugs in C applications, making
+ * them segfault or deadlock.
+ *
+ * A wrapper script will create a cgroup for each shell command that runs, as
+ * a subgroup of the specified cgroup. If the memory limit is exceeded, the
+ * kernel will send a SIGKILL signal to a process in the subgroup.
+ *
+ * @par Example:
+ * @code
+ *    mkdir -p /sys/fs/cgroup/memory/mediawiki
+ *    mkdir -m 0777 /sys/fs/cgroup/memory/mediawiki/job
+ *    echo '$wgShellCgroup = "/sys/fs/cgroup/memory/mediawiki/job";' >> LocalSettings.php
+ * @endcode
+ *
+ * The reliability of cgroup cleanup can be improved by installing a
+ * notify_on_release script in the root cgroup, see e.g.
+ * https://gerrit.wikimedia.org/r/#/c/40784
+ */
+$wgShellCgroup = false;
+
 /**
  * Executable path of the PHP cli binary (php/php5). Should be set up on install.
  */
@@ -6385,9 +6489,9 @@ $wgContentHandlerUseDB = false;
  * @since 1.21
  */
 $wgTextModelsToParse = array(
-       CONTENT_MODEL_WIKITEXT,    // Just for completeness, wikitext will always be parsed.
-       CONTENT_MODEL_JAVASCRIPT,  // Make categories etc work, people put them into comments.
-       CONTENT_MODEL_CSS,         // Make categories etc work, people put them into comments.
+       CONTENT_MODEL_WIKITEXT, // Just for completeness, wikitext will always be parsed.
+       CONTENT_MODEL_JAVASCRIPT, // Make categories etc work, people put them into comments.
+       CONTENT_MODEL_CSS, // Make categories etc work, people put them into comments.
 );
 
 /**
index 882f318..46a3773 100644 (file)
@@ -54,12 +54,12 @@ define( 'DBO_COMPRESS', 512 );
  */
 define( 'DB_SLAVE', -1 );     # Read from the slave (or only server)
 define( 'DB_MASTER', -2 );    # Write to master (or only server)
-define( 'DB_LAST', -3 );     # Whatever database was used last
 /**@}*/
 
 # Obsolete aliases
 define( 'DB_READ', -1 );
 define( 'DB_WRITE', -2 );
+define( 'DB_LAST', -3 ); # deprecated since 2008, usage throws exception
 
 
 /**@{
@@ -227,7 +227,7 @@ define( 'MW_SUPPORTS_RESOURCE_MODULES', 1 );
 define( 'OT_HTML', 1 );
 define( 'OT_WIKI', 2 );
 define( 'OT_PREPROCESS', 3 );
-define( 'OT_MSG' , 3 );  // b/c alias for OT_PREPROCESS
+define( 'OT_MSG', 3 );  // b/c alias for OT_PREPROCESS
 define( 'OT_PLAIN', 4 );
 /**@}*/
 
index 4d7b968..d48bd0b 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 class DeprecatedGlobal extends StubObject {
-        // The m's are to stay consistent with parent class.
+       // The m's are to stay consistent with parent class.
        protected $mRealValue, $mVersion;
 
        function __construct( $name, $realValue, $version = false ) {
index ce8077d..5434dab 100644 (file)
@@ -546,8 +546,8 @@ class EditPage {
                        // Standard preference behaviour
                        return true;
                } elseif ( !$this->mTitle->exists() &&
-                 isset( $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] ) &&
-                 $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
+                       isset( $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] ) &&
+                       $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
                {
                        // Categories are special
                        return true;
@@ -624,11 +624,8 @@ class EditPage {
                                wfProfileOut( get_class( $this ) . "::importContentFormData" );
                        }
 
-                       # Trim spaces on user supplied text
-                       $summary = trim( $request->getText( 'wpSummary' ) );
-
                        # Truncate for whole multibyte characters
-                       $this->summary = $wgContLang->truncate( $summary, 255 );
+                       $this->summary = $wgContLang->truncate( $request->getText( 'wpSummary' ), 255 );
 
                        # If the summary consists of a heading, e.g. '==Foobar==', extract the title from the
                        # header syntax, e.g. 'Foobar'. This is mainly an issue when we are using wpSummary for
@@ -1162,7 +1159,7 @@ class EditPage {
                                return false;
 
                        case self::AS_PARSE_ERROR:
-                               $wgOut->addWikiText( '<div class="error">' . $status->getWikiText() . '</div>');
+                               $wgOut->addWikiText( '<div class="error">' . $status->getWikiText() . '</div>' );
                                return true;
 
                        case self::AS_SUCCESS_NEW_ARTICLE:
@@ -1508,7 +1505,7 @@ class EditPage {
                                                $this->isConflict = false;
                                                wfDebug( __METHOD__ . ": conflict suppressed; new section\n" );
                                        }
-                               } elseif ( $this->section == '' && Revision::userWasLastToEdit( DB_MASTER,  $this->mTitle->getArticleID(),
+                               } elseif ( $this->section == '' && Revision::userWasLastToEdit( DB_MASTER, $this->mTitle->getArticleID(),
                                                        $wgUser->getId(), $this->edittime ) ) {
                                        # Suppress edit conflict with self, except for section edits where merging is required.
                                        wfDebug( __METHOD__ . ": Suppressing edit conflict, same user.\n" );
@@ -1715,7 +1712,7 @@ class EditPage {
         * @return bool
         * @deprecated since 1.21, use mergeChangesIntoContent() instead
         */
-       function mergeChangesInto( &$editText ){
+       function mergeChangesInto( &$editText ) {
                ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $editContent = $this->toEditContent( $editText );
@@ -1740,7 +1737,7 @@ class EditPage {
         *
         * @return bool
         */
-       private function mergeChangesIntoContent( &$editContent ){
+       private function mergeChangesIntoContent( &$editContent ) {
                wfProfileIn( __METHOD__ );
 
                $db = wfGetDB( DB_MASTER );
@@ -2197,7 +2194,7 @@ class EditPage {
                        } catch ( MWContentSerializationException $ex ) {
                                // this can't really happen, but be nice if it does.
                                $msg = wfMessage( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
-                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>');
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
 
@@ -2453,6 +2450,8 @@ class EditPage {
         * @return String
         */
        protected function getSummaryPreview( $isSubjectPreview, $summary = "" ) {
+               // avoid spaces in preview, gets always trimmed on save
+               $summary = trim( $summary );
                if ( !$summary || ( !$this->preview && !$this->diff ) ) {
                        return "";
                }
@@ -2616,7 +2615,7 @@ HTML
                                $this->showDiff();
                        } catch ( MWContentSerializationException $ex ) {
                                $msg = wfMessage( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
-                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>');
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
        }
@@ -2888,21 +2887,24 @@ HTML
                $dbr = wfGetDB( DB_SLAVE );
                $data = $dbr->selectRow(
                        array( 'logging', 'user' ),
-                       array( 'log_type',
-                                  'log_action',
-                                  'log_timestamp',
-                                  'log_user',
-                                  'log_namespace',
-                                  'log_title',
-                                  'log_comment',
-                                  'log_params',
-                                  'log_deleted',
-                                  'user_name' ),
-                       array( 'log_namespace' => $this->mTitle->getNamespace(),
-                                  'log_title' => $this->mTitle->getDBkey(),
-                                  'log_type' => 'delete',
-                                  'log_action' => 'delete',
-                                  'user_id=log_user' ),
+                       array(
+                               'log_type',
+                               'log_action',
+                               'log_timestamp',
+                               'log_user',
+                               'log_namespace',
+                               'log_title',
+                               'log_comment',
+                               'log_params',
+                               'log_deleted',
+                               'user_name'
+                       ), array(
+                               'log_namespace' => $this->mTitle->getNamespace(),
+                               'log_title' => $this->mTitle->getDBkey(),
+                               'log_type' => 'delete',
+                               'log_action' => 'delete',
+                               'user_id=log_user'
+                       ),
                        __METHOD__,
                        array( 'LIMIT' => 1, 'ORDER BY' => 'log_timestamp DESC' )
                );
@@ -2957,13 +2959,13 @@ HTML
 
                        if ( $this->mTriedSave && !$this->mTokenOk ) {
                                if ( $this->mTokenOkExceptSuffix ) {
-                                       $note = wfMessage( 'token_suffix_mismatch' )->plain() ;
+                                       $note = wfMessage( 'token_suffix_mismatch' )->plain();
 
                                } else {
-                                       $note = wfMessage( 'session_fail_preview' )->plain() ;
+                                       $note = wfMessage( 'session_fail_preview' )->plain();
                                }
                        } elseif ( $this->incompleteForm ) {
-                               $note = wfMessage( 'edit_form_incomplete' )->plain() ;
+                               $note = wfMessage( 'edit_form_incomplete' )->plain();
                        } else {
                                $note = wfMessage( 'previewnote' )->plain() .
                                        ' [[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' . wfMessage( 'continue-editing' )->text() . ']]';
@@ -2972,7 +2974,7 @@ HTML
                        $parserOptions = $this->mArticle->makeParserOptions( $this->mArticle->getContext() );
                        $parserOptions->setEditSection( false );
                        $parserOptions->setIsPreview( true );
-                       $parserOptions->setIsSectionPreview( !is_null($this->section) && $this->section !== '' );
+                       $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' );
 
                        # don't parse non-wikitext pages, show message about preview
                        if ( $this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage() ) {
@@ -2995,7 +2997,7 @@ HTML
                                # Used messages to make sure grep find them:
                                # Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview
                                if( $level && $format ) {
-                                       $note = "<div id='mw-{$level}{$format}preview'>" . wfMessage( "{$level}{$format}preview" )->text()  . "</div>";
+                                       $note = "<div id='mw-{$level}{$format}preview'>" . wfMessage( "{$level}{$format}preview" )->text() . "</div>";
                                }
                        }
 
@@ -3031,7 +3033,7 @@ HTML
                                }
                        }
                } catch ( MWContentSerializationException $ex ) {
-                       $m = wfMessage('content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
+                       $m = wfMessage( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
                        $note .= "\n\n" . $m->parse();
                        $previewHTML = '';
                }
@@ -3454,7 +3456,7 @@ HTML
                global $wgOut, $wgLang;
                $this->textbox2 = $this->textbox1;
 
-               if( is_array( $match ) ){
+               if( is_array( $match ) ) {
                        $match = $wgLang->listToText( $match );
                }
                $wgOut->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
index f09e8f8..81d1a9b 100644 (file)
@@ -262,7 +262,7 @@ class MWException extends Exception {
                if ( defined( 'MW_API' ) ) {
                        // Unhandled API exception, we can't be sure that format printer is alive
                        header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $this ) );
-                       wfHttpError(500, 'Internal Server Error', $this->getText() );
+                       wfHttpError( 500, 'Internal Server Error', $this->getText() );
                } elseif ( self::isCommandLine() ) {
                        MWExceptionHandler::printError( $this->getText() );
                } else {
@@ -329,7 +329,7 @@ class ErrorPageError extends MWException {
                $this->msg = $msg;
                $this->params = $params;
 
-               if( $msg instanceof Message ){
+               if( $msg instanceof Message ) {
                        parent::__construct( $msg );
                } else {
                        parent::__construct( wfMessage( $msg )->text() );
@@ -423,7 +423,7 @@ class PermissionsError extends ErrorPageError {
  * @ingroup Exception
  */
 class ReadOnlyError extends ErrorPageError {
-       public function __construct(){
+       public function __construct() {
                parent::__construct(
                        'readonly',
                        'readonlytext',
@@ -439,14 +439,14 @@ class ReadOnlyError extends ErrorPageError {
  * @ingroup Exception
  */
 class ThrottledError extends ErrorPageError {
-       public function __construct(){
+       public function __construct() {
                parent::__construct(
                        'actionthrottled',
                        'actionthrottledtext'
                );
        }
 
-       public function report(){
+       public function report() {
                global $wgOut;
                $wgOut->setStatusCode( 503 );
                parent::report();
@@ -460,7 +460,7 @@ class ThrottledError extends ErrorPageError {
  * @ingroup Exception
  */
 class UserBlockedError extends ErrorPageError {
-       public function __construct( Block $block ){
+       public function __construct( Block $block ) {
                global $wgLang, $wgRequest;
 
                $blocker = $block->getBlocker();
@@ -536,7 +536,7 @@ class UserNotLoggedIn extends ErrorPageError {
         */
        public function __construct(
                $reasonMsg = 'exception-nologin-text',
-               $titleMsg  = 'exception-nologin',
+               $titleMsg = 'exception-nologin',
                $params = null
        ) {
                parent::__construct( $titleMsg, $reasonMsg, $params );
@@ -560,21 +560,45 @@ class HttpError extends MWException {
         * @param $content String|Message: content of the message
         * @param $header String|Message: content of the header (\<title\> and \<h1\>)
         */
-       public function __construct( $httpCode, $content, $header = null ){
+       public function __construct( $httpCode, $content, $header = null ) {
                parent::__construct( $content );
                $this->httpCode = (int)$httpCode;
                $this->header = $header;
                $this->content = $content;
        }
 
+       /**
+        * Returns the HTTP status code supplied to the constructor.
+        *
+        * @return int
+        */
+       public function getStatusCode() {
+               return $this->httpCode;
+       }
+
+       /**
+        * Report the HTTP error.
+        * Sends the appropriate HTTP status code and outputs an
+        * HTML page with an error message.
+        */
        public function report() {
                $httpMessage = HttpStatus::getMessage( $this->httpCode );
 
-               header( "Status: {$this->httpCode} {$httpMessage}" );
+               header( "Status: {$this->httpCode} {$httpMessage}", true, $this->httpCode );
                header( 'Content-type: text/html; charset=utf-8' );
 
+               print $this->getHTML();
+       }
+
+       /**
+        * Returns HTML for reporting the HTTP error.
+        * This will be a minimal but complete HTML document.
+        *
+        * @return string HTML
+        */
+       public function getHTML() {
                if ( $this->header === null ) {
-                       $header = $httpMessage;
+                       $header = HttpStatus::getMessage( $this->httpCode );
                } elseif ( $this->header instanceof Message ) {
                        $header = $this->header->escaped();
                } else {
@@ -587,7 +611,7 @@ class HttpError extends MWException {
                        $content = htmlspecialchars( $this->content );
                }
 
-               print "<!DOCTYPE html>\n".
+               return "<!DOCTYPE html>\n".
                        "<html><head><title>$header</title></head>\n" .
                        "<body><h1>$header</h1><p>$content</p></body></html>\n";
        }
index 16c297e..9248575 100644 (file)
@@ -31,8 +31,8 @@
  * @ingroup SpecialPage Dump
  */
 class WikiExporter {
-       var $list_authors = false ; # Return distinct author list (when not returning full history)
-       var $author_list = "" ;
+       var $list_authors = false; # Return distinct author list (when not returning full history)
+       var $author_list = "";
 
        var $dumpUploads = false;
        var $dumpUploadFileContents = false;
@@ -87,10 +87,10 @@ class WikiExporter {
                        $buffer = WikiExporter::BUFFER, $text = WikiExporter::TEXT ) {
                $this->db = $db;
                $this->history = $history;
-               $this->buffer  = $buffer;
-               $this->writer  = new XmlDumpWriter();
-               $this->sink    = new DumpOutput();
-               $this->text    = $text;
+               $this->buffer = $buffer;
+               $this->writer = new XmlDumpWriter();
+               $this->sink = new DumpOutput();
+               $this->text = $text;
        }
 
        /**
@@ -226,7 +226,7 @@ class WikiExporter {
                foreach ( $res as $row ) {
                        $this->author_list .= "<contributor>" .
                                "<username>" .
-                               htmlentities( $row->rev_user_text )  .
+                               htmlentities( $row->rev_user_text ) .
                                "</username>" .
                                "<id>" .
                                $row->rev_user .
@@ -330,7 +330,7 @@ class WikiExporter {
                                $join['revision'] = array( 'INNER JOIN', 'page_id=rev_page' );
                        } elseif ( $this->history & WikiExporter::CURRENT ) {
                                # Latest revision dumps...
-                               if ( $this->list_authors && $cond != '' )  { // List authors, if so desired
+                               if ( $this->list_authors && $cond != '' ) { // List authors, if so desired
                                        $this->do_list_authors( $cond );
                                }
                                $join['revision'] = array( 'INNER JOIN', 'page_id=rev_page AND page_latest=rev_id' );
@@ -634,7 +634,7 @@ class XmlDumpWriter {
        function writeRevision( $row ) {
                wfProfileIn( __METHOD__ );
 
-               $out  = "    <revision>\n";
+               $out = "    <revision>\n";
                $out .= "      " . Xml::element( 'id', null, strval( $row->rev_id ) ) . "\n";
                if( isset( $row->rev_parent_id ) && $row->rev_parent_id ) {
                        $out .= "      " . Xml::element( 'parentid', null, strval( $row->rev_parent_id ) ) . "\n";
@@ -674,12 +674,12 @@ class XmlDumpWriter {
                }
 
                if ( isset( $row->rev_sha1 ) && $row->rev_sha1 && !( $row->rev_deleted & Revision::DELETED_TEXT ) ) {
-                       $out .= "      " . Xml::element('sha1', null, strval( $row->rev_sha1 ) ) . "\n";
+                       $out .= "      " . Xml::element( 'sha1', null, strval( $row->rev_sha1 ) ) . "\n";
                } else {
                        $out .= "      <sha1/>\n";
                }
 
-               if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model )  ) {
+               if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model ) ) {
                        $content_model = strval( $row->rev_content_model );
                } else {
                        // probably using $wgContentHandlerUseDB = false;
@@ -688,7 +688,7 @@ class XmlDumpWriter {
                        $content_model = ContentHandler::getDefaultModelFor( $title );
                }
 
-               $out .= "      " . Xml::element('model', null, strval( $content_model ) ) . "\n";
+               $out .= "      " . Xml::element( 'model', null, strval( $content_model ) ) . "\n";
 
                if ( isset( $row->rev_content_format ) && !is_null( $row->rev_content_format ) ) {
                        $content_format = strval( $row->rev_content_format );
@@ -699,7 +699,7 @@ class XmlDumpWriter {
                        $content_format = $content_handler->getDefaultFormat();
                }
 
-               $out .= "      " . Xml::element('format', null, strval( $content_format ) ) . "\n";
+               $out .= "      " . Xml::element( 'format', null, strval( $content_format ) ) . "\n";
 
                wfRunHooks( 'XmlDumpWriterWriteRevision', array( &$this, &$out, $row, $text ) );
 
@@ -720,7 +720,7 @@ class XmlDumpWriter {
        function writeLogItem( $row ) {
                wfProfileIn( __METHOD__ );
 
-               $out  = "  <logitem>\n";
+               $out = "  <logitem>\n";
                $out .= "    " . Xml::element( 'id', null, strval( $row->log_id ) ) . "\n";
 
                $out .= $this->writeTimestamp( $row->log_timestamp, "    " );
@@ -940,7 +940,6 @@ class DumpOutput {
         * @param $newname mixed File name. May be a string or an array with one element
         */
        function closeRenameAndReopen( $newname ) {
-               return;
        }
 
        /**
@@ -951,7 +950,6 @@ class DumpOutput {
         * @param $open bool If true, a new file with the old filename will be opened again for writing (default: false)
         */
        function closeAndRename( $newname, $open = false ) {
-               return;
        }
 
        /**
@@ -960,7 +958,7 @@ class DumpOutput {
         * @return null
         */
        function getFilenames() {
-               return NULL;
+               return null;
        }
 }
 
@@ -1009,7 +1007,7 @@ class DumpFileOutput extends DumpOutput {
         * @throws MWException
         */
        function renameOrException( $newname ) {
-                       if (rename( $this->filename, $newname ) ) {
+                       if ( !rename( $this->filename, $newname ) ) {
                                throw new MWException( __METHOD__ . ": rename of file {$this->filename} to $newname failed\n" );
                        }
        }
@@ -1072,7 +1070,7 @@ class DumpPipeOutput extends DumpFileOutput {
         */
        function __construct( $command, $file = null ) {
                if ( !is_null( $file ) ) {
-                       $command .=  " > " . wfEscapeShellArg( $file );
+                       $command .= " > " . wfEscapeShellArg( $file );
                }
 
                $this->startCommand( $command );
@@ -1128,7 +1126,7 @@ class DumpPipeOutput extends DumpFileOutput {
                        $this->renameOrException( $newname );
                        if ( $open ) {
                                $command = $this->command;
-                               $command .=  " > " . wfEscapeShellArg( $this->filename );
+                               $command .= " > " . wfEscapeShellArg( $this->filename );
                                $this->startCommand( $command );
                        }
                }
@@ -1361,7 +1359,7 @@ class DumpNamespaceFilter extends DumpFilter {
                        "NS_PROJECT_TALK"   => NS_PROJECT_TALK,
                        "NS_FILE"           => NS_FILE,
                        "NS_FILE_TALK"      => NS_FILE_TALK,
-                       "NS_IMAGE"          => NS_IMAGE,  // NS_IMAGE is an alias for NS_FILE
+                       "NS_IMAGE"          => NS_IMAGE, // NS_IMAGE is an alias for NS_FILE
                        "NS_IMAGE_TALK"     => NS_IMAGE_TALK,
                        "NS_MEDIAWIKI"      => NS_MEDIAWIKI,
                        "NS_MEDIAWIKI_TALK" => NS_MEDIAWIKI_TALK,
@@ -1529,7 +1527,7 @@ class DumpMultiWriter {
        function getFilenames() {
                $filenames = array();
                for ( $i = 0; $i < $this->count; $i++ ) {
-                       $filenames[] =  $this->sinks[$i]->getFilenames();
+                       $filenames[] = $this->sinks[$i]->getFilenames();
                }
                return $filenames;
        }
index 3468325..3f73376 100644 (file)
@@ -87,7 +87,7 @@ class ExternalEdit extends ContextSource {
                                                'URL' => $image->getCanonicalURL()
                                        )
                                );
-                       } else{
+                       } else {
                                $urls = array();
                        }
                } else {
index 23944a5..8cf9c84 100644 (file)
@@ -128,7 +128,7 @@ abstract class ExternalUser {
         * @param $name string
         * @return bool Success?
         */
-       protected abstract function initFromName( $name );
+       abstract protected function initFromName( $name );
 
        /**
         * Given an id, which was at some previous point in history returned by
@@ -138,7 +138,7 @@ abstract class ExternalUser {
         * @param $id string
         * @return bool Success?
         */
-       protected abstract function initFromId( $id );
+       abstract protected function initFromId( $id );
 
        /**
         * Try to magically initialize the user from cookies or similar information
@@ -280,12 +280,12 @@ abstract class ExternalUser {
         *
         * @param $id int user_id
         */
-       public final function linkToLocal( $id ) {
+       final public function linkToLocal( $id ) {
                $dbw = wfGetDB( DB_MASTER );
                $dbw->replace( 'external_user',
                        array( 'eu_local_id', 'eu_external_id' ),
                        array( 'eu_local_id' => $id,
-                                  'eu_external_id' => $this->getId() ),
+                               'eu_external_id' => $this->getId() ),
                        __METHOD__ );
        }
 
@@ -294,7 +294,7 @@ abstract class ExternalUser {
         * a local user.
         * @return Mixed User if the account is linked, Null otherwise.
         */
-       public final function getLocalUser(){
+       final public function getLocalUser() {
                $dbr = wfGetDB( DB_SLAVE );
                $row = $dbr->selectRow(
                        'external_user',
index 60f7600..efa213f 100644 (file)
@@ -114,9 +114,9 @@ class FakeTitle extends Title {
        function getParentCategories() { $this->error(); }
        function getParentCategoryTree( $children = array() ) { $this->error(); }
        function pageCond() { $this->error(); }
-       function getPreviousRevisionID( $revId, $flags=0 ) { $this->error(); }
-       function getNextRevisionID( $revId, $flags=0 ) { $this->error(); }
-       function getFirstRevision( $flags=0 ) { $this->error(); }
+       function getPreviousRevisionID( $revId, $flags = 0 ) { $this->error(); }
+       function getNextRevisionID( $revId, $flags = 0 ) { $this->error(); }
+       function getFirstRevision( $flags = 0 ) { $this->error(); }
        function isNewPage() { $this->error(); }
        function getEarliestRevTime( $flags = 0 ) { $this->error(); }
        function countRevisionsBetween( $old, $new ) { $this->error(); }
index f9dbf5b..8e000ae 100644 (file)
@@ -243,9 +243,9 @@ abstract class ChannelFeed extends FeedItem {
         */
        function contentType() {
                global $wgRequest;
-               $ctype = $wgRequest->getVal('ctype','application/xml');
-               $allowedctypes = array('application/xml','text/xml','application/rss+xml','application/atom+xml');
-               return (in_array($ctype, $allowedctypes) ? $ctype : 'application/xml');
+               $ctype = $wgRequest->getVal( 'ctype', 'application/xml' );
+               $allowedctypes = array( 'application/xml', 'text/xml', 'application/rss+xml', 'application/atom+xml' );
+               return (in_array( $ctype, $allowedctypes ) ? $ctype : 'application/xml');
        }
 
        /**
index 82c6e4a..67011d2 100644 (file)
@@ -39,7 +39,7 @@ class FeedUtils {
        public static function checkPurge( $timekey, $key ) {
                global $wgRequest, $wgUser, $messageMemc;
                $purge = $wgRequest->getVal( 'action' ) === 'purge';
-               if ( $purge && $wgUser->isAllowed('purge') ) {
+               if ( $purge && $wgUser->isAllowed( 'purge' ) ) {
                        $messageMemc->delete( $timekey );
                        $messageMemc->delete( $key );
                }
@@ -85,7 +85,7 @@ class FeedUtils {
                        $row->rc_last_oldid, $row->rc_this_oldid,
                        $timestamp,
                        ($row->rc_deleted & Revision::DELETED_COMMENT)
-                               ? wfMessage('rev-deleted-comment')->escaped()
+                               ? wfMessage( 'rev-deleted-comment' )->escaped()
                                : $row->rc_comment,
                        $actiontext
                );
@@ -102,7 +102,7 @@ class FeedUtils {
         * @param $actiontext String: text of the action; in case of log event
         * @return String
         */
-       public static function formatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext='' ) {
+       public static function formatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext = '' ) {
                global $wgFeedDiffCutoff, $wgLang;
                wfProfileIn( __METHOD__ );
 
@@ -222,7 +222,7 @@ class FeedUtils {
        protected static function getDiffLink( Title $title, $newid, $oldid = null ) {
                $queryParameters = ($oldid == null)
                        ? "diff={$newid}"
-                       : "diff={$newid}&oldid={$oldid}" ;
+                       : "diff={$newid}&oldid={$oldid}";
                $diffUrl = $title->getFullUrl( $queryParameters );
 
                $diffLink = Html::element( 'a', array( 'href' => $diffUrl ),
index e2fcd9c..48073f7 100644 (file)
@@ -80,13 +80,13 @@ class FileDeleteForm {
                $this->oldimage = $wgRequest->getText( 'oldimage', false );
                $token = $wgRequest->getText( 'wpEditToken' );
                # Flag to hide all contents of the archived revisions
-               $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed('suppressrevision');
+               $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed( 'suppressrevision' );
 
                if( $this->oldimage ) {
                        $this->oldfile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $this->title, $this->oldimage );
                }
 
-               if( !self::haveDeletableFile($this->file, $this->oldfile, $this->oldimage) ) {
+               if( !self::haveDeletableFile( $this->file, $this->oldfile, $this->oldimage ) ) {
                        $wgOut->addHTML( $this->prepareMessage( 'filedelete-nofile' ) );
                        $wgOut->addReturnTo( $this->title );
                        return;
@@ -344,7 +344,7 @@ class FileDeleteForm {
         *
         * @return bool
         */
-       public static function isValidOldSpec($oldimage) {
+       public static function isValidOldSpec( $oldimage ) {
                return strlen( $oldimage ) >= 16
                        && strpos( $oldimage, '/' ) === false
                        && strpos( $oldimage, '\\' ) === false;
@@ -360,7 +360,7 @@ class FileDeleteForm {
         * @param $oldimage File
         * @return bool
         */
-       public static function haveDeletableFile(&$file, &$oldfile, $oldimage) {
+       public static function haveDeletableFile( &$file, &$oldfile, $oldimage ) {
                return $oldimage
                        ? $oldfile && $oldfile->exists() && $oldfile->isLocal()
                        : $file && $file->exists() && $file->isLocal();
index 448bc03..89ad955 100644 (file)
@@ -53,7 +53,7 @@ class ForkController {
        const RESTART_ON_ERROR = 1;
 
        public function __construct( $numProcs, $flags = 0 ) {
-               if ( php_sapi_name() != 'cli' ) {
+               if ( PHP_SAPI != 'cli' ) {
                        throw new MWException( "ForkController cannot be used from the web." );
                }
                $this->procsToStart = $numProcs;
@@ -140,7 +140,7 @@ class ForkController {
                // Don't share DB, storage, or memcached connections
                wfGetLBFactory()->destroyInstance();
                FileBackendGroup::destroySingleton();
-               LockManagerGroup::destroySingleton();
+               LockManagerGroup::destroySingletons();
                ObjectCache::clear();
                $wgMemc = null;
        }
index c3c3073..a0a216e 100644 (file)
@@ -44,7 +44,15 @@ class GitInfo {
         * @param $dir string The root directory of the repo where the .git dir can be found
         */
        public function __construct( $dir ) {
-               $this->basedir = "{$dir}/.git/";
+               $this->basedir = "{$dir}/.git";
+               if ( is_readable( $this->basedir ) ) {
+                       $GITfile = file_get_contents( $this->basedir );
+                       if ( strlen( $GITfile ) > 8 && substr( $GITfile, 0, 8 ) === 'gitdir: ' ) {
+                               $path = rtrim( substr( $GITfile, 8 ), "\r\n" );
+                               $isAbsolute = $path[0] === '/' || substr( $path, 1, 1 ) === ':';
+                               $this->basedir = $isAbsolute ? $path : "{$dir}/{$path}";
+                       }
+               }
        }
 
        /**
@@ -102,7 +110,7 @@ class GitInfo {
                }
 
                // If not a SHA1 it may be a ref:
-               $REFfile = "{$this->basedir}{$HEAD}";
+               $REFfile = "{$this->basedir}/{$HEAD}";
                if ( !is_readable( $REFfile ) ) {
                        return false;
                }
index 2292e31..be862e7 100644 (file)
@@ -50,7 +50,7 @@ if ( !function_exists( 'mb_substr' ) ) {
         * @codeCoverageIgnore
         * @return string
         */
-       function mb_substr( $str, $start, $count='end' ) {
+       function mb_substr( $str, $start, $count = 'end' ) {
                return Fallback::mb_substr( $str, $start, $count );
        }
 
@@ -392,7 +392,7 @@ function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) {
 
        $cgi = '';
        foreach ( $array1 as $key => $value ) {
-               if ( !is_null($value) && $value !== false ) {
+               if ( !is_null( $value ) && $value !== false ) {
                        if ( $cgi != '' ) {
                                $cgi .= '&';
                        }
@@ -809,9 +809,14 @@ function wfParseUrl( $url ) {
        if ( !isset( $bits['host'] ) ) {
                $bits['host'] = '';
 
-               /* parse_url loses the third / for file:///c:/ urls (but not on variants) */
-               if ( substr( $bits['path'], 0, 1 ) !== '/' ) {
-                       $bits['path'] = '/' . $bits['path'];
+               // bug 45069
+               if ( isset( $bits['path'] ) ) {
+                       /* parse_url loses the third / for file:///c:/ urls (but not on variants) */
+                       if ( substr( $bits['path'], 0, 1 ) !== '/' ) {
+                               $bits['path'] = '/' . $bits['path'];
+                       }
+               } else {
+                       $bits['path'] = '';
                }
        }
 
@@ -2449,7 +2454,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
                $timestamp = new MWTimestamp( $ts );
                return $timestamp->getTimestamp( $outputtype );
        } catch( TimestampException $e ) {
-               wfDebug("wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n");
+               wfDebug( "wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" );
                return false;
        }
 }
@@ -2622,12 +2627,14 @@ function wfPercent( $nr, $acc = 2, $round = true ) {
 /**
  * Find out whether or not a mixed variable exists in a string
  *
+ * @deprecated Just use str(i)pos
  * @param $needle String
  * @param $str String
  * @param $insensitive Boolean
  * @return Boolean
  */
 function in_string( $needle, $str, $insensitive = false ) {
+       wfDeprecated( __METHOD__, '1.21' );
        $func = 'strpos';
        if( $insensitive ) $func = 'stripos';
 
@@ -2681,8 +2688,7 @@ function wfDl( $extension, $fileName = null ) {
        }
 
        $canDl = false;
-       $sapi = php_sapi_name();
-       if( $sapi == 'cli' || $sapi == 'cgi' || $sapi == 'embed' ) {
+       if( PHP_SAPI == 'cli' || PHP_SAPI == 'cgi' || PHP_SAPI == 'embed' ) {
                $canDl = ( function_exists( 'dl' ) && is_callable( 'dl' )
                && wfIniGetBool( 'enable_dl' ) && !wfIniGetBool( 'safe_mode' ) );
        }
@@ -2777,7 +2783,7 @@ function wfEscapeShellArg( ) {
  */
 function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array() ) {
        global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime,
-               $wgMaxShellWallClockTime;
+               $wgMaxShellWallClockTime, $wgShellCgroup;
 
        static $disabled;
        if ( is_null( $disabled ) ) {
@@ -2824,7 +2830,7 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array
        $cmd = $envcmd . $cmd;
 
        if ( php_uname( 's' ) == 'Linux' ) {
-               $time = intval ( isset($limits['time']) ? $limits['time'] : $wgMaxShellTime );
+               $time = intval ( isset( $limits['time'] ) ? $limits['time'] : $wgMaxShellTime );
                if ( isset( $limits['walltime'] ) ) {
                        $wallTime = intval( $limits['walltime'] );
                } elseif ( isset( $limits['time'] ) ) {
@@ -2832,12 +2838,19 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array
                } else {
                        $wallTime = intval( $wgMaxShellWallClockTime );
                }
-               $mem = intval ( isset($limits['memory']) ? $limits['memory'] : $wgMaxShellMemory );
-               $filesize = intval ( isset($limits['filesize']) ? $limits['filesize'] : $wgMaxShellFileSize );
+               $mem = intval ( isset( $limits['memory'] ) ? $limits['memory'] : $wgMaxShellMemory );
+               $filesize = intval ( isset( $limits['filesize'] ) ? $limits['filesize'] : $wgMaxShellFileSize );
 
                if ( $time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) {
-                       $cmd = '/bin/bash ' . escapeshellarg( "$IP/bin/ulimit5.sh" ) .
-                               " $time $mem $filesize $wallTime " . escapeshellarg( $cmd );
+                       $cmd = '/bin/bash ' . escapeshellarg( "$IP/includes/limit.sh" ) . ' ' .
+                               escapeshellarg( $cmd ) . ' ' .
+                               escapeshellarg(
+                                       "MW_CPU_LIMIT=$time; " .
+                                       'MW_CGROUP=' . escapeshellarg( $wgShellCgroup ) . '; ' .
+                                       "MW_MEM_LIMIT=$mem; " .
+                                       "MW_FILE_SIZE_LIMIT=$filesize; " .
+                                       "MW_WALL_CLOCK_LIMIT=$wallTime"
+                               );
                }
        }
        wfDebug( "wfShellExec: $cmd\n" );
@@ -3198,6 +3211,7 @@ function wfDoUpdates( $commit = '' ) {
  * @return string|bool The output number as a string, or false on error
  */
 function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1, $lowercase = true, $engine = 'auto' ) {
+       $input = (string)$input;
        if(
                $sourceBase < 2 ||
                $sourceBase > 36 ||
index 952022f..86eb38d 100644 (file)
@@ -639,9 +639,9 @@ class HTMLForm extends ContextSource {
                        : 'application/x-www-form-urlencoded';
                # Attributes
                $attribs = array(
-                       'action'  => $this->mAction === false ? $this->getTitle()->getFullURL() : $this->mAction,
-                       'method'  => $this->mMethod,
-                       'class'   => 'visualClear',
+                       'action' => $this->mAction === false ? $this->getTitle()->getFullURL() : $this->mAction,
+                       'method' => $this->mMethod,
+                       'class' => 'visualClear',
                        'enctype' => $encType,
                );
                if ( !empty( $this->mId ) ) {
@@ -712,8 +712,8 @@ class HTMLForm extends ContextSource {
 
                foreach ( $this->mButtons as $button ) {
                        $attrs = array(
-                               'type'  => 'submit',
-                               'name'  => $button['name'],
+                               'type' => 'submit',
+                               'name' => $button['name'],
                                'value' => $button['value']
                        );
 
index 55c2ae5..5974173 100644 (file)
@@ -247,7 +247,7 @@ class HistoryBlobStub {
                                if ( !isset( $parts[1] ) || $parts[1] == '' ) {
                                        return false;
                                }
-                               $row->old_text = ExternalStore::fetchFromUrl($url);
+                               $row->old_text = ExternalStore::fetchFromUrl( $url );
 
                        }
                        if( !in_array( 'object', $flags ) ) {
@@ -395,7 +395,7 @@ class DiffHistoryBlob implements HistoryBlob {
         */
        function addItem( $text ) {
                if ( $this->mFrozen ) {
-                       throw new MWException( __METHOD__.": Cannot add more items after sleep/wakeup" );
+                       throw new MWException( __METHOD__ . ": Cannot add more items after sleep/wakeup" );
                }
 
                $this->mItems[] = $text;
@@ -430,7 +430,7 @@ class DiffHistoryBlob implements HistoryBlob {
         * @throws MWException
         */
        function compress() {
-               if ( !function_exists( 'xdiff_string_rabdiff' ) ){
+               if ( !function_exists( 'xdiff_string_rabdiff' ) ) {
                        throw new MWException( "Need xdiff 1.5+ support to write DiffHistoryBlob\n" );
                }
                if ( isset( $this->mDiffs ) ) {
@@ -535,11 +535,11 @@ class DiffHistoryBlob implements HistoryBlob {
                # Check the checksum if hash/mhash is available
                $ofp = $this->xdiffAdler32( $base );
                if ( $ofp !== false && $ofp !== substr( $diff, 0, 4 ) ) {
-                       wfDebug( __METHOD__. ": incorrect base checksum\n" );
+                       wfDebug( __METHOD__ . ": incorrect base checksum\n" );
                        return false;
                }
                if ( $header['csize'] != strlen( $base ) ) {
-                       wfDebug( __METHOD__. ": incorrect base length\n" );
+                       wfDebug( __METHOD__ . ": incorrect base length\n" );
                        return false;
                }
 
@@ -568,7 +568,7 @@ class DiffHistoryBlob implements HistoryBlob {
                                $out .= substr( $base, $x['off'], $x['csize'] );
                                break;
                        default:
-                               wfDebug( __METHOD__.": invalid op\n" );
+                               wfDebug( __METHOD__ . ": invalid op\n" );
                                return false;
                        }
                }
index 9e201a2..a29e5fe 100644 (file)
@@ -150,6 +150,7 @@ class Hooks {
                        return true;
                }
 
+               wfProfileIn( 'hook: ' . $event );
                $hooks = self::getHandlers( $event );
 
                foreach ( $hooks as $hook ) {
@@ -288,10 +289,12 @@ class Hooks {
                                        );
                                }
                        } elseif ( !$retval ) {
+                               wfProfileOut( 'hook: ' . $event );
                                return false;
                        }
                }
 
+               wfProfileOut( 'hook: ' . $event );
                return true;
        }
 
index 14456e4..60be863 100644 (file)
@@ -465,8 +465,7 @@ class Html {
                        $key = strtolower( $key );
 
                        // Here we're blacklisting some HTML5-only attributes...
-                       if ( !$wgHtml5 && in_array( $key, self::$HTMLFiveOnlyAttribs )
-                        ) {
+                       if ( !$wgHtml5 && in_array( $key, self::$HTMLFiveOnlyAttribs ) ) {
                                continue;
                        }
 
@@ -738,7 +737,7 @@ class Html {
                        }
                }
 
-               if (substr($value, 0, 1) == "\n") {
+               if ( substr( $value, 0, 1 ) == "\n" ) {
                        // Workaround for bug 12130: browsers eat the initial newline
                        // assuming that it's just for show, but they do keep the later
                        // newlines, which we may want to preserve during editing.
@@ -930,7 +929,7 @@ class Html {
                        $icon = $wgStylePath.'/common/images/'.$icon;
                }
 
-               $s  = Html::openElement( 'div', array( 'class' => "mw-infobox $class") );
+               $s = Html::openElement( 'div', array( 'class' => "mw-infobox $class" ) );
 
                $s .= Html::openElement( 'div', array( 'class' => 'mw-infobox-left' ) ).
                                Html::element( 'img',
index b1092df..6a348a6 100644 (file)
@@ -244,7 +244,7 @@ class MWHttpRequest {
                }
 
                $members = array( "postData", "proxy", "noProxy", "sslVerifyHost", "caInfo",
-                                 "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback" );
+                               "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback" );
 
                foreach ( $members as $o ) {
                        if ( isset( $options[$o] ) ) {
@@ -284,7 +284,7 @@ class MWHttpRequest {
                        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"' );
+                               ' Http::$httpEngine is set to "curl"' );
                }
 
                switch( Http::$httpEngine ) {
@@ -338,7 +338,7 @@ class MWHttpRequest {
                if ( Http::isLocalURL( $this->url ) || $this->noProxy ) {
                        $this->proxy = '';
                } elseif ( $wgHTTPProxy ) {
-                       $this->proxy = $wgHTTPProxy ;
+                       $this->proxy = $wgHTTPProxy;
                } elseif ( getenv( "http_proxy" ) ) {
                        $this->proxy = getenv( "http_proxy" );
                }
@@ -646,12 +646,12 @@ class MWHttpRequest {
                        $locations = $headers[ 'location' ];
                        $domain = '';
                        $foundRelativeURI = false;
-                       $countLocations = count($locations);
+                       $countLocations = count( $locations );
 
                        for ( $i = $countLocations - 1; $i >= 0; $i-- ) {
                                $url = parse_url( $locations[ $i ] );
 
-                               if ( isset($url[ 'host' ]) ) {
+                               if ( isset( $url['host'] ) ) {
                                        $domain = $url[ 'scheme' ] . '://' . $url[ 'host' ];
                                        break;  //found correct URI (with host)
                                } else {
@@ -830,7 +830,7 @@ class PhpHttpRequest extends MWHttpRequest {
                parent::execute();
 
                if ( is_array( $this->postData ) ) {
-                       $this->postData = wfArrayToCGI( $this->postData );
+                       $this->postData = wfArrayToCgi( $this->postData );
                }
 
                if ( $this->parsedUrl['scheme'] != 'http' &&
index 1b40f4b..5c50c22 100644 (file)
@@ -714,7 +714,9 @@ class IP {
         * @return String: valid dotted quad IPv4 address or null
         */
        public static function canonicalize( $addr ) {
-               $addr = preg_replace( '/\%.*/','', $addr ); // remove zone info (bug 35738)
+               // remove zone info (bug 35738)
+               $addr = preg_replace( '/\%.*/', '', $addr );
+
                if ( self::isValid( $addr ) ) {
                        return $addr;
                }
index 91c3190..037093a 100644 (file)
@@ -161,7 +161,7 @@ class ImageGallery {
         * @param $alt   String: Alt text for the image
         * @param $link  String: Override image link (optional)
         */
-       function add( $title, $html = '', $alt = '', $link = '') {
+       function add( $title, $html = '', $alt = '', $link = '' ) {
                if ( $title instanceof File ) {
                        // Old calling convention
                        $title = $title->getTitle();
@@ -354,7 +354,7 @@ class ImageGallery {
                                        array(),
                                        array( 'known', 'noclasses' )
                                ) . "<br />\n" :
-                               '' ;
+                               '';
 
                        # ATTENTION: The newline after <div class="gallerytext"> is needed to accommodate htmltidy which
                        # in version 4.8.6 generated crackpot html in its absence, see:
index c93f38c..0b814ec 100644 (file)
@@ -156,7 +156,7 @@ class ImagePage extends Article {
                        $pageLang = $this->getTitle()->getPageViewLanguage();
                        $out->addHTML( Xml::openElement( 'div', array( 'id' => 'mw-imagepage-content',
                                'lang' => $pageLang->getHtmlCode(), 'dir' => $pageLang->getDir(),
-                               'class' => 'mw-content-'.$pageLang->getDir() ) ) );
+                               'class' => 'mw-content-' . $pageLang->getDir() ) ) );
 
                        parent::view();
 
@@ -298,18 +298,7 @@ class ImagePage extends Article {
                $dirmark = $lang->getDirMarkEntity();
                $request = $this->getContext()->getRequest();
 
-               $sizeSel = intval( $user->getOption( 'imagesize' ) );
-               if ( !isset( $wgImageLimits[$sizeSel] ) ) {
-                       $sizeSel = User::getDefaultOption( 'imagesize' );
-
-                       // The user offset might still be incorrect, specially if
-                       // $wgImageLimits got changed (see bug #8858).
-                       if ( !isset( $wgImageLimits[$sizeSel] ) ) {
-                               // Default to the first offset in $wgImageLimits
-                               $sizeSel = 0;
-                       }
-               }
-               $max = $wgImageLimits[$sizeSel];
+               $max = $this->getImageLimitsFromOption( $user, 'imagesize' );
                $maxWidth = $max[0];
                $maxHeight = $max[1];
 
@@ -327,7 +316,8 @@ class ImagePage extends Article {
                        $height_orig = $this->displayImg->getHeight( $page );
                        $height = $height_orig;
 
-                       $longDesc = wfMessage( 'parentheses', $this->displayImg->getLongDesc() )->text();
+                       $filename = wfEscapeWikiText( $this->displayImg->getName() );
+                       $linktext = $filename;
 
                        wfRunHooks( 'ImageOpenShowImageInlineBefore', array( &$this, &$out ) );
 
@@ -351,16 +341,13 @@ class ImagePage extends Article {
                                                # Note that $height <= $maxHeight now, but might not be identical
                                                # because of rounding.
                                        }
-                                       $msgbig = wfMessage( 'show-big-image' )->escaped();
+                                       $linktext = wfMessage( 'show-big-image' )->escaped();
                                        if ( $this->displayImg->getRepo()->canTransformVia404() ) {
                                                $thumbSizes = $wgImageLimits;
                                        } else {
                                                # Creating thumb links triggers thumbnail generation.
                                                # Just generate the thumb for the current users prefs.
-                                               $thumbOption = $user->getOption( 'thumbsize' );
-                                               $thumbSizes = array( isset( $wgImageLimits[$thumbOption] )
-                                                       ? $wgImageLimits[$thumbOption]
-                                                       : $wgImageLimits[User::getDefaultOption( 'thumbsize' )] );
+                                               $thumbSizes = array( $this->getImageLimitsFromOption( $user, 'thumbsize' ) );
                                        }
                                        # Generate thumbnails or thumbnail links as needed...
                                        $otherSizes = array();
@@ -368,12 +355,19 @@ class ImagePage extends Article {
                                                if ( $size[0] < $width_orig && $size[1] < $height_orig
                                                        && $size[0] != $width && $size[1] != $height )
                                                {
-                                                       $otherSizes[] = $this->makeSizeLink( $params, $size[0], $size[1] );
+                                                       $sizeLink = $this->makeSizeLink( $params, $size[0], $size[1] );
+                                                       if ( $sizeLink ) {
+                                                               $otherSizes[] = $sizeLink;
+                                                       }
                                                }
                                        }
-                                       $msgsmall = wfMessage( 'show-big-image-preview' )->
-                                               rawParams( $this->makeSizeLink( $params, $width, $height ) )->
-                                               parse();
+                                       $msgsmall = '';
+                                       $sizeLinkBigImagePreview = $this->makeSizeLink( $params, $width, $height );
+                                       if ( $sizeLinkBigImagePreview ) {
+                                               $msgsmall .= wfMessage( 'show-big-image-preview' )->
+                                                       rawParams( $sizeLinkBigImagePreview )->
+                                                       parse();
+                                       }
                                        if ( count( $otherSizes ) ) {
                                                $msgsmall .= ' ' .
                                                Html::rawElement( 'span', array( 'class' => 'mw-filepage-other-resolutions' ),
@@ -381,7 +375,7 @@ class ImagePage extends Article {
                                                        params( count( $otherSizes ) )->parse()
                                                );
                                        }
-                               } elseif ( $width == 0 && $height == 0 ){
+                               } elseif ( $width == 0 && $height == 0 ) {
                                        # Some sort of audio file that doesn't have dimensions
                                        # Don't output a no hi res message for such a file
                                        $msgsmall = '';
@@ -397,7 +391,6 @@ class ImagePage extends Article {
                                $params['height'] = $height;
                                $thumbnail = $this->displayImg->transform( $params );
 
-                               $showLink = true;
                                $anchorclose = Html::rawElement( 'div', array( 'class' => 'mw-filepage-resolutioninfo' ), $msgsmall );
 
                                $isMulti = $this->displayImg->isMultipage() && $this->displayImg->pageCount() > 1;
@@ -471,48 +464,39 @@ class ImagePage extends Article {
                                                "<hr />$thumb1\n$thumb2<br style=\"clear: both\" /></div></td></tr></table>"
                                        );
                                }
-                       } else {
+                       } elseif ( $this->displayImg->isSafeFile() ) {
                                # if direct link is allowed but it's not a renderable image, show an icon.
-                               if ( $this->displayImg->isSafeFile() ) {
-                                       $icon = $this->displayImg->iconThumb();
-
-                                       $out->addHTML( '<div class="fullImageLink" id="file">' .
-                                               $icon->toHtml( array( 'file-link' => true ) ) .
-                                               "</div>\n" );
-                               }
+                               $icon = $this->displayImg->iconThumb();
 
-                               $showLink = true;
+                               $out->addHTML( '<div class="fullImageLink" id="file">' .
+                                       $icon->toHtml( array( 'file-link' => true ) ) .
+                                       "</div>\n" );
                        }
 
-                       if ( $showLink ) {
-                               $filename = wfEscapeWikiText( $this->displayImg->getName() );
-                               $linktext = $filename;
-                               if ( isset( $msgbig ) ) {
-                                       $linktext = wfEscapeWikiText( $msgbig );
-                               }
-                               $medialink = "[[Media:$filename|$linktext]]";
-
-                               if ( !$this->displayImg->isSafeFile() ) {
-                                       $warning = wfMessage( 'mediawarning' )->plain();
-                                       // dirmark is needed here to separate the file name, which
-                                       // most likely ends in Latin characters, from the description,
-                                       // which may begin with the file type. In RTL environment
-                                       // this will get messy.
-                                       // The dirmark, however, must not be immediately adjacent
-                                       // to the filename, because it can get copied with it.
-                                       // See bug 25277.
-                                       $out->addWikiText( <<<EOT
+                       $longDesc = wfMessage( 'parentheses', $this->displayImg->getLongDesc() )->text();
+
+                       $medialink = "[[Media:$filename|$linktext]]";
+
+                       if ( !$this->displayImg->isSafeFile() ) {
+                               $warning = wfMessage( 'mediawarning' )->plain();
+                               // dirmark is needed here to separate the file name, which
+                               // most likely ends in Latin characters, from the description,
+                               // which may begin with the file type. In RTL environment
+                               // this will get messy.
+                               // The dirmark, however, must not be immediately adjacent
+                               // to the filename, because it can get copied with it.
+                               // See bug 25277.
+                               $out->addWikiText( <<<EOT
 <div class="fullMedia"><span class="dangerousLink">{$medialink}</span> $dirmark<span class="fileInfo">$longDesc</span></div>
 <div class="mediaWarning">$warning</div>
 EOT
-                                               );
-                               } else {
-                                       $out->addWikiText( <<<EOT
+                                       );
+                       } else {
+                               $out->addWikiText( <<<EOT
 <div class="fullMedia">{$medialink} {$dirmark}<span class="fileInfo">$longDesc</span>
 </div>
 EOT
-                                       );
-                               }
+                               );
                        }
 
                        // Add cannot animate thumbnail warning
@@ -547,7 +531,7 @@ EOT
                                        array( 'delete', 'move' ),
                                        $this->getTitle()->getPrefixedText(),
                                        '',
-                                       array(  'lim' => 10,
+                                       array( 'lim' => 10,
                                                'conds' => array( "log_action != 'revision'" ),
                                                'showIfEmpty' => false,
                                                'msgKey' => array( 'moveddeleted-notice' )
@@ -620,7 +604,7 @@ EOT
                $wrap = "<div class=\"sharedUploadNotice\">\n$1\n</div>\n";
                $repo = $this->mPage->getFile()->getRepo()->getDisplayName();
 
-               if ( $descUrl && $descText && wfMessage( 'sharedupload-desc-here' )->plain() !== '-'  ) {
+               if ( $descUrl && $descText && wfMessage( 'sharedupload-desc-here' )->plain() !== '-' ) {
                        $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-here', $repo, $descUrl ) );
                } elseif ( $descUrl && wfMessage( 'sharedupload-desc-there' )->plain() !== '-' ) {
                        $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-there', $repo, $descUrl ) );
@@ -639,7 +623,7 @@ EOT
                return $uploadTitle->getFullURL( array(
                        'wpDestFile' => $this->mPage->getFile()->getName(),
                        'wpForReUpload' => 1
-                ) );
+               ) );
        }
 
        /**
@@ -820,7 +804,7 @@ EOT
 
                                $ul = Html::rawElement(
                                        'ul',
-                                       array( 'class' => 'mw-imagepage-redirectstofile'),
+                                       array( 'class' => 'mw-imagepage-redirectstofile' ),
                                        $li
                                        ) . "\n";
                                $liContents = wfMessage( 'linkstoimage-redirect' )->rawParams(
@@ -920,6 +904,34 @@ EOT
                        return $a->page_namespace - $b->page_namespace;
                }
        }
+
+       /**
+        * Returns the corrosponding $wgImageLimits entry for the selected user option
+        *
+        * @param $user User
+        * @param $optionName string Name of a option to check, typically imagesize or thumbsize
+        * @return array
+        * @since 1.21
+        */
+       public function getImageLimitsFromOption( $user, $optionName ) {
+               global $wgImageLimits;
+
+               $option = intval( $user->getOption( $optionName ) );
+               if ( !isset( $wgImageLimits[$option] ) ) {
+                       $option = User::getDefaultOption( $optionName );
+               }
+
+               // The user offset might still be incorrect, specially if
+               // $wgImageLimits got changed (see bug #8858).
+               if ( !isset( $wgImageLimits[$option] ) ) {
+                       // Default to the first offset in $wgImageLimits
+                       $option = 0;
+               }
+
+               return isset( $wgImageLimits[$option] )
+                       ? $wgImageLimits[$option]
+                       : array( 800, 600 ); // if nothing is set, fallback to a hardcoded default
+       }
 }
 
 /**
@@ -1053,9 +1065,9 @@ class ImageHistoryList extends ContextSource {
                                } else {
                                        list( $ts, ) = explode( '!', $img, 2 );
                                        $query = array(
-                                               'type'   => 'oldimage',
+                                               'type' => 'oldimage',
                                                'target' => $this->title->getPrefixedText(),
-                                               'ids'    => $ts,
+                                               'ids' => $ts,
                                        );
                                        $del = Linker::revDeleteLink( $query,
                                                $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
@@ -1175,7 +1187,7 @@ class ImageHistoryList extends ContextSource {
        protected function getThumbForLine( $file ) {
                $lang = $this->getLanguage();
                $user = $this->getUser();
-               if ( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE,$user )
+               if ( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE, $user )
                        && !$file->isDeleted( File::DELETED_FILE ) )
                {
                        $params = array(
index bd9ce25..15e6620 100644 (file)
@@ -400,7 +400,7 @@ class WikiImporter {
        /** Left in for debugging */
        private function dumpElement() {
                static $lookup = null;
-               if (!$lookup) {
+               if ( !$lookup ) {
                        $xmlReaderConstants = array(
                                "NONE",
                                "ELEMENT",
@@ -473,7 +473,7 @@ class WikiImporter {
                                $skip = true;
                        }
 
-                       if ($skip) {
+                       if ( $skip ) {
                                $keepReading = $this->reader->next();
                                $skip = false;
                                $this->debug( "Skip" );
@@ -509,7 +509,7 @@ class WikiImporter {
 
                while ( $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'logitem') {
+                                       $this->reader->name == 'logitem' ) {
                                break;
                        }
 
@@ -572,7 +572,7 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'page') {
+                                       $this->reader->name == 'page' ) {
                                break;
                        }
 
@@ -626,7 +626,7 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'revision') {
+                                       $this->reader->name == 'revision' ) {
                                break;
                        }
 
@@ -712,7 +712,7 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'upload') {
+                                       $this->reader->name == 'upload' ) {
                                break;
                        }
 
@@ -809,7 +809,7 @@ class WikiImporter {
 
                while ( $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'contributor') {
+                                       $this->reader->name == 'contributor' ) {
                                break;
                        }
 
@@ -897,7 +897,7 @@ class UploadSourceAdapter {
         * @return bool
         */
        function stream_open( $path, $mode, $options, &$opened_path ) {
-               $url = parse_url($path);
+               $url = parse_url( $path );
                $id = $url['host'];
 
                if ( !isset( self::$sourceRegistrations[$id] ) ) {
@@ -918,22 +918,22 @@ class UploadSourceAdapter {
                $leave = false;
 
                while ( !$leave && !$this->mSource->atEnd() &&
-                               strlen($this->mBuffer) < $count ) {
+                               strlen( $this->mBuffer ) < $count ) {
                        $read = $this->mSource->readChunk();
 
-                       if ( !strlen($read) ) {
+                       if ( !strlen( $read ) ) {
                                $leave = true;
                        }
 
                        $this->mBuffer .= $read;
                }
 
-               if ( strlen($this->mBuffer) ) {
+               if ( strlen( $this->mBuffer ) ) {
                        $return = substr( $this->mBuffer, 0, $count );
                        $this->mBuffer = substr( $this->mBuffer, $count );
                }
 
-               $this->mPosition += strlen($return);
+               $this->mPosition += strlen( $return );
 
                return $return;
        }
@@ -1390,7 +1390,7 @@ class WikiRevision {
                                array( 'rev_page' => $pageId,
                                        'rev_timestamp' => $dbw->timestamp( $this->timestamp ),
                                        'rev_user_text' => $userText,
-                                       'rev_comment'   => $this->getComment() ),
+                                       'rev_comment' => $this->getComment() ),
                                __METHOD__
                        );
                        if( $prior ) {
@@ -1405,15 +1405,15 @@ class WikiRevision {
                # @todo FIXME: Use original rev_id optionally (better for backups)
                # Insert the row
                $revision = new Revision( array(
-                       'title'      => $this->title,
-                       'page'       => $pageId,
-                       'content_model'  => $this->getModel(),
+                       'title' => $this->title,
+                       'page' => $pageId,
+                       'content_model' => $this->getModel(),
                        'content_format' => $this->getFormat(),
-                       'text'       => $this->getContent()->serialize( $this->getFormat() ), //XXX: just set 'content' => $this->getContent()?
-                       'comment'    => $this->getComment(),
-                       'user'       => $userId,
-                       'user_text'  => $userText,
-                       'timestamp'  => $this->timestamp,
+                       'text' => $this->getContent()->serialize( $this->getFormat() ), //XXX: just set 'content' => $this->getContent()?
+                       'comment' => $this->getComment(),
+                       'user' => $userId,
+                       'user_text' => $userText,
+                       'timestamp' => $this->timestamp,
                        'minor_edit' => $this->minor,
                        ) );
                $revision->insertOn( $dbw );
@@ -1442,13 +1442,13 @@ class WikiRevision {
                // @todo FIXME: Use original log ID (better for backups)
                $prior = $dbw->selectField( 'logging', '1',
                        array( 'log_type' => $this->getType(),
-                               'log_action'    => $this->getAction(),
+                               'log_action' => $this->getAction(),
                                'log_timestamp' => $dbw->timestamp( $this->timestamp ),
                                'log_namespace' => $this->getTitle()->getNamespace(),
-                               'log_title'     => $this->getTitle()->getDBkey(),
-                               'log_comment'   => $this->getComment(),
+                               'log_title' => $this->getTitle()->getDBkey(),
+                               'log_comment' => $this->getComment(),
                                #'log_user_text' => $this->user_text,
-                               'log_params'    => $this->params ),
+                               'log_params' => $this->params ),
                        __METHOD__
                );
                // @todo FIXME: This could fail slightly for multiple matches :P
@@ -1650,7 +1650,7 @@ class ImportStreamSource {
                        return Status::newFatal( 'importnofile' );
                }
                if( !empty( $upload['error'] ) ) {
-                       switch($upload['error']){
+                       switch( $upload['error'] ) {
                                case 1: # The uploaded file exceeds the upload_max_filesize directive in php.ini.
                                        return Status::newFatal( 'importuploaderrorsize' );
                                case 2: # The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
index c2f6b1e..28379c7 100644 (file)
@@ -89,7 +89,7 @@ class LinkFilter {
         * @param $prot        String: protocol
         * @return Array to be passed to DatabaseBase::buildLike() or false on error
         */
-        public static function makeLikeArray( $filterEntry , $prot = 'http://' ) {
+       public static function makeLikeArray( $filterEntry, $prot = 'http://' ) {
                $db = wfGetDB( DB_MASTER );
                if ( substr( $filterEntry, 0, 2 ) == '*.' ) {
                        $subdomains = true;
@@ -118,7 +118,7 @@ class LinkFilter {
                }
                // Reverse the labels in the hostname, convert to lower case
                // For emails reverse domainpart only
-               if ( $prot == 'mailto:' && strpos($host, '@') ) {
+               if ( $prot == 'mailto:' && strpos( $host, '@' ) ) {
                        // complete email adress
                        $mailparts = explode( '@', $host );
                        $domainpart = strtolower( implode( '.', array_reverse( explode( '.', $mailparts[1] ) ) ) );
index 2f6ee22..a96bc5f 100644 (file)
@@ -33,7 +33,7 @@ class Linker {
         * Flags for userToolLinks()
         */
        const TOOL_LINKS_NOBLOCK = 1;
-       const TOOL_LINKS_EMAIL   = 2;
+       const TOOL_LINKS_EMAIL = 2;
 
        /**
         * Get the appropriate HTML attributes to add to the "a" element of an ex-
@@ -600,9 +600,9 @@ class Linker {
                $prefix = $postfix = '';
 
                if ( 'center' == $fp['align'] ) {
-                       $prefix  = '<div class="center">';
+                       $prefix = '<div class="center">';
                        $postfix = '</div>';
-                       $fp['align']   = 'none';
+                       $fp['align'] = 'none';
                }
                if ( $file && !isset( $hp['width'] ) ) {
                        if ( isset( $hp['height'] ) && $file->isVectorized() ) {
@@ -724,7 +724,7 @@ class Linker {
                                $extLinkAttrs = $parser->getExternalLinkAttribs( $frameParams['link-url'] );
                                foreach ( $extLinkAttrs as $name => $val ) {
                                        // Currently could include 'rel' and 'target'
-                                       $mtoParams['parser-extlink-'.$name] = $val;
+                                       $mtoParams['parser-extlink-' . $name] = $val;
                                }
                        }
                } elseif ( isset( $frameParams['link-title'] ) && $frameParams['link-title'] !== '' ) {
@@ -751,7 +751,7 @@ class Linker {
         * @return mixed
         */
        public static function makeThumbLinkObj( Title $title, $file, $label = '', $alt,
-               $align = 'right', $params = array(), $framed = false , $manualthumb = "" )
+               $align = 'right', $params = array(), $framed = false, $manualthumb = "" )
        {
                $frameParams = array(
                        'alt' => $alt,
@@ -1028,7 +1028,7 @@ class Linker {
                        $key = strtolower( $name );
                }
 
-               return self::linkKnown( SpecialPage::getTitleFor( $name ) , wfMessage( $key )->text() );
+               return self::linkKnown( SpecialPage::getTitleFor( $name ), wfMessage( $key )->text() );
        }
 
        /**
@@ -1038,9 +1038,11 @@ class Linker {
         * @param $escape Boolean: do we escape the link text?
         * @param $linktype String: type of external link. Gets added to the classes
         * @param $attribs Array of extra attributes to <a>
+        * @param $title Title|null Title object used for title specific link attributes
         * @return string
         */
-       public static function makeExternalLink( $url, $text, $escape = true, $linktype = '', $attribs = array() ) {
+       public static function makeExternalLink( $url, $text, $escape = true, $linktype = '', $attribs = array(), $title = null ) {
+               global $wgTitle;
                $class = "external";
                if ( $linktype ) {
                        $class .= " $linktype";
@@ -1053,6 +1055,11 @@ class Linker {
                if ( $escape ) {
                        $text = htmlspecialchars( $text );
                }
+
+               if ( !$title ) {
+                       $title = $wgTitle;
+               }
+               $attribs['rel'] = Parser::getExternalLinkRel( $url, $title );
                $link = '';
                $success = wfRunHooks( 'LinkerMakeExternalLink',
                        array( &$url, &$text, &$link, &$attribs, $linktype ) );
@@ -1665,11 +1672,10 @@ class Linker {
                $lang = wfGetLangObj( $lang );
                $title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
 
-               return
-                  '<table id="toc" class="toc"><tr><td>'
-                . '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
-                . $toc
-                . "</ul>\n</td></tr></table>\n";
+               return '<table id="toc" class="toc"><tr><td>'
+                       . '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
+                       . $toc
+                       . "</ul>\n</td></tr></table>\n";
        }
 
        /**
@@ -1927,13 +1933,13 @@ class Linker {
         * Make an HTML list of templates, and then add a "More..." link at
         * the bottom. If $more is null, do not add a "More..." link. If $more
         * is a Title, make a link to that title and use it. If $more is a string,
-        * directly paste it in as the link.
+        * directly paste it in as the link (escaping needs to be done manually).
+        * Finally, if $more is a Message, call toString().
         *
-        * @param $templates Array of templates from Article::getUsedTemplate
-        * or similar
+        * @param array $templates Array of templates from Article::getUsedTemplate or similar
         * @param bool $preview Whether this is for a preview
         * @param bool $section Whether this is for a section edit
-        * @param Title|string|null $more A link for "More..." of the templates
+        * @param Title|Message|string|null $more An escaped link for "More..." of the templates
         * @return String: HTML output
         */
        public static function formatTemplates( $templates, $preview = false, $section = false, $more = null ) {
@@ -2068,7 +2074,7 @@ class Linker {
                        # Compatibility: formerly some tooltips had [alt-.] hardcoded
                        $tooltip = preg_replace( "/ ?\[alt-.\]$/", '', $tooltip );
                        # Message equal to '-' means suppress it.
-                       if (  $tooltip == '-' ) {
+                       if ( $tooltip == '-' ) {
                                $tooltip = false;
                        }
                }
@@ -2150,17 +2156,17 @@ class Linker {
                                // RevDelete links using revision ID are stable across
                                // page deletion and undeletion; use when possible.
                                $query = array(
-                                       'type'   => 'revision',
+                                       'type' => 'revision',
                                        'target' => $title->getPrefixedDBkey(),
-                                       'ids'    => $rev->getId()
+                                       'ids' => $rev->getId()
                                );
                        } else {
                                // Older deleted entries didn't save a revision ID.
                                // We have to refer to these by timestamp, ick!
                                $query = array(
-                                       'type'   => 'archive',
+                                       'type' => 'archive',
                                        'target' => $title->getPrefixedDBkey(),
-                                       'ids'    => $rev->getTimestamp()
+                                       'ids' => $rev->getTimestamp()
                                );
                        }
                        return Linker::revDeleteLink( $query,
@@ -2280,7 +2286,7 @@ class Linker {
         * @return string the a-element
         */
        static function makeKnownLinkObj(
-               $title, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = ''
+               $title, $text = '', $query = '', $trail = '', $prefix = '', $aprops = '', $style = ''
        ) {
                wfDeprecated( __METHOD__, '1.21' );
 
index cfd7413..83883b5 100644 (file)
@@ -213,14 +213,14 @@ class LinksUpdate extends SqlDataUpdate {
                $existing = $this->getExistingImages();
                $imageUpdates = array_diff_key( $existing, $this->mImages ) + array_diff_key( $this->mImages, $existing );
 
-               $this->dumbTableUpdate( 'pagelinks',     $this->getLinkInsertions(),     'pl_from' );
-               $this->dumbTableUpdate( 'imagelinks',    $this->getImageInsertions(),    'il_from' );
+               $this->dumbTableUpdate( 'pagelinks', $this->getLinkInsertions(), 'pl_from' );
+               $this->dumbTableUpdate( 'imagelinks', $this->getImageInsertions(), 'il_from' );
                $this->dumbTableUpdate( 'categorylinks', $this->getCategoryInsertions(), 'cl_from' );
                $this->dumbTableUpdate( 'templatelinks', $this->getTemplateInsertions(), 'tl_from' );
                $this->dumbTableUpdate( 'externallinks', $this->getExternalInsertions(), 'el_from' );
-               $this->dumbTableUpdate( 'langlinks',     $this->getInterlangInsertions(),'ll_from' );
-               $this->dumbTableUpdate( 'iwlinks',       $this->getInterwikiInsertions(),'iwl_from' );
-               $this->dumbTableUpdate( 'page_props',    $this->getPropertyInsertions(), 'pp_page' );
+               $this->dumbTableUpdate( 'langlinks', $this->getInterlangInsertions(), 'll_from' );
+               $this->dumbTableUpdate( 'iwlinks', $this->getInterwikiInsertions(), 'iwl_from' );
+               $this->dumbTableUpdate( 'page_props', $this->getPropertyInsertions(), 'pp_page' );
 
                # Update the cache of all the category pages and image description
                # pages which were changed, and fix the category table count
@@ -291,7 +291,7 @@ class LinksUpdate extends SqlDataUpdate {
                $this->mDb->delete( $table, array( $fromField => $this->mId ), __METHOD__ );
                if ( count( $insertions ) ) {
                        # The link array was constructed without FOR UPDATE, so there may
-                       # be collisions.  This may cause minor link table inconsistencies,
+                       # be collisions. This may cause minor link table inconsistencies,
                        # which is better than crippling the site with lock contention.
                        $this->mDb->insert( $table, $insertions, __METHOD__, array( 'IGNORE' ) );
                }
@@ -360,9 +360,9 @@ class LinksUpdate extends SqlDataUpdate {
                                : $dbkeys;
                        foreach ( $diffs as $dbk => $id ) {
                                $arr[] = array(
-                                       'pl_from'      => $this->mId,
+                                       'pl_from' => $this->mId,
                                        'pl_namespace' => $ns,
-                                       'pl_title'     => $dbk
+                                       'pl_title' => $dbk
                                );
                        }
                }
@@ -380,9 +380,9 @@ class LinksUpdate extends SqlDataUpdate {
                        $diffs = isset( $existing[$ns] ) ? array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys;
                        foreach ( $diffs as $dbk => $id ) {
                                $arr[] = array(
-                                       'tl_from'      => $this->mId,
+                                       'tl_from' => $this->mId,
                                        'tl_namespace' => $ns,
-                                       'tl_title'     => $dbk
+                                       'tl_title' => $dbk
                                );
                        }
                }
@@ -401,7 +401,7 @@ class LinksUpdate extends SqlDataUpdate {
                foreach( $diffs as $iname => $dummy ) {
                        $arr[] = array(
                                'il_from' => $this->mId,
-                               'il_to'   => $iname
+                               'il_to' => $iname
                        );
                }
                return $arr;
@@ -418,9 +418,9 @@ class LinksUpdate extends SqlDataUpdate {
                foreach( $diffs as $url => $dummy ) {
                        foreach( wfMakeUrlIndexes( $url ) as $index ) {
                                $arr[] = array(
-                                       'el_from'   => $this->mId,
-                                       'el_to'     => $url,
-                                       'el_index'  => $index,
+                                       'el_from' => $this->mId,
+                                       'el_to' => $url,
+                                       'el_index' => $index,
                                );
                        }
                }
@@ -459,8 +459,8 @@ class LinksUpdate extends SqlDataUpdate {
                                $this->mTitle->getCategorySortkey( $prefix ) );
 
                        $arr[] = array(
-                               'cl_from'    => $this->mId,
-                               'cl_to'      => $name,
+                               'cl_from' => $this->mId,
+                               'cl_to' => $name,
                                'cl_sortkey' => $sortkey,
                                'cl_timestamp' => $this->mDb->timestamp(),
                                'cl_sortkey_prefix' => $prefix,
@@ -483,8 +483,8 @@ class LinksUpdate extends SqlDataUpdate {
                $arr = array();
                foreach( $diffs as $lang => $title ) {
                        $arr[] = array(
-                               'll_from'  => $this->mId,
-                               'll_lang'  => $lang,
+                               'll_from' => $this->mId,
+                               'll_lang' => $lang,
                                'll_title' => $title
                        );
                }
@@ -501,9 +501,9 @@ class LinksUpdate extends SqlDataUpdate {
                $arr = array();
                foreach ( $diffs as $name => $value ) {
                        $arr[] = array(
-                               'pp_page'      => $this->mId,
-                               'pp_propname'  => $name,
-                               'pp_value'     => $value,
+                               'pp_page' => $this->mId,
+                               'pp_propname' => $name,
+                               'pp_value' => $value,
                        );
                }
                return $arr;
@@ -521,9 +521,9 @@ class LinksUpdate extends SqlDataUpdate {
                        $diffs = isset( $existing[$prefix] ) ? array_diff_key( $dbkeys, $existing[$prefix] ) : $dbkeys;
                        foreach ( $diffs as $dbk => $id ) {
                                $arr[] = array(
-                                       'iwl_from'   => $this->mId,
+                                       'iwl_from' => $this->mId,
                                        'iwl_prefix' => $prefix,
-                                       'iwl_title'  => $dbk
+                                       'iwl_title' => $dbk
                                );
                        }
                }
index 7cf59e9..257a46d 100644 (file)
@@ -217,7 +217,7 @@ class MagicWord {
 
        /**#@-*/
 
-       function __construct($id = 0, $syn = array(), $cs = false) {
+       function __construct( $id = 0, $syn = array(), $cs = false ) {
                $this->mId = $id;
                $this->mSynonyms = (array)$syn;
                $this->mCaseSensitive = $cs;
@@ -367,7 +367,7 @@ class MagicWord {
         * @return string
         */
        function getRegex() {
-               if ($this->mRegex == '' ) {
+               if ( $this->mRegex == '' ) {
                        $this->initRegex();
                }
                return $this->mRegex;
@@ -393,7 +393,7 @@ class MagicWord {
         * @return string
         */
        function getRegexStart() {
-               if ($this->mRegex == '' ) {
+               if ( $this->mRegex == '' ) {
                        $this->initRegex();
                }
                return $this->mRegexStart;
@@ -405,7 +405,7 @@ class MagicWord {
         * @return string
         */
        function getBaseRegex() {
-               if ($this->mRegex == '') {
+               if ( $this->mRegex == '' ) {
                        $this->initRegex();
                }
                return $this->mBaseRegex;
@@ -454,9 +454,9 @@ class MagicWord {
                        # blank elements and re-sort the indices.
                        # See also bug 6526
 
-                       $matches = array_values(array_filter($matches));
+                       $matches = array_values( array_filter( $matches ) );
 
-                       if ( count($matches) == 1 ) {
+                       if ( count( $matches ) == 1 ) {
                                return $matches[0];
                        } else {
                                return $matches[1];
@@ -598,7 +598,7 @@ class MagicWord {
        function replaceMultiple( $magicarr, $subject, &$result ) {
                $search = array();
                $replace = array();
-               foreach( $magicarr as $id => $replacement ){
+               foreach( $magicarr as $id => $replacement ) {
                        $mw = MagicWord::get( $id );
                        $search[] = $mw->getRegex();
                        $replace[] = $replacement;
@@ -618,7 +618,7 @@ class MagicWord {
        function addToArray( &$array, $value ) {
                global $wgContLang;
                foreach ( $this->mSynonyms as $syn ) {
-                       $array[$wgContLang->lc($syn)] = $value;
+                       $array[$wgContLang->lc( $syn )] = $value;
                }
        }
 
@@ -812,7 +812,7 @@ class MagicWordArray {
                        return array( $magicName, $paramValue );
                }
                // This shouldn't happen either
-               throw new MWException( __METHOD__.': parameter not found' );
+               throw new MWException( __METHOD__ . ': parameter not found' );
        }
 
        /**
index 8f10b8b..6e533a3 100644 (file)
@@ -226,6 +226,39 @@ class Message {
                $this->language = $wgLang;
        }
 
+       /**
+        * Returns the message key
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getKey() {
+               return $this->key;
+       }
+
+       /**
+        * Returns the message parameters
+        *
+        * @since 1.21
+        *
+        * @return string[]
+        */
+       public function getParams() {
+               return $this->parameters;
+       }
+
+       /**
+        * Returns the message format
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getFormat() {
+               return $this->format;
+       }
+
        /**
         * Factory function that is just wrapper for the real constructor. It is
         * intented to be used instead of the real constructor, because it allows
@@ -252,9 +285,9 @@ class Message {
        public static function newFallbackSequence( /*...*/ ) {
                $keys = func_get_args();
                if ( func_num_args() == 1 ) {
-                       if ( is_array($keys[0]) ) {
+                       if ( is_array( $keys[0] ) ) {
                                // Allow an array to be passed as the first argument instead
-                               $keys = array_values($keys[0]);
+                               $keys = array_values( $keys[0] );
                        } else {
                                // Optimize a single string to not need special fallback handling
                                $keys = $keys[0];
@@ -416,7 +449,7 @@ class Message {
         */
        public function content() {
                if ( !$this->content ) {
-                       $this->content = new MessageContent( $this->key );
+                       $this->content = new MessageContent( $this );
                }
 
                return $this->content;
@@ -431,7 +464,7 @@ class Message {
                $string = $this->fetchMessage();
 
                if ( $string === false ) {
-                       $key =  htmlspecialchars( is_array( $this->key ) ? $this->key[0] : $this->key );
+                       $key = htmlspecialchars( is_array( $this->key ) ? $this->key[0] : $this->key );
                        if ( $this->format === 'plain' ) {
                                return '<' . $key . '>';
                        }
@@ -457,11 +490,11 @@ class Message {
                        if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
                                $string = $m[1];
                        }
-               } elseif( $this->format === 'block-parse' ){
+               } elseif( $this->format === 'block-parse' ) {
                        $string = $this->parseText( $string );
-               } elseif( $this->format === 'text' ){
+               } elseif( $this->format === 'text' ) {
                        $string = $this->transformText( $string );
-               } elseif( $this->format === 'escaped' ){
+               } elseif( $this->format === 'escaped' ) {
                        $string = $this->transformText( $string );
                        $string = htmlspecialchars( $string, ENT_QUOTES, 'UTF-8', false );
                }
@@ -474,7 +507,7 @@ class Message {
 
        /**
         * Magic method implementation of the above (for PHP >= 5.2.0), so we can do, eg:
-        *     $foo = Message::get($key);
+        *     $foo = Message::get( $key );
         *     $string = "<abbr>$foo</abbr>";
         * @since 1.18
         * @return String
index 15894a4..0b8014a 100644 (file)
@@ -34,7 +34,7 @@ abstract class RdfMetaData {
                $this->mArticle = $article;
        }
 
-       public abstract function show();
+       abstract public function show();
 
        protected function setup() {
                global $wgOut, $wgRequest;
@@ -42,7 +42,7 @@ abstract class RdfMetaData {
                $httpaccept = isset( $_SERVER['HTTP_ACCEPT'] ) ? $_SERVER['HTTP_ACCEPT'] : null;
                $rdftype = wfNegotiateType( wfAcceptToPrefs( $httpaccept ), wfAcceptToPrefs( self::RDF_TYPE_PREFS ) );
 
-               if( !$rdftype ){
+               if( !$rdftype ) {
                        throw new HttpError( 406, wfMessage( 'notacceptable' ) );
                }
 
@@ -70,7 +70,7 @@ abstract class RdfMetaData {
                $lastEditor = User::newFromId( $this->mArticle->getUser() );
                $this->person( 'creator', $lastEditor );
 
-               foreach( $this->mArticle->getContributors() as $user ){
+               foreach( $this->mArticle->getContributors() as $user ) {
                        $this->person( 'contributor', $user );
                }
 
@@ -82,10 +82,10 @@ abstract class RdfMetaData {
                print "\t\t<dc:{$name}>{$value}</dc:{$name}>\n";
        }
 
-       protected function date($timestamp) {
-               return substr($timestamp, 0, 4) . '-'
-                 . substr($timestamp, 4, 2) . '-'
-                 . substr($timestamp, 6, 2);
+       protected function date( $timestamp ) {
+               return substr( $timestamp, 0, 4 ) . '-'
+                       . substr( $timestamp, 4, 2 ) . '-'
+                       . substr( $timestamp, 6, 2 );
        }
 
        protected function pageOrString( $name, $page, $str ) {
@@ -95,7 +95,7 @@ abstract class RdfMetaData {
                        $nt = Title::newFromText( $page );
                }
 
-               if( !$nt || $nt->getArticleID() == 0 ){
+               if( !$nt || $nt->getArticleID() == 0 ) {
                        $this->element( $name, $str );
                } else {
                        $this->page( $name, $nt );
@@ -110,13 +110,13 @@ abstract class RdfMetaData {
                $this->url( $name, $title->getFullUrl() );
        }
 
-       protected function url($name, $url) {
+       protected function url( $name, $url ) {
                $url = htmlspecialchars( $url );
                print "\t\t<dc:{$name} rdf:resource=\"{$url}\" />\n";
        }
 
        protected function person( $name, User $user ) {
-               if( $user->isAnon() ){
+               if( $user->isAnon() ) {
                        $this->element( $name, wfMessage( 'anonymous' )->numParams( 1 )->text() );
                } else {
                        $real = $user->getRealName();
@@ -141,11 +141,11 @@ abstract class RdfMetaData {
                global $wgRightsPage, $wgRightsUrl, $wgRightsText;
 
                if( $wgRightsPage && ( $nt = Title::newFromText( $wgRightsPage ) )
-                       && ($nt->getArticleID() != 0)) {
-                       $this->page('rights', $nt);
-               } elseif( $wgRightsUrl ){
-                       $this->url('rights', $wgRightsUrl);
-               } elseif( $wgRightsText ){
+                       && ( $nt->getArticleID() != 0 ) ) {
+                       $this->page( 'rights', $nt );
+               } elseif( $wgRightsUrl ) {
+                       $this->url( 'rights', $wgRightsUrl );
+               } elseif( $wgRightsText ) {
                        $this->element( 'rights', $wgRightsText );
                }
        }
@@ -153,7 +153,7 @@ abstract class RdfMetaData {
        protected function getTerms( $url ) {
                global $wgLicenseTerms;
 
-               if( $wgLicenseTerms ){
+               if( $wgLicenseTerms ) {
                        return $wgLicenseTerms;
                } else {
                        $known = $this->getKnownLicenses();
@@ -166,23 +166,23 @@ abstract class RdfMetaData {
        }
 
        protected function getKnownLicenses() {
-               $ccLicenses = array('by', 'by-nd', 'by-nd-nc', 'by-nc',
-                                                       'by-nc-sa', 'by-sa');
-               $ccVersions = array('1.0', '2.0');
+               $ccLicenses = array( 'by', 'by-nd', 'by-nd-nc', 'by-nc',
+                                                       'by-nc-sa', 'by-sa' );
+               $ccVersions = array( '1.0', '2.0' );
                $knownLicenses = array();
 
-               foreach ($ccVersions as $version) {
-                       foreach ($ccLicenses as $license) {
-                               if( $version == '2.0' && substr( $license, 0, 2) != 'by' ) {
+               foreach ( $ccVersions as $version ) {
+                       foreach ( $ccLicenses as $license ) {
+                               if( $version == '2.0' && substr( $license, 0, 2 ) != 'by' ) {
                                        # 2.0 dropped the non-attribs licenses
                                        continue;
                                }
                                $lurl = "http://creativecommons.org/licenses/{$license}/{$version}/";
-                               $knownLicenses[$lurl] = explode('-', $license);
+                               $knownLicenses[$lurl] = explode( '-', $license );
                                $knownLicenses[$lurl][] = 're';
                                $knownLicenses[$lurl][] = 'di';
                                $knownLicenses[$lurl][] = 'no';
-                               if (!in_array('nd', $knownLicenses[$lurl])) {
+                               if ( !in_array( 'nd', $knownLicenses[$lurl] ) ) {
                                        $knownLicenses[$lurl][] = 'de';
                                }
                        }
@@ -191,13 +191,12 @@ abstract class RdfMetaData {
                /* Handle the GPL and LGPL, too. */
 
                $knownLicenses['http://creativecommons.org/licenses/GPL/2.0/'] =
-                 array('de', 're', 'di', 'no', 'sa', 'sc');
+                       array( 'de', 're', 'di', 'no', 'sa', 'sc' );
                $knownLicenses['http://creativecommons.org/licenses/LGPL/2.1/'] =
-                 array('de', 're', 'di', 'no', 'sa', 'sc');
+                       array( 'de', 're', 'di', 'no', 'sa', 'sc' );
                $knownLicenses['http://www.gnu.org/copyleft/fdl.html'] =
-                 array('de', 're', 'di', 'no', 'sa', 'sc');
+                       array( 'de', 're', 'di', 'no', 'sa', 'sc' );
 
                return $knownLicenses;
        }
 }
-
index 65a2a6f..e787fbd 100644 (file)
@@ -39,7 +39,7 @@
  * 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
+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
@@ -197,14 +197,14 @@ class MimeMagic {
 
                if ( $wgMimeTypeFile ) {
                        if ( is_file( $wgMimeTypeFile ) and is_readable( $wgMimeTypeFile ) ) {
-                               wfDebug( __METHOD__.": loading mime types from $wgMimeTypeFile\n" );
+                               wfDebug( __METHOD__ . ": loading mime types from $wgMimeTypeFile\n" );
                                $types .= "\n";
                                $types .= file_get_contents( $wgMimeTypeFile );
                        } else {
-                               wfDebug( __METHOD__.": can't load mime types from $wgMimeTypeFile\n" );
+                               wfDebug( __METHOD__ . ": can't load mime types from $wgMimeTypeFile\n" );
                        }
                } else {
-                       wfDebug( __METHOD__.": no mime types file defined, using build-ins only.\n" );
+                       wfDebug( __METHOD__ . ": no mime types file defined, using build-ins only.\n" );
                }
 
                $types = str_replace( array( "\r\n", "\n\r", "\n\n", "\r\r", "\r" ), "\n", $types );
@@ -213,7 +213,7 @@ class MimeMagic {
                $this->mMimeToExt = array();
                $this->mToMime = array();
 
-               $lines = explode( "\n",$types );
+               $lines = explode( "\n", $types );
                foreach ( $lines as $s ) {
                        $s = trim( $s );
                        if ( empty( $s ) ) {
@@ -231,7 +231,7 @@ class MimeMagic {
                        }
 
                        $mime = substr( $s, 0, $i );
-                       $ext = trim( substr($s, $i+1 ) );
+                       $ext = trim( substr( $s, $i+1 ) );
 
                        if ( empty( $ext ) ) {
                                continue;
@@ -272,17 +272,17 @@ class MimeMagic {
 
                if ( $wgMimeInfoFile ) {
                        if ( is_file( $wgMimeInfoFile ) and is_readable( $wgMimeInfoFile ) ) {
-                               wfDebug( __METHOD__.": loading mime info from $wgMimeInfoFile\n" );
+                               wfDebug( __METHOD__ . ": loading mime info from $wgMimeInfoFile\n" );
                                $info .= "\n";
                                $info .= file_get_contents( $wgMimeInfoFile );
                        } else {
-                               wfDebug(__METHOD__.": can't load mime info from $wgMimeInfoFile\n");
+                               wfDebug( __METHOD__ . ": can't load mime info from $wgMimeInfoFile\n" );
                        }
                } else {
-                       wfDebug(__METHOD__.": no mime info file defined, using build-ins only.\n");
+                       wfDebug( __METHOD__ . ": no mime info file defined, using build-ins only.\n" );
                }
 
-               $info = str_replace( array( "\r\n", "\n\r", "\n\n", "\r\r", "\r" ), "\n", $info);
+               $info = str_replace( array( "\r\n", "\n\r", "\n\n", "\r\r", "\r" ), "\n", $info );
                $info = str_replace( "\t", " ", $info );
 
                $this->mMimeTypeAliases = array();
@@ -330,9 +330,9 @@ class MimeMagic {
                                $this->mMediaTypes[$mtype][] = $mime;
                        }
 
-                       if ( sizeof( $m ) > 1 ) {
+                       if ( count( $m ) > 1 ) {
                                $main = $m[0];
-                               for ( $i=1; $i<sizeof($m); $i += 1 ) {
+                               for ( $i = 1; $i < count( $m ); $i += 1 ) {
                                        $mime = $m[$i];
                                        $this->mMimeTypeAliases[$mime] = $main;
                                }
@@ -511,7 +511,7 @@ class MimeMagic {
        public function improveTypeFromExtension( $mime, $ext ) {
                if ( $mime === 'unknown/unknown' ) {
                        if ( $this->isRecognizableExtension( $ext ) ) {
-                               wfDebug( __METHOD__. ': refusing to guess mime type for .' .
+                               wfDebug( __METHOD__ . ': refusing to guess mime type for .' .
                                        "$ext file, we should have recognized it\n" );
                        } else {
                                // Not something we can detect, so simply
@@ -525,7 +525,7 @@ class MimeMagic {
                                // find the proper mime type for that file extension
                                $mime = $this->guessTypesForExtension( $ext );
                        } else {
-                               wfDebug( __METHOD__. ": refusing to guess better type for $mime file, " .
+                               wfDebug( __METHOD__ . ": refusing to guess better type for $mime file, " .
                                        ".$ext is not a known OPC extension.\n" );
                                $mime = 'application/zip';
                        }
@@ -535,7 +535,7 @@ class MimeMagic {
                        $mime = $this->mMimeTypeAliases[$mime];
                }
 
-               wfDebug(__METHOD__.": improved mime type for .$ext: $mime\n");
+               wfDebug( __METHOD__ . ": improved mime type for .$ext: $mime\n" );
                return $mime;
        }
 
@@ -555,14 +555,14 @@ class MimeMagic {
         */
        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. " .
+                       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" );
+                       wfDebug( __METHOD__ . ": internal type detection failed for $file (.$ext)...\n" );
                        $mime = $this->detectMimeType( $file, $ext );
                }
 
@@ -570,7 +570,7 @@ class MimeMagic {
                        $mime = $this->mMimeTypeAliases[$mime];
                }
 
-               wfDebug(__METHOD__.": guessed mime type of $file: $mime\n");
+               wfDebug( __METHOD__ . ": guessed mime type of $file: $mime\n" );
                return $mime;
        }
 
@@ -629,7 +629,7 @@ class MimeMagic {
                        $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);
+                               $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";
@@ -661,12 +661,11 @@ class MimeMagic {
                 * 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 ) ) {
+                       ( 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';
@@ -698,11 +697,11 @@ class MimeMagic {
                } 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";
+                       $script_type = "UTF-16LE";
                }
 
                if ( $script_type ) {
-                       if ( $script_type !== "UTF-8" && $script_type !== "ASCII") {
+                       if ( $script_type !== "UTF-8" && $script_type !== "ASCII" ) {
                                // Quick and dirty fold down to ASCII!
                                $pack = array( 'UTF-16BE' => 'n*', 'UTF-16LE' => 'v*' );
                                $chars = unpack( $pack[$script_type], substr( $head, 2 ) );
@@ -720,14 +719,14 @@ class MimeMagic {
 
                        if ( preg_match( '%/?([^\s]+/)(\w+)%', $head, $match ) ) {
                                $mime = "application/x-{$match[2]}";
-                               wfDebug( __METHOD__.": shell script recognized as $mime\n" );
+                               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" );
+                       wfDebug( __METHOD__ . ": ZIP header present in $file\n" );
                        return $this->detectZipType( $head, $tail, $ext );
                }
 
@@ -737,14 +736,14 @@ class MimeMagic {
 
                if( $gis && isset( $gis['mime'] ) ) {
                        $mime = $gis['mime'];
-                       wfDebug( __METHOD__.": getimagesize detected $file as $mime\n" );
+                       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" );
+                       wfDebug( __METHOD__ . ": detected $file as image/vnd.djvu\n" );
                        return 'image/vnd.djvu';
                }
 
@@ -766,7 +765,7 @@ class MimeMagic {
         */
        function detectZipType( $header, $tail = null, $ext = false ) {
                if( $ext ) { # TODO: remove $ext param
-                       wfDebug( __METHOD__.": WARNING: use of the \$ext parameter is deprecated. " .
+                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. " .
                                "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
                }
 
@@ -797,7 +796,7 @@ class MimeMagic {
 
                if ( preg_match( $opendocRegex, substr( $header, 30 ), $matches ) ) {
                        $mime = $matches[1];
-                       wfDebug( __METHOD__.": detected $mime from ZIP archive\n" );
+                       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
@@ -814,7 +813,7 @@ class MimeMagic {
                                        $mime = "application/zip";
                                }
                        }
-                       wfDebug( __METHOD__.": detected an Open Packaging Conventions archive: $mime\n" );
+                       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 ) ) ) {
@@ -843,9 +842,9 @@ class MimeMagic {
                                        break;
                        }
 
-                       wfDebug( __METHOD__.": detected a MS Office document with OPC trailer\n");
+                       wfDebug( __METHOD__ . ": detected a MS Office document with OPC trailer\n" );
                } else {
-                       wfDebug( __METHOD__.": unable to identify type of ZIP archive\n" );
+                       wfDebug( __METHOD__ . ": unable to identify type of ZIP archive\n" );
                }
                return $mime;
        }
@@ -872,7 +871,7 @@ class MimeMagic {
                global $wgMimeDetectorCommand;
 
                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" );
+                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
                }
 
                $m = null;
@@ -898,7 +897,7 @@ class MimeMagic {
                                $m = finfo_file( $mime_magic_resource, $file );
                                finfo_close( $mime_magic_resource );
                        } else {
-                               wfDebug( __METHOD__.": finfo_open failed on ".FILEINFO_MIME."!\n" );
+                               wfDebug( __METHOD__ . ": finfo_open failed on ".FILEINFO_MIME."!\n" );
                        }
                } elseif ( function_exists( "mime_content_type" ) ) {
 
@@ -911,9 +910,9 @@ class MimeMagic {
                        # Also note that this has been DEPRECATED in favor of the fileinfo extension by PECL, see above.
                        # see http://www.php.net/manual/en/ref.mime-magic.php for details.
 
-                       $m = mime_content_type($file);
+                       $m = mime_content_type( $file );
                } else {
-                       wfDebug( __METHOD__.": no magic mime detector found!\n" );
+                       wfDebug( __METHOD__ . ": no magic mime detector found!\n" );
                }
 
                if ( $m ) {
@@ -925,7 +924,7 @@ class MimeMagic {
                        if ( strpos( $m, 'unknown' ) !== false ) {
                                $m = null;
                        } else {
-                               wfDebug( __METHOD__.": magic mime type of $file: $m\n" );
+                               wfDebug( __METHOD__ . ": magic mime type of $file: $m\n" );
                                return $m;
                        }
                }
@@ -937,11 +936,11 @@ class MimeMagic {
                }
                if ( $ext ) {
                        if( $this->isRecognizableExtension( $ext ) ) {
-                               wfDebug( __METHOD__. ": refusing to guess mime type for .$ext file, we should have recognized it\n" );
+                               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" );
+                                       wfDebug( __METHOD__ . ": extension mime type of $file: $m\n" );
                                        return $m;
                                }
                        }
@@ -1066,7 +1065,7 @@ class MimeMagic {
 
                foreach ( $m as $mime ) {
                        foreach ( $this->mMediaTypes as $type => $codes ) {
-                               if ( in_array($mime, $codes, true ) ) {
+                               if ( in_array( $mime, $codes, true ) ) {
                                        return $type;
                                }
                        }
index 46af002..e35bf07 100644 (file)
@@ -67,7 +67,7 @@ class MWNamespace {
        public static function isMovable( $index ) {
                global $wgAllowImageMoving;
 
-               $result = !( $index < NS_MAIN || ( $index == NS_FILE && !$wgAllowImageMoving )  || $index == NS_CATEGORY );
+               $result = !( $index < NS_MAIN || ( $index == NS_FILE && !$wgAllowImageMoving ) || $index == NS_CATEGORY );
 
                /**
                 * @since 1.20
@@ -290,9 +290,9 @@ class MWNamespace {
         * @param $index Int: namespace index
         * @return bool
         */
-        public static function canTalk( $index ) {
+       public static function canTalk( $index ) {
                return $index >= NS_MAIN;
-        }
+       }
 
        /**
         * Does this namespace contain content, for the purposes of calculating
index 5b0f36c..f719421 100644 (file)
@@ -248,6 +248,11 @@ class OutputPage extends ContextSource {
         */
        private $mRedirectedFrom = null;
 
+       /**
+        * Additional key => value data
+        */
+       private $mProperties = array();
+
        /**
         * Constructor for OutputPage. This should not be called directly.
         * Instead a new RequestContext should be created and it will implicitly create
@@ -442,7 +447,7 @@ class OutputPage extends ContextSource {
        protected function filterModules( $modules, $position = null, $type = ResourceLoaderModule::TYPE_COMBINED ) {
                $resourceLoader = $this->getResourceLoader();
                $filteredModules = array();
-               foreach( $modules as $val ){
+               foreach( $modules as $val ) {
                        $module = $resourceLoader->getModule( $val );
                        if( $module instanceof ResourceLoaderModule
                                && $module->getOrigin() <= $this->getAllowedModules( $type )
@@ -512,7 +517,7 @@ class OutputPage extends ContextSource {
         * @return Array of module names
         */
        public function getModuleStyles( $filter = false, $position = null ) {
-               return $this->getModules( $filter,  $position, 'mModuleStyles' );
+               return $this->getModules( $filter, $position, 'mModuleStyles' );
        }
 
        /**
@@ -620,6 +625,32 @@ class OutputPage extends ContextSource {
                return $this->mArticleBodyOnly;
        }
 
+       /**
+        * Set an additional output property
+        * @since 1.21
+        *
+        * @param string $name
+        * @param mixed $value
+        */
+       public function setProperty( $name, $value ) {
+               $this->mProperties[$name] = $value;
+       }
+
+       /**
+        * Get an additional output property
+        * @since 1.21
+        *
+        * @param $name
+        * @return mixed: Property value or null if not found
+        */
+       public function getProperty( $name ) {
+               if ( isset( $this->mProperties[$name] ) ) {
+                       return $this->mProperties[$name];
+               } else {
+                       return null;
+               }
+       }
+
        /**
         * checkLastModified tells the client to use the client-cached page if
         * possible. If successful, the OutputPage is disabled so that
@@ -1251,7 +1282,7 @@ class OutputPage extends ContextSource {
         * @return Int ResourceLoaderModule ORIGIN_ class constant
         */
        public function getAllowedModules( $type ) {
-               if( $type == ResourceLoaderModule::TYPE_COMBINED ){
+               if( $type == ResourceLoaderModule::TYPE_COMBINED ) {
                        return min( array_values( $this->mAllowedModules ) );
                } else {
                        return isset( $this->mAllowedModules[$type] )
@@ -1275,7 +1306,7 @@ class OutputPage extends ContextSource {
         * @param  $level Int ResourceLoaderModule class constant
         */
        public function reduceAllowedModules( $type, $level ) {
-               $this->mAllowedModules[$type] = min( $this->getAllowedModules($type), $level );
+               $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level );
        }
 
        /**
@@ -1873,7 +1904,7 @@ class OutputPage extends ContextSource {
                                        wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **\n", false );
                                        # 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='.$wgSquidMaxage.'+'.$this->mSquidMaxage.', content="ESI/1.0"');
+                                       $response->header( 'Surrogate-Control: max-age=' . $wgSquidMaxage . '+' . $this->mSquidMaxage . ', 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
@@ -1883,7 +1914,7 @@ class OutputPage extends ContextSource {
                                        wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **\n", false );
                                        # start with a shorter timeout for initial testing
                                        # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
-                                       $response->header( 'Cache-Control: s-maxage='.$this->mSquidMaxage.', must-revalidate, max-age=0' );
+                                       $response->header( 'Cache-Control: s-maxage=' . $this->mSquidMaxage . ', must-revalidate, max-age=0' );
                                }
                        } else {
                                # We do want clients to cache if they can, but they *must* check for updates
@@ -1892,7 +1923,7 @@ class OutputPage extends ContextSource {
                                $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
                                $response->header( "Cache-Control: private, must-revalidate, max-age=0" );
                        }
-                       if($this->mLastModified) {
+                       if( $this->mLastModified ) {
                                $response->header( "Last-Modified: {$this->mLastModified}" );
                        }
                } else {
@@ -2071,7 +2102,7 @@ class OutputPage extends ContextSource {
 
                $this->prepareErrorPage( $title );
 
-               if ( $msg instanceof Message ){
+               if ( $msg instanceof Message ) {
                        $this->addHTML( $msg->parseAsBlock() );
                } else {
                        $this->addWikiMsgArray( $msg, $params );
@@ -2128,7 +2159,7 @@ class OutputPage extends ContextSource {
                                        unset( $returntoquery['title'] );
                                        unset( $returntoquery['returnto'] );
                                        unset( $returntoquery['returntoquery'] );
-                                       $query['returntoquery'] = wfArrayToCGI( $returntoquery );
+                                       $query['returntoquery'] = wfArrayToCgi( $returntoquery );
                                }
                        }
                        $loginLink = Linker::linkKnown(
@@ -2272,7 +2303,7 @@ class OutputPage extends ContextSource {
 
                        $pageLang = $this->getTitle()->getPageLanguage();
                        $params = array(
-                               'id'   => 'wpTextbox1',
+                               'id' => 'wpTextbox1',
                                'name' => 'wpTextbox1',
                                'cols' => $this->getUser()->getOption( 'cols' ),
                                'rows' => $this->getUser()->getOption( 'rows' ),
@@ -2483,7 +2514,7 @@ $templates
                        'mediawiki.page.startup',
                        'mediawiki.page.ready',
                ) );
-               if ( $wgIncludeLegacyJavaScript ){
+               if ( $wgIncludeLegacyJavaScript ) {
                        $this->addModules( 'mediawiki.legacy.wikibits' );
                }
 
@@ -2711,7 +2742,7 @@ $templates
                                }
                        }
 
-                       if( $group == 'noscript' ){
+                       if( $group == 'noscript' ) {
                                $links .= Html::rawElement( 'noscript', array(), $link ) . "\n";
                        } else {
                                $links .= $link . "\n";
@@ -2926,7 +2957,7 @@ $templates
         * DO NOT CALL THIS FROM OUTSIDE OF THIS CLASS OR Skin::makeGlobalVariablesScript().
         * This is only public until that function is removed. You have been warned.
         *
-        * Do not add things here which can be evaluated in ResourceLoaderStartupScript
+        * Do not add things here which can be evaluated in ResourceLoaderStartUpModule
         * - in other words, page-independent/site-wide variables (without state).
         * You will only be adding bloat to the html page and causing page caches to
         * have to be purged on configuration changes.
@@ -3066,7 +3097,7 @@ $templates
                                        'http-equiv' => 'Content-Type',
                                        'content' => "$wgMimeType; charset=UTF-8"
                                ) );
-                               $tags['meta-content-style-type'] = Html::element( 'meta', array(  // bug 15835
+                               $tags['meta-content-style-type'] = Html::element( 'meta', array( // bug 15835
                                        'http-equiv' => 'Content-Style-Type',
                                        'content' => 'text/css'
                                ) );
@@ -3095,7 +3126,7 @@ $templates
                        );
                        $tags['meta-keywords'] = Html::element( 'meta', array(
                                'name' => 'keywords',
-                               'content' =>  preg_replace(
+                               'content' => preg_replace(
                                        array_keys( $strip ),
                                        array_values( $strip ),
                                        implode( ',', $this->mKeywords )
@@ -3379,7 +3410,7 @@ $templates
                if ( $wgUseSiteCss ) {
                        $moduleStyles[] = 'site';
                        $moduleStyles[] = 'noscript';
-                       if( $this->getUser()->isLoggedIn() ){
+                       if( $this->getUser()->isLoggedIn() ) {
                                $moduleStyles[] = 'user.groups';
                        }
                }
@@ -3629,7 +3660,7 @@ $templates
                                                '1.20'
                                        );
                                }
-                       }  else {
+                       } else {
                                $args = array();
                                $name = $spec;
                        }
index 2aed2af..c60c107 100644 (file)
@@ -37,7 +37,7 @@
  * @note Since we can't rely on anything, the minimum PHP versions and MW current
  * version are hardcoded here
  */
-function wfPHPVersionError( $type ){
+function wfPHPVersionError( $type ) {
        $mwVersion = '1.21';
        $phpVersion = PHP_VERSION;
        $message = "MediaWiki $mwVersion requires at least PHP version 5.3.2, you are using PHP $phpVersion.";
index 077430d..9e937e4 100644 (file)
@@ -866,7 +866,7 @@ abstract class ReverseChronologicalPager extends IndexPager {
                if ( $this->mMonth ) {
                        $month = $this->mMonth + 1;
                        // For December, we want January 1 of the next year
-                       if ($month > 12) {
+                       if ( $month > 12 ) {
                                $month = 1;
                                $year++;
                        }
@@ -1160,7 +1160,7 @@ abstract class TablePager extends IndexPager {
                        # The pair is either $index => $limit, in which case the $value
                        # will be numeric, or $limit => $text, in which case the $value
                        # will be a string.
-                       if( is_int( $value ) ){
+                       if( is_int( $value ) ) {
                                $limit = $value;
                                $text = $this->getLanguage()->formatNum( $limit );
                        } else {
index 2dbc7ec..3be504a 100644 (file)
@@ -293,7 +293,7 @@ class PathRouter {
                        foreach ( $m as $matchKey => $matchValue ) {
                                if ( preg_match( '/^par\d+$/u', $matchKey ) ) {
                                        $n = intval( substr( $matchKey, 3 ) );
-                                       $data['$'.$n] = rawurldecode( $matchValue );
+                                       $data['$' . $n] = rawurldecode( $matchValue );
                                }
                        }
                        // If present give our $data array a $key as well
index 9878396..76e1760 100644 (file)
@@ -359,7 +359,7 @@ class Preferences {
                if ( $wgEnableEmail ) {
                        $helpMessages[] = $wgEmailConfirmToEdit
                                        ? 'prefs-help-email-required'
-                                       : 'prefs-help-email' ;
+                                       : 'prefs-help-email';
 
                        if( $wgEnableUserEmail ) {
                                // additional messages when users can send email to each other
@@ -891,7 +891,7 @@ class Preferences {
                        'max' => $watchlistdaysMax,
                        'section' => 'watchlist/displaywatchlist',
                        'help' => $context->msg( 'prefs-watchlist-days-max' )->numParams(
-                                                $watchlistdaysMax )->text(),
+                               $watchlistdaysMax )->text(),
                        'label-message' => 'prefs-watchlist-days',
                );
                $defaultPreferences['wllimit'] = array(
@@ -1407,7 +1407,7 @@ class Preferences {
                # via $wgHiddenPrefs, we don't want to destroy that setting in case the preference
                # is subsequently re-enabled
                # TODO: maintenance script to actually delete these
-               foreach( $wgHiddenPrefs as $pref ){
+               foreach( $wgHiddenPrefs as $pref ) {
                        # If the user has not set a non-default value here, the default will be returned
                        # and subsequently discarded
                        $formData[$pref] = $user->getOption( $pref, null, true );
index 5d4b35c..7df6a50 100644 (file)
@@ -45,7 +45,7 @@ class PrefixSearch {
                // Find a Title which is not an interwiki and is in NS_MAIN
                $title = Title::newFromText( $search );
                if( $title && $title->getInterwiki() == '' ) {
-                       $ns = array($title->getNamespace());
+                       $ns = array( $title->getNamespace() );
                        if( $ns[0] == NS_MAIN ) {
                                $ns = $namespaces; // no explicit prefix, use default namespaces
                        }
index fe871b9..17e4372 100644 (file)
@@ -139,7 +139,7 @@ class ProtectionForm {
                                        if( !$wgUser->isAllowedAny( 'protect', 'editprotected' ) )
                                                continue;
                                } else {
-                                       if( !$wgUser->isAllowed($val) )
+                                       if( !$wgUser->isAllowed( $val ) )
                                                continue;
                                }
                                $this->mRestrictions[$action] = $val;
@@ -228,14 +228,14 @@ class ProtectionForm {
                }
 
                list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
-               if ( $cascadeSources && count($cascadeSources) > 0 ) {
+               if ( $cascadeSources && count( $cascadeSources ) > 0 ) {
                        $titles = '';
 
                        foreach ( $cascadeSources as $title ) {
                                $titles .= '* [[:' . $title->getPrefixedText() . "]]\n";
                        }
 
-                       $wgOut->wrapWikiMsg( "<div id=\"mw-protect-cascadeon\">\n$1\n" . $titles . "</div>", array( 'protect-cascadeon', count($cascadeSources) ) );
+                       $wgOut->wrapWikiMsg( "<div id=\"mw-protect-cascadeon\">\n$1\n" . $titles . "</div>", array( 'protect-cascadeon', count( $cascadeSources ) ) );
                }
 
                # Show an appropriate message if the user isn't allowed or able to change
@@ -284,7 +284,7 @@ class ProtectionForm {
                $expiry = array();
                foreach( $this->mApplicableTypes as $action ) {
                        $expiry[$action] = $this->getExpiry( $action );
-                       if( empty($this->mRestrictions[$action]) )
+                       if( empty( $this->mRestrictions[$action] ) )
                                continue; // unprotected
                        if ( !$expiry[$action] ) {
                                $this->show( array( 'protect_expiry_invalid' ) );
@@ -300,7 +300,7 @@ class ProtectionForm {
                #  to a semi-protected page.
                $edit_restriction = isset( $this->mRestrictions['edit'] ) ? $this->mRestrictions['edit'] : '';
                $this->mCascade = $wgRequest->getBool( 'mwProtect-cascade' );
-               if ($this->mCascade && ($edit_restriction != 'protect') &&
+               if ( $this->mCascade && ($edit_restriction != 'protect') &&
                        !User::groupHasPermission( $edit_restriction, 'protect' ) )
                        $this->mCascade = false;
 
@@ -412,14 +412,14 @@ class ProtectionForm {
                                wfMessage( 'protect-othertime-op' )->text(),
                                "othertime"
                        ) . "\n";
-                       foreach( explode(',', $scExpiryOptions) as $option ) {
-                               if ( strpos($option, ":") === false ) {
+                       foreach( explode( ',', $scExpiryOptions ) as $option ) {
+                               if ( strpos( $option, ":" ) === false ) {
                                        $show = $value = $option;
                                } else {
-                                       list($show, $value) = explode(":", $option);
+                                       list( $show, $value ) = explode( ":", $option );
                                }
-                               $show = htmlspecialchars($show);
-                               $value = htmlspecialchars($value);
+                               $show = htmlspecialchars( $show );
+                               $value = htmlspecialchars( $value );
                                $expiryFormOptions .= Xml::option( $show, $value, $this->mExpirySelection[$action] === $value ) . "\n";
                        }
                        # Add expiry dropdown
@@ -458,7 +458,7 @@ class ProtectionForm {
                        "</td></tr>";
                }
                # Give extensions a chance to add items to the form
-               wfRunHooks( 'ProtectionForm::buildForm', array($this->mArticle,&$out) );
+               wfRunHooks( 'ProtectionForm::buildForm', array( $this->mArticle, &$out ) );
 
                $out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
 
@@ -569,7 +569,7 @@ class ProtectionForm {
                                if( !$wgUser->isAllowedAny( 'protect', 'editprotected' ) && !$this->disabled )
                                        continue;
                        } else {
-                               if( !$wgUser->isAllowed($key) && !$this->disabled )
+                               if( !$wgUser->isAllowed( $key ) && !$this->disabled )
                                        continue;
                        }
                        $levels[] = $key;
@@ -644,6 +644,6 @@ class ProtectionForm {
                $out->addHTML( Xml::element( 'h2', null, $protectLogPage->getName()->text() ) );
                LogEventsList::showLogExtract( $out, 'protect', $this->mTitle );
                # Let extensions add other relevant log extracts
-               wfRunHooks( 'ProtectionForm::showLogExtract', array($this->mArticle,$out) );
+               wfRunHooks( 'ProtectionForm::showLogExtract', array( $this->mArticle, $out ) );
        }
 }
index 349789f..1a147b1 100644 (file)
@@ -109,7 +109,7 @@ function wfProxyCheck() {
        if ( !$skip ) {
                $title = SpecialPage::getTitleFor( 'Blockme' );
                $iphash = md5( $ip . $wgProxyKey );
-               $url = wfExpandUrl( $title->getFullURL( 'ip='.$iphash ), PROTO_HTTP );
+               $url = wfExpandUrl( $title->getFullURL( 'ip=' . $iphash ), PROTO_HTTP );
 
                foreach ( $wgProxyPorts as $port ) {
                        $params = implode( ' ', array(
index 56df21e..f63e95c 100644 (file)
@@ -80,7 +80,7 @@ class RecentChange {
         * @var Title
         */
        var $mMovedToTitle = false;
-       var $numberofWatchingusers = 0 ; # Dummy to prevent error message in SpecialRecentchangeslinked
+       var $numberofWatchingusers = 0; # Dummy to prevent error message in SpecialRecentchangeslinked
        var $notificationtimestamp;
 
        # Factory methods
@@ -712,7 +712,7 @@ class RecentChange {
                        $trail = "curid=" . (int)( $this->mAttribs['rc_cur_id'] ) .
                                "&oldid=" . (int)( $this->mAttribs['rc_last_oldid'] );
                        if ( $forceCur ) {
-                               $trail .= '&diff=0' ;
+                               $trail .= '&diff=0';
                        } else {
                                $trail .= '&diff=' . (int)( $this->mAttribs['rc_this_oldid'] );
                        }
@@ -761,10 +761,10 @@ class RecentChange {
                        if ( $szdiff < -500 ) {
                                $szdiff = "\002$szdiff\002";
                        } elseif ( $szdiff >= 0 ) {
-                               $szdiff = '+' . $szdiff ;
+                               $szdiff = '+' . $szdiff;
                        }
                        // @todo i18n with parentheses in content language?
-                       $szdiff = '(' . $szdiff . ')' ;
+                       $szdiff = '(' . $szdiff . ')';
                } else {
                        $szdiff = '';
                }
@@ -800,7 +800,7 @@ class RecentChange {
                # see http://www.irssi.org/documentation/formats for some colour codes. prefix is \003,
                # no colour (\003) switches back to the term default
                $fullString = "$titleString\0034 $flag\00310 " .
-                                         "\00302$url\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n";
+                       "\00302$url\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n";
 
                return $fullString;
        }
index 5f62e4d..4bdce87 100644 (file)
@@ -254,9 +254,11 @@ class Revision implements IDBAccessObject {
                        $matchId = 'page_latest';
                }
                return self::loadFromConds( $db,
-                       array( "rev_id=$matchId",
-                                  'page_namespace' => $title->getNamespace(),
-                                  'page_title'     => $title->getDBkey() )
+                       array(
+                               "rev_id=$matchId",
+                               'page_namespace' => $title->getNamespace(),
+                               'page_title'     => $title->getDBkey()
+                       )
                );
        }
 
@@ -272,9 +274,11 @@ class Revision implements IDBAccessObject {
         */
        public static function loadFromTimestamp( $db, $title, $timestamp ) {
                return self::loadFromConds( $db,
-                       array( 'rev_timestamp'  => $db->timestamp( $timestamp ),
-                                  'page_namespace' => $title->getNamespace(),
-                                  'page_title'     => $title->getDBkey() )
+                       array(
+                               'rev_timestamp'  => $db->timestamp( $timestamp ),
+                               'page_namespace' => $title->getNamespace(),
+                               'page_title'     => $title->getDBkey()
+                       )
                );
        }
 
@@ -330,9 +334,11 @@ class Revision implements IDBAccessObject {
        public static function fetchRevision( $title ) {
                return self::fetchFromConds(
                        wfGetDB( DB_SLAVE ),
-                       array( 'rev_id=page_latest',
-                                  'page_namespace' => $title->getNamespace(),
-                                  'page_title'     => $title->getDBkey() )
+                       array(
+                               'rev_id=page_latest',
+                               'page_namespace' => $title->getNamespace(),
+                               'page_title'     => $title->getDBkey()
+                       )
                );
        }
 
@@ -496,7 +502,7 @@ class Revision implements IDBAccessObject {
                        if ( !isset( $row->rev_parent_id ) ) {
                                $this->mParentId = null;
                        } else {
-                               $this->mParentId  = intval( $row->rev_parent_id );
+                               $this->mParentId = intval( $row->rev_parent_id );
                        }
 
                        if ( !isset( $row->rev_len ) ) {
@@ -532,7 +538,7 @@ class Revision implements IDBAccessObject {
                        }
 
                        // Lazy extraction...
-                       $this->mText      = null;
+                       $this->mText = null;
                        if( isset( $row->old_text ) ) {
                                $this->mTextRow = $row;
                        } else {
@@ -557,8 +563,8 @@ class Revision implements IDBAccessObject {
                        if ( !empty( $row['content'] ) ) {
                                //@todo: when is that set? test with external store setup! check out insertOn() [dk]
                                if ( !empty( $row['text_id'] ) ) {
-                                       throw new MWException( "Text already stored in external store (id {$row['text_id']}), "
-                                                                                       . "can't serialize content object" );
+                                       throw new MWException( "Text already stored in external store (id {$row['text_id']}), " .
+                                               "can't serialize content object" );
                                }
 
                                $row['content_model'] = $row['content']->getModel();
@@ -615,12 +621,12 @@ class Revision implements IDBAccessObject {
                                } elseif ( $this->mTitle->getArticleID() !== $this->mPage ) {
                                        // Got different page IDs. This may be legit (e.g. during undeletion),
                                        // but it seems worth mentioning it in the log.
-                                       wfDebug( "Page ID " . $this->mPage . " mismatches the ID "
-                                                       . $this->mTitle->getArticleID() . " provided by the Title object." );
+                                       wfDebug( "Page ID " . $this->mPage . " mismatches the ID " .
+                                               $this->mTitle->getArticleID() . " provided by the Title object." );
                                }
                        }
 
-                       $this->mCurrent   = false;
+                       $this->mCurrent = false;
 
                        // If we still have no length, see it we have the text to figure it out
                        if ( !$this->mSize ) {
@@ -718,7 +724,7 @@ class Revision implements IDBAccessObject {
                                array( 'page', 'revision' ),
                                self::selectPageFields(),
                                array( 'page_id=rev_page',
-                                          'rev_id' => $this->mId ),
+                                       'rev_id' => $this->mId ),
                                __METHOD__ );
                        if ( $row ) {
                                $this->mTitle = Title::newFromRow( $row );
index 0034afe..ff79c59 100644 (file)
@@ -381,7 +381,7 @@ class Sanitizer {
                                'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's',
                                'strike', 'strong', 'tt', 'var', 'div', 'center',
                                'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
-                               'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'abbr', 'dfn',
+                               'ruby', 'rt', 'rb', 'rp', 'p', 'span', 'abbr', 'dfn',
                                'kbd', 'samp'
                        );
                        if ( $wgHtml5 ) {
@@ -431,7 +431,7 @@ class Sanitizer {
                $extratags = array_flip( $extratags );
                $removetags = array_flip( $removetags );
                $htmlpairs = array_merge( $extratags, $htmlpairsStatic );
-               $htmlelements = array_diff_key( array_merge( $extratags, $htmlelementsStatic ) , $removetags );
+               $htmlelements = array_diff_key( array_merge( $extratags, $htmlelementsStatic ), $removetags );
 
                # Remove HTML comments
                $text = Sanitizer::removeHTMLcomments( $text );
@@ -604,9 +604,9 @@ class Sanitizer {
         */
        static function removeHTMLcomments( $text ) {
                wfProfileIn( __METHOD__ );
-               while (($start = strpos($text, '<!--')) !== false) {
-                       $end = strpos($text, '-->', $start + 4);
-                       if ($end === false) {
+               while ( ($start = strpos( $text, '<!--' ) ) !== false ) {
+                       $end = strpos( $text, '-->', $start + 4 );
+                       if ( $end === false ) {
                                # Unterminated comment; bail out
                                break;
                        }
@@ -615,22 +615,22 @@ class Sanitizer {
 
                        # Trim space and newline if the comment is both
                        # preceded and followed by a newline
-                       $spaceStart = max($start - 1, 0);
+                       $spaceStart = max( $start - 1, 0 );
                        $spaceLen = $end - $spaceStart;
-                       while (substr($text, $spaceStart, 1) === ' ' && $spaceStart > 0) {
+                       while ( substr( $text, $spaceStart, 1 ) === ' ' && $spaceStart > 0 ) {
                                $spaceStart--;
                                $spaceLen++;
                        }
-                       while (substr($text, $spaceStart + $spaceLen, 1) === ' ')
+                       while ( substr( $text, $spaceStart + $spaceLen, 1 ) === ' ' )
                                $spaceLen++;
-                       if (substr($text, $spaceStart, 1) === "\n" and substr($text, $spaceStart + $spaceLen, 1) === "\n") {
+                       if ( substr( $text, $spaceStart, 1 ) === "\n" and substr( $text, $spaceStart + $spaceLen, 1 ) === "\n" ) {
                                # Remove the comment, leading and trailing
                                # spaces, and leave only one newline.
-                               $text = substr_replace($text, "\n", $spaceStart, $spaceLen + 1);
+                               $text = substr_replace( $text, "\n", $spaceStart, $spaceLen + 1 );
                        }
                        else {
                                # Remove just the comment.
-                               $text = substr_replace($text, '', $start, $end - $start);
+                               $text = substr_replace( $text, '', $start, $end - $start );
                        }
                }
                wfProfileOut( __METHOD__ );
@@ -647,6 +647,7 @@ class Sanitizer {
         *
         * @param $params
         * @param $element
+        * @return bool
         */
        static function validateTag( $params, $element ) {
                $params = Sanitizer::decodeTagAttributes( $params );
@@ -736,6 +737,16 @@ class Sanitizer {
                                $value = Sanitizer::escapeId( $value, 'noninitial' );
                        }
 
+                       # WAI-ARIA
+                       # http://www.w3.org/TR/wai-aria/
+                       # http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#wai-aria
+                       # For now we only support role="presentation" until we work out what roles should be
+                       # usable by content and we ensure that our code explicitly rejects patterns that
+                       # violate HTML5's ARIA restrictions.
+                       if ( $attribute === 'role' && $value !== 'presentation' ) {
+                               continue;
+                       }
+
                        //RDFa and microdata properties allow URLs, URIs and/or CURIs. check them for sanity
                        if ( $attribute === 'rel' || $attribute === 'rev' ||
                                $attribute === 'about' || $attribute === 'property' || $attribute === 'resource' || #RDFa
@@ -1039,7 +1050,7 @@ class Sanitizer {
                $id = str_replace( array_keys( $replace ), array_values( $replace ), $id );
 
                if ( !preg_match( '/^[a-zA-Z]/', $id )
-               && !in_array( 'noninitial', $options ) )  {
+               && !in_array( 'noninitial', $options ) ) {
                        // Initial character must be a letter!
                        $id = "x$id";
                }
@@ -1059,10 +1070,10 @@ class Sanitizer {
         */
        static function escapeClass( $class ) {
                // Convert ugly stuff to underscores and kill underscores in ugly places
-               return rtrim(preg_replace(
-                       array('/(^[0-9\\-])|[\\x00-\\x20!"#$%&\'()*+,.\\/:;<=>?@[\\]^`{|}~]|\\xC2\\xA0/','/_+/'),
+               return rtrim( preg_replace(
+                       array( '/(^[0-9\\-])|[\\x00-\\x20!"#$%&\'()*+,.\\/:;<=>?@[\\]^`{|}~]|\\xC2\\xA0/', '/_+/' ),
                        '_',
-                       $class ), '_');
+                       $class ), '_' );
        }
 
        /**
@@ -1227,7 +1238,7 @@ class Sanitizer {
                        $ret = Sanitizer::normalizeEntity( $matches[1] );
                } elseif( $matches[2] != '' ) {
                        $ret = Sanitizer::decCharReference( $matches[2] );
-               } elseif( $matches[3] != ''  ) {
+               } elseif( $matches[3] != '' ) {
                        $ret = Sanitizer::hexCharReference( $matches[3] );
                }
                if( is_null( $ret ) ) {
@@ -1347,7 +1358,7 @@ class Sanitizer {
                        return Sanitizer::decodeEntity( $matches[1] );
                } elseif( $matches[2] != '' ) {
                        return  Sanitizer::decodeChar( intval( $matches[2] ) );
-               } elseif( $matches[3] != ''  ) {
+               } elseif( $matches[3] != '' ) {
                        return  Sanitizer::decodeChar( hexdec( $matches[3] ) );
                }
                # Last case should be an ampersand by itself
@@ -1416,7 +1427,18 @@ class Sanitizer {
                        return $whitelist;
                }
 
-               $common = array( 'id', 'class', 'lang', 'dir', 'title', 'style' );
+               $common = array(
+                       # HTML
+                       'id',
+                       'class',
+                       'style',
+                       'lang',
+                       'dir',
+                       'title',
+
+                       # WAI-ARIA
+                       'role',
+               );
 
                if ( $wgAllowRdfaAttributes ) {
                        #RDFa attributes as specified in section 9 of http://www.w3.org/TR/2008/REC-rdfa-syntax-20081014
@@ -1736,8 +1758,8 @@ class Sanitizer {
                // Please note strings below are enclosed in brackets [], this make the
                // hyphen "-" a range indicator. Hence it is double backslashed below.
                // See bug 26948
-               $rfc5322_atext   = "a-z0-9!#$%&'*+\\-\/=?^_`{|}~" ;
-               $rfc1034_ldh_str = "a-z0-9\\-" ;
+               $rfc5322_atext   = "a-z0-9!#$%&'*+\\-\/=?^_`{|}~";
+               $rfc1034_ldh_str = "a-z0-9\\-";
 
                $HTML5_email_regexp = "/
                ^                      # start of string
@@ -1746,7 +1768,7 @@ class Sanitizer {
                [$rfc1034_ldh_str]+       # First domain part
                (\\.[$rfc1034_ldh_str]+)*  # Following part prefixed with a dot
                $                      # End of string
-               /ix" ; // case Insensitive, eXtended
+               /ix"; // case Insensitive, eXtended
 
                return (bool) preg_match( $HTML5_email_regexp, $addr );
        }
index f6c8245..0853df1 100644 (file)
@@ -50,22 +50,22 @@ if ( $wgLoadScript === false ) $wgLoadScript = "$wgScriptPath/load$wgScriptExten
 
 if ( $wgArticlePath === false ) {
        if ( $wgUsePathInfo ) {
-               $wgArticlePath      = "$wgScript/$1";
+               $wgArticlePath = "$wgScript/$1";
        } else {
-               $wgArticlePath      = "$wgScript?title=$1";
+               $wgArticlePath = "$wgScript?title=$1";
        }
 }
 
-if ( !empty($wgActionPaths) && !isset($wgActionPaths['view']) ) {
+if ( !empty( $wgActionPaths ) && !isset( $wgActionPaths['view'] ) ) {
        # 'view' is assumed the default action path everywhere in the code
        # but is rarely filled in $wgActionPaths
        $wgActionPaths['view'] = $wgArticlePath;
 }
 
-if ( !empty($wgActionPaths) && !isset($wgActionPaths['view']) ) {
+if ( !empty( $wgActionPaths ) && !isset( $wgActionPaths['view'] ) ) {
        # 'view' is assumed the default action path everywhere in the code
        # but is rarely filled in $wgActionPaths
-       $wgActionPaths['view'] = $wgArticlePath ;
+       $wgActionPaths['view'] = $wgArticlePath;
 }
 
 if ( $wgStylePath === false ) $wgStylePath = "$wgScriptPath/skins";
@@ -323,7 +323,7 @@ if ( !$wgEnotifMinorEdits ) {
 }
 
 # $wgDisabledActions is deprecated as of 1.18
-foreach( $wgDisabledActions as $action ){
+foreach( $wgDisabledActions as $action ) {
        $wgActions[$action] = false;
 }
 
@@ -337,7 +337,7 @@ if ( !$wgHtml5Version && $wgHtml5 && $wgAllowRdfaAttributes ) {
 }
 
 # Blacklisted file extensions shouldn't appear on the "allowed" list
-$wgFileExtensions = array_diff ( $wgFileExtensions, $wgFileBlacklist );
+$wgFileExtensions = array_values( array_diff ( $wgFileExtensions, $wgFileBlacklist ) );
 
 if ( $wgArticleCountMethod === null ) {
        $wgArticleCountMethod = $wgUseCommaCount ? 'comma' : 'link';
@@ -353,12 +353,13 @@ if ( $wgAjaxUploadDestCheck ) {
 
 if ( $wgNewUserLog ) {
        # Add a new log type
-       $wgLogTypes[]                        = 'newusers';
-       $wgLogNames['newusers']              = 'newuserlogpage';
-       $wgLogHeaders['newusers']            = 'newuserlogpagetext';
+       $wgLogTypes[] = 'newusers';
+       $wgLogNames['newusers'] = 'newuserlogpage';
+       $wgLogHeaders['newusers'] = 'newuserlogpagetext';
        $wgLogActionsHandlers['newusers/newusers'] = 'NewUsersLogFormatter';
        $wgLogActionsHandlers['newusers/create'] = 'NewUsersLogFormatter';
        $wgLogActionsHandlers['newusers/create2'] = 'NewUsersLogFormatter';
+       $wgLogActionsHandlers['newusers/byemail'] = 'NewUsersLogFormatter';
        $wgLogActionsHandlers['newusers/autocreate'] = 'NewUsersLogFormatter';
 }
 
index afe0cc7..11d7fd6 100644 (file)
@@ -83,7 +83,7 @@
  * $conf->settings = array(
  *     'wgMergeSetting' = array(
  *             # Value that will be shared among all wikis:
- *             'default' => array(  NS_USER => true ),
+ *             'default' => array( NS_USER => true ),
  *
  *             # Leading '+' means merging the array of value with the defaults
  *             '+beta' => array( NS_HELP => true ),
@@ -161,6 +161,12 @@ class SiteConfiguration {
         */
        public $siteParamsCallback = null;
 
+       /**
+        * Configuration cache for getConfig()
+        * @var array
+        */
+       protected $cfgCache = array();
+
        /**
         * Retrieves a configuration setting for a given wiki.
         * @param $settingName String ID of the setting name to retrieve
@@ -205,7 +211,7 @@ class SiteConfiguration {
                                                        $retval = $thisSetting[$tag];
                                                }
                                                break 2;
-                                       } elseif( array_key_exists( "+$tag", $thisSetting ) && is_array($thisSetting["+$tag"]) ) {
+                                       } elseif( array_key_exists( "+$tag", $thisSetting ) && is_array( $thisSetting["+$tag"] ) ) {
                                                if( !isset( $retval ) ) {
                                                        $retval = array();
                                                }
@@ -216,7 +222,7 @@ class SiteConfiguration {
                                $suffix = $params['suffix'];
                                if( !is_null( $suffix ) ) {
                                        if( array_key_exists( $suffix, $thisSetting ) ) {
-                                               if ( isset($retval) && is_array($retval) && is_array($thisSetting[$suffix]) ) {
+                                               if ( isset( $retval ) && is_array( $retval ) && is_array( $thisSetting[$suffix] ) ) {
                                                        $retval = self::arrayMerge( $retval, $thisSetting[$suffix] );
                                                } else {
                                                        $retval = $thisSetting[$suffix];
@@ -360,9 +366,9 @@ class SiteConfiguration {
        public function extractGlobalSetting( $setting, $wiki, $params ) {
                $value = $this->getSetting( $setting, $wiki, $params );
                if ( !is_null( $value ) ) {
-                       if (substr($setting,0,1) == '+' && is_array($value)) {
-                               $setting = substr($setting,1);
-                               if ( is_array($GLOBALS[$setting]) ) {
+                       if ( substr( $setting, 0, 1 ) == '+' && is_array( $value ) ) {
+                               $setting = substr( $setting, 1 );
+                               if ( is_array( $GLOBALS[$setting] ) ) {
                                        $GLOBALS[$setting] = self::arrayMerge( $GLOBALS[$setting], $value );
                                } else {
                                        $GLOBALS[$setting] = $value;
@@ -413,7 +419,7 @@ class SiteConfiguration {
                        return $default;
                }
 
-               foreach( $default as $name => $def ){
+               foreach( $default as $name => $def ) {
                        if( !isset( $ret[$name] ) || ( is_array( $default[$name] ) && !is_array( $ret[$name] ) ) ) {
                                $ret[$name] = $default[$name];
                        }
@@ -446,7 +452,7 @@ class SiteConfiguration {
                $ret['params'] += $params;
 
                // Automatically fill that ones if needed
-               if( !isset( $ret['params']['lang'] ) && !is_null( $ret['lang'] ) ){
+               if( !isset( $ret['params']['lang'] ) && !is_null( $ret['lang'] ) ) {
                        $ret['params']['lang'] = $ret['lang'];
                }
                if( !isset( $ret['params']['site'] ) && !is_null( $ret['suffix'] ) ) {
@@ -486,6 +492,67 @@ class SiteConfiguration {
                return array( $site, $lang );
        }
 
+       /**
+        * Get the resolved (post-setup) configuration of a potentially foreign wiki.
+        * For foreign wikis, this is expensive, and only works if maintenance
+        * scripts are setup to handle the --wiki parameter such as in wiki farms.
+        *
+        * @param string $wiki
+        * @param array|string $settings A setting name or array of setting names
+        * @return Array|mixed Array if $settings is an array, otherwise the value
+        * @throws MWException
+        * @since 1.21
+        */
+       public function getConfig( $wiki, $settings ) {
+               global $IP;
+
+               $multi = is_array( $settings );
+               $settings = (array)$settings;
+               if ( $wiki === wfWikiID() ) { // $wiki is this wiki
+                       $res = array();
+                       foreach ( $settings as $name ) {
+                               if ( !preg_match( '/^wg[A-Z]/', $name ) ) {
+                                       throw new MWException( "Variable '$name' does start with 'wg'." );
+                               } elseif ( !isset( $GLOBALS[$name] ) ) {
+                                       throw new MWException( "Variable '$name' is not set." );
+                               }
+                               $res[$name] = $GLOBALS[$name];
+                       }
+               } else { // $wiki is a foreign wiki
+                       if ( isset( $this->cfgCache[$wiki] ) ) {
+                               $res = array_intersect_key( $this->cfgCache[$wiki], array_flip( $settings ) );
+                               if ( count( $res ) == count( $settings ) ) {
+                                       return $res; // cache hit
+                               }
+                       } elseif ( !in_array( $wiki, $this->wikis ) ) {
+                               throw new MWException( "No such wiki '$wiki'." );
+                       } else {
+                               $this->cfgCache[$wiki] = array();
+                       }
+                       $retVal = 1;
+                       $cmd = wfShellWikiCmd(
+                               "$IP/maintenance/getConfiguration.php",
+                               array(
+                                       '--wiki', $wiki,
+                                       '--settings', implode( ' ', $settings ),
+                                       '--format', 'PHP'
+                               )
+                       );
+                       // ulimit5.sh breaks this call
+                       $data = trim( wfShellExec( $cmd, $retVal, array(), array( 'memory' => 0 ) ) );
+                       if ( $retVal != 0 || !strlen( $data ) ) {
+                               throw new MWException( "Failed to run getConfiguration.php." );
+                       }
+                       $res = unserialize( $data );
+                       if ( !is_array( $res ) ) {
+                               throw new MWException( "Failed to unserialize configuration array." );
+                       }
+                       $this->cfgCache[$wiki] = $this->cfgCache[$wiki] + $res;
+               }
+
+               return $multi ? $res : current( $res );
+       }
+
        /**
         * Returns true if the given vhost is handled locally.
         * @param $vhost String
@@ -509,9 +576,9 @@ class SiteConfiguration {
                $out = $array1;
                for( $i = 1; $i < func_num_args(); $i++ ) {
                        foreach( func_get_arg( $i ) as $key => $value ) {
-                               if ( isset($out[$key]) && is_array($out[$key]) && is_array($value) ) {
+                               if ( isset( $out[$key] ) && is_array( $out[$key] ) && is_array( $value ) ) {
                                        $out[$key] = self::arrayMerge( $out[$key], $value );
-                               } elseif ( !isset($out[$key]) || !$out[$key] && !is_numeric($key) ) {
+                               } elseif ( !isset( $out[$key] ) || !$out[$key] && !is_numeric( $key ) ) {
                                        // Values that evaluate to true given precedence, for the primary purpose of merging permissions arrays.
                                        $out[$key] = $value;
                                } elseif ( is_numeric( $key ) ) {
index 01841b6..addaddd 100644 (file)
@@ -294,8 +294,6 @@ class SiteStatsUpdate implements DeferrableUpdate {
                        $this->doUpdatePendingDeltas();
                } else {
                        $dbw = wfGetDB( DB_MASTER );
-                       // Need a separate transaction because this a global lock
-                       $dbw->begin( __METHOD__ );
 
                        $lockKey = wfMemcKey( 'site_stats' ); // prepend wiki ID
                        if ( $rate ) {
@@ -316,6 +314,9 @@ class SiteStatsUpdate implements DeferrableUpdate {
                                $this->images   += ( $pd['ss_images']['+'] - $pd['ss_images']['-'] );
                        }
 
+                       // Need a separate transaction because this a global lock
+                       $dbw->begin( __METHOD__ );
+
                        // Build up an SQL query of deltas and apply them...
                        $updates = '';
                        $this->appendUpdate( $updates, 'ss_total_views', $this->views );
index 4889863..723ede4 100644 (file)
@@ -262,7 +262,7 @@ abstract class Skin extends ContextSource {
         * @return Title
         */
        public function getRelevantTitle() {
-               if ( isset($this->mRelevantTitle) ) {
+               if ( isset( $this->mRelevantTitle ) ) {
                        return $this->mRelevantTitle;
                }
                return $this->getTitle();
@@ -286,7 +286,7 @@ abstract class Skin extends ContextSource {
         * @return User
         */
        public function getRelevantUser() {
-               if ( isset($this->mRelevantUser) ) {
+               if ( isset( $this->mRelevantUser ) ) {
                        return $this->mRelevantUser;
                }
                $title = $this->getRelevantTitle();
@@ -435,7 +435,7 @@ abstract class Skin extends ContextSource {
                $colon = $this->msg( 'colon-separator' )->escaped();
 
                if ( !empty( $allCats['normal'] ) ) {
-                       $t = $embed . implode( "{$pop}{$embed}" , $allCats['normal'] ) . $pop;
+                       $t = $embed . implode( "{$pop}{$embed}", $allCats['normal'] ) . $pop;
 
                        $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
                        $linkPage = wfMessage( 'pagecategorieslink' )->inContentLanguage()->text();
@@ -456,7 +456,7 @@ abstract class Skin extends ContextSource {
 
                        $s .= "<div id=\"mw-hidden-catlinks\" class=\"mw-hidden-catlinks$class\">" .
                                $this->msg( 'hidden-categories' )->numParams( count( $allCats['hidden'] ) )->escaped() .
-                               $colon . '<ul>' . $embed . implode( "{$pop}{$embed}" , $allCats['hidden'] ) . $pop . '</ul>' .
+                               $colon . '<ul>' . $embed . implode( "{$pop}{$embed}", $allCats['hidden'] ) . $pop . '</ul>' .
                                '</div>';
                }
 
@@ -499,7 +499,7 @@ abstract class Skin extends ContextSource {
 
                        # add our current element to the list
                        $eltitle = Title::newFromText( $element );
-                       $return .=  Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
+                       $return .= Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
                }
 
                return $return;
@@ -860,7 +860,7 @@ abstract class Skin extends ContextSource {
                if ( is_string( $icon ) ) {
                        $html = $icon;
                } else { // Assuming array
-                       $url = isset($icon["url"]) ? $icon["url"] : null;
+                       $url = isset( $icon["url"] ) ? $icon["url"] : null;
                        unset( $icon["url"] );
                        if ( isset( $icon["src"] ) && $withImage === 'withImage' ) {
                                $html = Html::element( 'img', $icon ); // do this the lazy way, just pass icon data as an attribute array
index 90cd131..c1c7219 100644 (file)
@@ -120,7 +120,7 @@ class LegacyTemplate extends BaseTemplate {
                }
 
                $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
-                 "<table cellspacing='0' style='width: 100%;'>\n<tr>\n";
+                       "<table cellspacing='0' style='width: 100%;'>\n<tr>\n";
 
                if ( $this->getSkin()->qbSetting() == 0 ) {
                        $s .= "<td class='top' style='text-align: left; vertical-align: top;' rowspan='{$rows}'>\n" .
@@ -179,10 +179,10 @@ class LegacyTemplate extends BaseTemplate {
                $search = $wgRequest->getText( 'search' );
 
                $s = '<form id="searchform' . $this->searchboxes . '" name="search" class="inline" method="post" action="'
-                 . $this->getSkin()->escapeSearchLink() . "\">\n"
-                 . '<input type="text" id="searchInput' . $this->searchboxes . '" name="search" size="19" value="'
-                 . htmlspecialchars( substr( $search, 0, 256 ) ) . "\" />\n"
-                 . '<input type="submit" name="go" value="' . wfMessage( 'searcharticle' )->text() . '" />';
+                       . $this->getSkin()->escapeSearchLink() . "\">\n"
+                       . '<input type="text" id="searchInput' . $this->searchboxes . '" name="search" size="19" value="'
+                       . htmlspecialchars( substr( $search, 0, 256 ) ) . "\" />\n"
+                       . '<input type="submit" name="go" value="' . wfMessage( 'searcharticle' )->text() . '" />';
 
                if ( $wgUseTwoButtonsSearchForm ) {
                        $s .= '&#160;<input type="submit" name="fulltext" value="' . wfMessage( 'searchbutton' )->text() . "\" />\n";
@@ -253,7 +253,7 @@ class LegacyTemplate extends BaseTemplate {
                $lang = $title->getPageLanguage();
                $variants = $lang->getVariants();
 
-               if ( !$wgDisableLangConversion && sizeof( $variants ) > 1
+               if ( !$wgDisableLangConversion && count( $variants ) > 1
                        && !$title->isSpecialPage() ) {
                        foreach ( $variants as $code ) {
                                $varname = $lang->getVariantname( $code );
@@ -263,7 +263,7 @@ class LegacyTemplate extends BaseTemplate {
                                }
                                $s = $wgLang->pipeList( array(
                                        $s,
-                                       '<a href="' . htmlspecialchars( $title->getLocalURL( 'variant=' . $code ) ) . '" lang="' . $code . '" hreflang="' . $code .  '">' . htmlspecialchars( $varname ) . '</a>'
+                                       '<a href="' . htmlspecialchars( $title->getLocalURL( 'variant=' . $code ) ) . '" lang="' . $code . '" hreflang="' . $code . '">' . htmlspecialchars( $varname ) . '</a>'
                                ) );
                        }
                }
index 58d443a..86972ee 100644 (file)
@@ -169,7 +169,7 @@ class SkinTemplate extends Skin {
                        unset( $query['returnto'] );
                        unset( $query['returntoquery'] );
                }
-               $this->thisquery = wfArrayToCGI( $query );
+               $this->thisquery = wfArrayToCgi( $query );
                $this->loggedin = $user->isLoggedIn();
                $this->username = $user->getName();
 
@@ -219,7 +219,7 @@ class SkinTemplate extends Skin {
                if ( $subpagestr !== '' ) {
                        $subpagestr = '<span class="subpages">' . $subpagestr . '</span>';
                }
-               $tpl->set( 'subtitle',  $subpagestr . $out->getSubtitle() );
+               $tpl->set( 'subtitle', $subpagestr . $out->getSubtitle() );
 
                $undelete = $this->getUndeleteLink();
                if ( $undelete === '' ) {
@@ -403,7 +403,7 @@ class SkinTemplate extends Skin {
                        $pageLang = $title->getPageViewLanguage();
                        $realBodyAttribs['lang'] = $pageLang->getHtmlCode();
                        $realBodyAttribs['dir'] = $pageLang->getDir();
-                       $realBodyAttribs['class'] = 'mw-content-'.$pageLang->getDir();
+                       $realBodyAttribs['class'] = 'mw-content-' . $pageLang->getDir();
                }
 
                $out->mBodytext = Html::rawElement( 'div', $realBodyAttribs, $out->mBodytext );
@@ -413,25 +413,28 @@ class SkinTemplate extends Skin {
                $language_urls = array();
 
                if ( !$wgHideInterlanguageLinks ) {
-                       foreach( $out->getLanguageLinks() as $l ) {
-                               $tmp = explode( ':', $l, 2 );
-                               $class = 'interwiki-' . $tmp[0];
-                               unset( $tmp );
-                               $nt = Title::newFromText( $l );
-                               if ( $nt ) {
-                                       $ilLangName = Language::fetchLanguageName( $nt->getInterwiki() );
+                       foreach( $out->getLanguageLinks() as $languageLinkText ) {
+                               $languageLinkParts = explode( ':', $languageLinkText, 2 );
+                               $class = 'interwiki-' . $languageLinkParts[0];
+                               unset( $languageLinkParts );
+                               $languageLinkTitle = Title::newFromText( $languageLinkText );
+                               if ( $languageLinkTitle ) {
+                                       $ilInterwikiCode = $languageLinkTitle->getInterwiki();
+                                       $ilLangName = Language::fetchLanguageName( $ilInterwikiCode );
+
                                        if ( strval( $ilLangName ) === '' ) {
-                                               $ilLangName = $l;
+                                               $ilLangName = $languageLinkText;
                                        } else {
                                                $ilLangName = $this->formatLanguageName( $ilLangName );
                                        }
+
                                        $language_urls[] = array(
-                                               'href' => $nt->getFullURL(),
+                                               'href' => $languageLinkTitle->getFullURL(),
                                                'text' => $ilLangName,
-                                               'title' => $nt->getText(),
+                                               'title' => $languageLinkTitle->getText(),
                                                'class' => $class,
-                                               'lang' => $nt->getInterwiki(),
-                                               'hreflang' => $nt->getInterwiki(),
+                                               'lang' => $ilInterwikiCode,
+                                               'hreflang' => $ilInterwikiCode
                                        );
                                }
                        }
@@ -574,7 +577,7 @@ class SkinTemplate extends Skin {
                        $a['wpStickHTTPS'] = true;
                }
 
-               $returnto = wfArrayToCGI( $a );
+               $returnto = wfArrayToCgi( $a );
                if( $this->loggedin ) {
                        $personal_urls['userpage'] = array(
                                'text' => $this->username,
@@ -1008,6 +1011,12 @@ class SkinTemplate extends Skin {
                                        // Gets preferred variant (note that user preference is
                                        // only possible for wiki content language variant)
                                        $preferred = $pageLang->getPreferredVariant();
+                                       if ( Action::getActionName( $this ) === 'view' ) {
+                                               $params = $request->getQueryValues();
+                                               unset( $params['title'] );
+                                       } else {
+                                               $params = array();
+                                       }
                                        // Loops over each variant
                                        foreach( $variants as $code ) {
                                                // Gets variant name from language code
@@ -1021,7 +1030,7 @@ class SkinTemplate extends Skin {
                                                $content_navigation['variants'][] = array(
                                                        'class' => ( $code == $preferred ) ? 'selected' : false,
                                                        'text' => $varname,
-                                                       'href' => $title->getLocalURL( array( 'variant' => $code ) ),
+                                                       'href' => $title->getLocalURL( array( 'variant' => $code ) + $params ),
                                                        'lang' => $code,
                                                        'hreflang' => $code
                                                );
@@ -1042,7 +1051,7 @@ class SkinTemplate extends Skin {
                }
 
                // Equiv to SkinTemplateContentActions
-               wfRunHooks( 'SkinTemplateNavigation::Universal', array( &$this,  &$content_navigation ) );
+               wfRunHooks( 'SkinTemplateNavigation::Universal', array( &$this, &$content_navigation ) );
 
                // Setup xml ids and tooltip info
                foreach ( $content_navigation as $section => &$links ) {
index da150c9..3b3a5ee 100644 (file)
@@ -598,7 +598,7 @@ class SpecialPage {
         *
         * @param $subPage string|null
         */
-       public final function run( $subPage ) {
+       final public function run( $subPage ) {
                /**
                 * Gets called before @see SpecialPage::execute.
                 *
@@ -846,7 +846,7 @@ class SpecialPage {
 
                foreach ( $wgFeedClasses as $format => $class ) {
                        $theseParams = $params + array( 'feedformat' => $format );
-                       $url = $feedTemplate . wfArrayToCGI( $theseParams );
+                       $url = $feedTemplate . wfArrayToCgi( $theseParams );
                        $this->getOutput()->addFeedLink( $format, $url );
                }
        }
@@ -863,7 +863,7 @@ abstract class FormSpecialPage extends SpecialPage {
         * Get an HTMLForm descriptor array
         * @return Array
         */
-       protected abstract function getFormFields();
+       abstract protected function getFormFields();
 
        /**
         * Add pre- or post-text to the form
@@ -904,7 +904,7 @@ abstract class FormSpecialPage extends SpecialPage {
                // Retain query parameters (uselang etc)
                $params = array_diff_key(
                        $this->getRequest()->getQueryValues(), array( 'title' => null ) );
-               $form->addHiddenField( 'redirectparams', wfArrayToCGI( $params ) );
+               $form->addHiddenField( 'redirectparams', wfArrayToCgi( $params ) );
 
                $form->addPreText( $this->preText() );
                $form->addPostText( $this->postText() );
@@ -921,13 +921,13 @@ abstract class FormSpecialPage extends SpecialPage {
         * @param  $data Array
         * @return Bool|Array true for success, false for didn't-try, array of errors on failure
         */
-       public abstract function onSubmit( array $data );
+       abstract public function onSubmit( array $data );
 
        /**
         * Do something exciting on successful processing of the form, most likely to show a
         * confirmation message
         */
-       public abstract function onSuccess();
+       abstract public function onSuccess();
 
        /**
         * Basic SpecialPage workflow: get a form, send it to the user; get some data back,
@@ -1045,7 +1045,7 @@ abstract class RedirectSpecialPage extends UnlistedSpecialPage {
                // Redirect to index.php with query parameters
                } elseif ( $redirect === true ) {
                        global $wgScript;
-                       $url = $wgScript . '?' . wfArrayToCGI( $query );
+                       $url = $wgScript . '?' . wfArrayToCgi( $query );
                        $this->getOutput()->redirect( $url );
                        return $redirect;
                } else {
@@ -1278,7 +1278,7 @@ class SpecialMytalk extends RedirectSpecialArticle {
  */
 class SpecialMycontributions extends RedirectSpecialPage {
        function __construct() {
-               parent::__construct(  'Mycontributions' );
+               parent::__construct( 'Mycontributions' );
                $this->mAllowedRedirectParams = array( 'limit', 'namespace', 'tagfilter',
                        'offset', 'dir', 'year', 'month', 'feed' );
        }
index 4a45b44..add7efc 100644 (file)
@@ -95,7 +95,7 @@ class SpecialPageFactory {
                'Preferences'               => 'SpecialPreferences',
                'Contributions'             => 'SpecialContributions',
                'Listgrouprights'           => 'SpecialListGroupRights',
-               'Listusers'                 => 'SpecialListUsers' ,
+               'Listusers'                 => 'SpecialListUsers',
                'Listadmins'                => 'SpecialListAdmins',
                'Listbots'                  => 'SpecialListBots',
                'Activeusers'               => 'SpecialActiveUsers',
@@ -119,7 +119,7 @@ class SpecialPageFactory {
                'Upload'                    => 'SpecialUpload',
                'UploadStash'               => 'SpecialUploadStash',
 
-               // Wiki data and tools
+               // Data and tools
                'Statistics'                => 'SpecialStatistics',
                'Allmessages'               => 'SpecialAllmessages',
                'Version'                   => 'SpecialVersion',
@@ -476,7 +476,7 @@ class SpecialPageFactory {
                        if ( $name != $page->getLocalName() && !$context->getRequest()->wasPosted() ) {
                                $query = $context->getRequest()->getQueryValues();
                                unset( $query['title'] );
-                               $query = wfArrayToCGI( $query );
+                               $query = wfArrayToCgi( $query );
                                $title = $page->getTitle( $par );
                                $url = $title->getFullUrl( $query );
                                $context->getOutput()->redirect( $url );
index d0ead9a..c01cdd0 100644 (file)
@@ -76,7 +76,7 @@ abstract class SqlDataUpdate extends DataUpdate {
 
                // NOTE: nested transactions are not supported, only start a transaction if none is open
                if ( $this->mDb->trxLevel() === 0 ) {
-                       $this->mDb->begin( get_class( $this ) . '::beginTransaction'  );
+                       $this->mDb->begin( get_class( $this ) . '::beginTransaction' );
                        $this->mHasTransaction = true;
                }
        }
index 7d75f2c..f5fd195 100644 (file)
@@ -293,7 +293,7 @@ class SquidPurgeClient {
                        if ( count( $lines ) < 2 ) {
                                return 'done';
                        }
-                       if ( $this->readState == 'status' )  {
+                       if ( $this->readState == 'status' ) {
                                $this->processStatusLine( $lines[0] );
                        } else { // header
                                $this->processHeaderLine( $lines[0] );
@@ -318,7 +318,7 @@ class SquidPurgeClient {
                                return 'done';
                        }
                default:
-                       throw new MWException( __METHOD__.': unexpected state' );
+                       throw new MWException( __METHOD__ . ': unexpected state' );
                }
        }
 
@@ -373,7 +373,7 @@ class SquidPurgeClient {
         * @param $msg string
         */
        protected function log( $msg ) {
-               wfDebugLog( 'squid', __CLASS__." ($this->host): $msg\n" );
+               wfDebugLog( 'squid', __CLASS__ . " ($this->host): $msg\n" );
        }
 }
 
@@ -429,14 +429,14 @@ class SquidPurgeClientPool {
                        $numReady = socket_select( $readSockets, $writeSockets, $exceptSockets, $timeout );
                        wfRestoreWarnings();
                        if ( $numReady === false ) {
-                               wfDebugLog( 'squid', __METHOD__.': Error in stream_select: ' .
+                               wfDebugLog( 'squid', __METHOD__ . ': Error in stream_select: ' .
                                        socket_strerror( socket_last_error() ) . "\n" );
                                break;
                        }
                        // Check for timeout, use 1% tolerance since we aimed at having socket_select()
                        // exit at precisely the overall timeout
                        if ( microtime( true ) - $startTime > $this->timeout * 0.99 ) {
-                               wfDebugLog( 'squid', __CLASS__.": timeout ({$this->timeout}s)\n" );
+                               wfDebugLog( 'squid', __CLASS__ . ": timeout ({$this->timeout}s)\n" );
                                break;
                        } elseif ( !$numReady ) {
                                continue;
index 2553f54..449b656 100644 (file)
@@ -176,10 +176,10 @@ class Status {
                if ( count( $this->errors ) == 0 ) {
                        if ( $this->ok ) {
                                $this->fatal( 'internalerror_info',
-                                       __METHOD__." called for a good result, this is incorrect\n" );
+                                       __METHOD__ . " called for a good result, this is incorrect\n" );
                        } else {
                                $this->fatal( 'internalerror_info',
-                                       __METHOD__.": Invalid result object: no error text but not OK\n" );
+                                       __METHOD__ . ": Invalid result object: no error text but not OK\n" );
                        }
                }
                if ( count( $this->errors ) == 1 ) {
@@ -190,7 +190,7 @@ class Status {
                                $s = wfMessage( $longContext, "* $s\n" )->plain();
                        }
                } else {
-                       $s = '* '. implode("\n* ",
+                       $s = '* '. implode( "\n* ",
                                $this->getErrorMessageArray( $this->errors ) ) . "\n";
                        if ( $longContext ) {
                                $s = wfMessage( $longContext, $s )->plain();
@@ -216,7 +216,7 @@ class Status {
                                $msg = $error['message'];
                        } elseif ( isset( $error['message'] ) && isset( $error['params'] ) ) {
                                $msg = wfMessage( $error['message'],
-                                       array_map( 'wfEscapeWikiText', $this->cleanParams( $error['params'] ) )  );
+                                       array_map( 'wfEscapeWikiText', $this->cleanParams( $error['params'] ) ) );
                        } else {
                                $msgName = array_shift( $error );
                                $msg = wfMessage( $msgName,
@@ -231,6 +231,10 @@ class Status {
        /**
         * Get the error message as HTML. This is done by parsing the wikitext error
         * message.
+        *
+        * @note: this does not perform a full wikitext to HTML conversion, it merely applies
+        *        a message transformation.
+        * @todo: figure out whether that is actually The Right Thing.
         */
        public function getHTML( $shortContext = false, $longContext = false ) {
                $text = $this->getWikiText( $shortContext, $longContext );
index 54a85dc..6647de4 100644 (file)
@@ -135,12 +135,12 @@ class StringUtils {
                $m = array();
 
                while ( $inputPos < strlen( $subject ) &&
-                 preg_match( "!($encStart)|($encEnd)!S$flags", $subject, $m, PREG_OFFSET_CAPTURE, $inputPos ) )
+                       preg_match( "!($encStart)|($encEnd)!S$flags", $subject, $m, PREG_OFFSET_CAPTURE, $inputPos ) )
                {
                        $tokenOffset = $m[0][1];
                        if ( $m[1][0] != '' ) {
                                if ( $foundStart &&
-                                 $strcmp( $endDelim, substr( $subject, $tokenOffset, $endLength ) ) == 0 )
+                                       $strcmp( $endDelim, substr( $subject, $tokenOffset, $endLength ) ) == 0 )
                                {
                                        # An end match is present at the same location
                                        $tokenType = 'end';
@@ -432,7 +432,7 @@ class ReplacementArray {
         * @param $from string
         */
        function removePair( $from ) {
-               unset($this->data[$from]);
+               unset( $this->data[$from] );
                $this->fss = false;
        }
 
index cc0adb7..8a1e758 100644 (file)
@@ -118,7 +118,7 @@ class StubObject {
                }
 
                if ( get_class( $GLOBALS[$this->mGlobal] ) != $this->mClass ) {
-                       $fname = __METHOD__.'-'.$this->mGlobal;
+                       $fname = __METHOD__ . '-' . $this->mGlobal;
                        wfProfileIn( $fname );
                        $caller = wfGetCaller( $level );
                        if ( ++$recursionLevel > 2 ) {
index aa53563..40e5b09 100644 (file)
@@ -149,7 +149,7 @@ class Title {
                $t->mDbkeyform = str_replace( ' ', '_', $filteredText );
                $t->mDefaultNamespace = $defaultNamespace;
 
-               static $cachedcount = 0 ;
+               static $cachedcount = 0;
                if ( $t->secureAndSplit() ) {
                        if ( $defaultNamespace == NS_MAIN ) {
                                if ( $cachedcount >= self::CACHE_MAX ) {
@@ -681,6 +681,7 @@ class Title {
        public function getContentModel() {
                if ( !$this->mContentModel ) {
                        $linkCache = LinkCache::singleton();
+                       $linkCache->addLinkObj( $this );
                        $this->mContentModel = $linkCache->getGoodLinkFieldObj( $this, 'model' );
                }
 
@@ -1330,7 +1331,7 @@ class Title {
         * second argument named variant. This was deprecated in favor
         * of passing an array of option with a "variant" key
         * Once $query2 is removed for good, this helper can be dropped
-        * andthe wfArrayToCGI moved to getLocalURL();
+        * andthe wfArrayToCgi moved to getLocalURL();
         *
         * @since 1.19 (r105919)
         * @param $query
@@ -1342,15 +1343,15 @@ class Title {
                        wfDeprecated( "Title::get{Canonical,Full,Link,Local} method called with a second parameter is deprecated. Add your parameter to an array passed as the first parameter.", "1.19" );
                }
                if ( is_array( $query ) ) {
-                       $query = wfArrayToCGI( $query );
+                       $query = wfArrayToCgi( $query );
                }
                if ( $query2 ) {
                        if ( is_string( $query2 ) ) {
                                // $query2 is a string, we will consider this to be
                                // a deprecated $variant argument and add it to the query
-                               $query2 = wfArrayToCGI( array( 'variant' => $query2 ) );
+                               $query2 = wfArrayToCgi( array( 'variant' => $query2 ) );
                        } else {
-                               $query2 = wfArrayToCGI( $query2 );
+                               $query2 = wfArrayToCgi( $query2 );
                        }
                        // If we have $query content add a & to it first
                        if ( $query ) {
@@ -1728,8 +1729,10 @@ class Title {
         */
        private function checkQuickPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) {
                if ( $action == 'create' ) {
-                       if ( ( $this->isTalkPage() && !$user->isAllowed( 'createtalk' ) ) ||
-                                ( !$this->isTalkPage() && !$user->isAllowed( 'createpage' ) ) ) {
+                       if (
+                               ( $this->isTalkPage() && !$user->isAllowed( 'createtalk' ) ) ||
+                               ( !$this->isTalkPage() && !$user->isAllowed( 'createpage' ) )
+                       ) {
                                $errors[] = $user->isAnon() ? array( 'nocreatetext' ) : array( 'nocreate-loggedin' );
                        }
                } elseif ( $action == 'move' ) {
@@ -1818,8 +1821,11 @@ class Title {
                        $errors = $this->resultToError( $errors, $result );
                }
                // Check getUserPermissionsErrorsExpensive hook
-               if ( $doExpensiveQueries && !( $short && count( $errors ) > 0 ) &&
-                        !wfRunHooks( 'getUserPermissionsErrorsExpensive', array( &$this, &$user, $action, &$result ) ) ) {
+               if (
+                       $doExpensiveQueries
+                       && !( $short && count( $errors ) > 0 )
+                       && !wfRunHooks( 'getUserPermissionsErrorsExpensive', array( &$this, &$user, $action, &$result ) )
+               ) {
                        $errors = $this->resultToError( $errors, $result );
                }
 
@@ -1838,10 +1844,9 @@ class Title {
         * @return Array list of errors
         */
        private function checkSpecialsAndNSPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) {
-               # Only 'createaccount' and 'execute' can be performed on
-               # special pages, which don't actually exist in the DB.
-               $specialOKActions = array( 'createaccount', 'execute' );
-               if ( NS_SPECIAL == $this->mNamespace && !in_array( $action, $specialOKActions ) ) {
+               # Only 'createaccount' can be performed on special pages,
+               # which don't actually exist in the DB.
+               if ( NS_SPECIAL == $this->mNamespace && $action !== 'createaccount' ) {
                        $errors[] = array( 'ns-specialprotected' );
                }
 
@@ -1850,7 +1855,7 @@ class Title {
                        $ns = $this->mNamespace == NS_MAIN ?
                                wfMessage( 'nstab-main' )->text() : $this->getNsText();
                        $errors[] = $this->mNamespace == NS_MEDIAWIKI ?
-                               array( 'protectedinterface' ) : array( 'namespaceprotected',  $ns );
+                               array( 'protectedinterface' ) : array( 'namespaceprotected', $ns );
                }
 
                return $errors;
@@ -2088,7 +2093,7 @@ class Title {
         * @return Array list of errors
         */
        private function checkReadPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) {
-               global $wgWhitelistRead, $wgRevokePermissions;
+               global $wgWhitelistRead, $wgWhitelistReadRegexp, $wgRevokePermissions;
                static $useShortcut = null;
 
                # Initialize the $useShortcut boolean, to determine if we can skip quite a bit of code below
@@ -2147,7 +2152,7 @@ class Title {
                                # If it's a special page, ditch the subpage bit and check again
                                $name = $this->getDBkey();
                                list( $name, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $name );
-                               if ( $name !== false ) {
+                               if ( $name ) {
                                        $pure = SpecialPage::getTitleFor( $name )->getPrefixedText();
                                        if ( in_array( $pure, $wgWhitelistRead, true ) ) {
                                                $whitelisted = true;
@@ -2156,6 +2161,17 @@ class Title {
                        }
                }
 
+               if( !$whitelisted && is_array( $wgWhitelistReadRegexp ) && !empty( $wgWhitelistReadRegexp ) ) {
+                       $name = $this->getPrefixedText();
+                       // Check for regex whitelisting
+                       foreach ( $wgWhitelistReadRegexp as $listItem ) {
+                               if ( preg_match( $listItem, $name ) ) {
+                                       $whitelisted = true;
+                                       break;
+                               }
+                       }
+               }
+
                if ( !$whitelisted ) {
                        # If the title is not whitelisted, give extensions a chance to do so...
                        wfRunHooks( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) );
@@ -2264,8 +2280,10 @@ class Title {
        public function userCanEditJsSubpage() {
                global $wgUser;
                wfDeprecated( __METHOD__, '1.19' );
-               return ( ( $wgUser->isAllowedAll( 'editusercssjs', 'edituserjs' ) )
-                          || preg_match( '/^' . preg_quote( $wgUser->getName(), '/' ) . '\//', $this->mTextform ) );
+               return (
+                       ( $wgUser->isAllowedAll( 'editusercssjs', 'edituserjs' ) )
+                       || preg_match( '/^' . preg_quote( $wgUser->getName(), '/' ) . '\//', $this->mTextform )
+               );
        }
 
        /**
@@ -2333,9 +2351,12 @@ class Title {
 
                if ( !isset( $this->mTitleProtection ) ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $res = $dbr->select( 'protected_titles', '*',
+                       $res = $dbr->select(
+                               'protected_titles',
+                               array( 'pt_user', 'pt_reason', 'pt_expiry', 'pt_create_perm' ),
                                array( 'pt_namespace' => $this->getNamespace(), 'pt_title' => $this->getDBkey() ),
-                               __METHOD__ );
+                               __METHOD__
+                       );
 
                        // fetchRow returns false if there are no rows.
                        $this->mTitleProtection = $dbr->fetchRow( $res );
@@ -2512,7 +2533,7 @@ class Title {
 
                if ( $getPages ) {
                        $cols = array( 'pr_page', 'page_namespace', 'page_title',
-                                                  'pr_expiry', 'pr_type', 'pr_level' );
+                               'pr_expiry', 'pr_type', 'pr_level' );
                        $where_clauses[] = 'page_id=pr_page';
                        $tables[] = 'page';
                } else {
@@ -2540,8 +2561,10 @@ class Title {
                                                $pagerestrictions[$row->pr_type] = array();
                                        }
 
-                                       if ( isset( $pagerestrictions[$row->pr_type] ) &&
-                                                !in_array( $row->pr_level, $pagerestrictions[$row->pr_type] ) ) {
+                                       if (
+                                               isset( $pagerestrictions[$row->pr_type] )
+                                               && !in_array( $row->pr_level, $pagerestrictions[$row->pr_type] )
+                                       ) {
                                                $pagerestrictions[$row->pr_type][] = $row->pr_level;
                                        }
                                } else {
@@ -2725,7 +2748,7 @@ class Title {
 
                                $res = $dbr->select(
                                        'page_restrictions',
-                                       '*',
+                                       array( 'pr_type', 'pr_expiry', 'pr_level', 'pr_cascade' ),
                                        array( 'pr_page' => $this->getArticleID() ),
                                        __METHOD__
                                );
@@ -2767,6 +2790,10 @@ class Title {
         * Purge expired restrictions from the page_restrictions table
         */
        static function purgeExpiredRestrictions() {
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
                $dbw = wfGetDB( DB_MASTER );
                $dbw->delete(
                        'page_restrictions',
@@ -2918,22 +2945,21 @@ class Title {
         * @return Bool
         */
        public function isRedirect( $flags = 0 ) {
-               if ( !is_null( $this->mRedirect ) ) {
+               if ( !( $flags & Title::GAID_FOR_UPDATE ) && !is_null( $this->mRedirect ) ) {
                        return $this->mRedirect;
                }
-               # Calling getArticleID() loads the field from cache as needed
+
                if ( !$this->getArticleID( $flags ) ) {
                        return $this->mRedirect = false;
                }
 
                $linkCache = LinkCache::singleton();
+               $linkCache->addLinkObj( $this );
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'redirect' );
+
                if ( $cached === null ) {
-                       // TODO: check the assumption that the cache actually knows about this title
-                       // and handle this, such as get the title from the database.
-                       // See https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
-                       wfDebug( "LinkCache doesn't currently know about this title: " . $this->getPrefixedDBkey() );
-                       wfDebug( wfBacktrace() );
+                       // Should not happen
+                       throw new MWException( "LinkCache doesn't know redirect status of this title: " . $this->getPrefixedDBkey() );
                }
 
                $this->mRedirect = (bool)$cached;
@@ -2949,20 +2975,21 @@ class Title {
         * @return Int
         */
        public function getLength( $flags = 0 ) {
-               if ( $this->mLength != -1 ) {
+               if ( !( $flags & Title::GAID_FOR_UPDATE ) && $this->mLength != -1 ) {
                        return $this->mLength;
                }
-               # Calling getArticleID() loads the field from cache as needed
+
                if ( !$this->getArticleID( $flags ) ) {
                        return $this->mLength = 0;
                }
+
                $linkCache = LinkCache::singleton();
+               $linkCache->addLinkObj( $this );
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'length' );
-               if ( $cached === null ) { # check the assumption that the cache actually knows about this title
-                       # XXX: this does apparently happen, see https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
-                       #      as a stop gap, perhaps log this, but don't throw an exception?
-                       wfDebug( "LinkCache doesn't currently know about this title: " . $this->getPrefixedDBkey() );
-                       wfDebug( wfBacktrace() );
+
+               if ( $cached === null ) {
+                       // Should not happen
+                       throw new MWException( "LinkCache doesn't know redirect status of this title: " . $this->getPrefixedDBkey() );
                }
 
                $this->mLength = intval( $cached );
@@ -2981,17 +3008,18 @@ class Title {
                if ( !( $flags & Title::GAID_FOR_UPDATE ) && $this->mLatestID !== false ) {
                        return intval( $this->mLatestID );
                }
-               # Calling getArticleID() loads the field from cache as needed
+
                if ( !$this->getArticleID( $flags ) ) {
                        return $this->mLatestID = 0;
                }
+
                $linkCache = LinkCache::singleton();
                $linkCache->addLinkObj( $this );
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'revision' );
-               if ( $cached === null ) { # check the assumption that the cache actually knows about this title
-                       # XXX: this does apparently happen, see https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
-                       #      as a stop gap, perhaps log this, but don't throw an exception?
-                       throw new MWException( "LinkCache doesn't currently know about this title: " . $this->getPrefixedDBkey() );
+
+               if ( $cached === null ) {
+                       // Should not happen
+                       throw new MWException( "LinkCache doesn't know latest revision ID of this title: " . $this->getPrefixedDBkey() );
                }
 
                $this->mLatestID = intval( $cached );
@@ -3176,15 +3204,18 @@ class Title {
                # Pages with "/./" or "/../" appearing in the URLs will often be un-
                # reachable due to the way web browsers deal with 'relative' URLs.
                # Also, they conflict with subpage syntax.  Forbid them explicitly.
-               if ( strpos( $dbkey, '.' ) !== false &&
-                        ( $dbkey === '.' || $dbkey === '..' ||
-                          strpos( $dbkey, './' ) === 0  ||
-                          strpos( $dbkey, '../' ) === 0 ||
-                          strpos( $dbkey, '/./' ) !== false ||
-                          strpos( $dbkey, '/../' ) !== false  ||
-                          substr( $dbkey, -2 ) == '/.' ||
-                          substr( $dbkey, -3 ) == '/..' ) )
-               {
+               if (
+                       strpos( $dbkey, '.' ) !== false &&
+                       (
+                               $dbkey === '.' || $dbkey === '..' ||
+                               strpos( $dbkey, './' ) === 0  ||
+                               strpos( $dbkey, '../' ) === 0 ||
+                               strpos( $dbkey, '/./' ) !== false ||
+                               strpos( $dbkey, '/../' ) !== false  ||
+                               substr( $dbkey, -2 ) == '/.' ||
+                               substr( $dbkey, -3 ) == '/..'
+                       )
+               ) {
                        return false;
                }
 
@@ -3197,9 +3228,10 @@ class Title {
                # underlying database field. We make an exception for special pages, which
                # don't need to be stored in the database, and may edge over 255 bytes due
                # to subpage syntax for long titles, e.g. [[Special:Block/Long name]]
-               if ( ( $this->mNamespace != NS_SPECIAL && strlen( $dbkey ) > 255 ) ||
-                 strlen( $dbkey ) > 512 )
-               {
+               if (
+                       ( $this->mNamespace != NS_SPECIAL && strlen( $dbkey ) > 255 )
+                       || strlen( $dbkey ) > 512
+               ) {
                        return false;
                }
 
@@ -3494,9 +3526,11 @@ class Title {
                if ( strlen( $nt->getDBkey() ) < 1 ) {
                        $errors[] = array( 'articleexists' );
                }
-               if ( ( $this->getDBkey() == '' ) ||
-                        ( !$oldid ) ||
-                        ( $nt->getDBkey() == '' ) ) {
+               if (
+                       ( $this->getDBkey() == '' ) ||
+                       ( !$oldid ) ||
+                       ( $nt->getDBkey() == '' )
+               ) {
                        $errors[] = array( 'badarticleerror' );
                }
 
@@ -3981,7 +4015,7 @@ class Title {
                }
                # Get the article text
                $rev = Revision::newFromTitle( $nt, false, Revision::READ_LATEST );
-               if( !is_object( $rev ) ){
+               if( !is_object( $rev ) ) {
                        return false;
                }
                $content = $rev->getContent();
@@ -4025,12 +4059,11 @@ class Title {
 
                $dbr = wfGetDB( DB_SLAVE );
 
-               $res = $dbr->select( 'categorylinks', '*',
-                       array(
-                               'cl_from' => $titleKey,
-                       ),
-                       __METHOD__,
-                       array()
+               $res = $dbr->select(
+                       'categorylinks',
+                       'cl_to',
+                       array( 'cl_from' => $titleKey ),
+                       __METHOD__
                );
 
                if ( $res->numRows() > 0 ) {
@@ -4270,7 +4303,7 @@ class Title {
                }
                $old_cmp = '>';
                $new_cmp = '<';
-               $options = (array) $options;
+               $options = (array)$options;
                if ( in_array( 'include_old', $options ) ) {
                        $old_cmp = '>=';
                }
diff --git a/includes/UIDGenerator.php b/includes/UIDGenerator.php
new file mode 100644 (file)
index 0000000..99642b7
--- /dev/null
@@ -0,0 +1,350 @@
+<?php
+/**
+ * This file deals with UID generation.
+ *
+ * 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
+ */
+
+/**
+ * Class for getting statistically unique IDs
+ *
+ * @since 1.21
+ */
+class UIDGenerator {
+       /** @var UIDGenerator */
+       protected static $instance = null;
+
+       protected $nodeId32; // string; node ID in binary (32 bits)
+       protected $nodeId48; // string; node ID in binary (48 bits)
+
+       protected $lockFile88; // string; local file path
+       protected $lockFile128; // string; local file path
+
+       /** @var Array */
+       protected $fileHandles = array(); // cache file handles
+
+       const QUICK_RAND = 1; // get randomness from fast and unsecure sources
+
+       protected function __construct() {
+               $idFile = wfTempDir() . '/mw-' . __CLASS__ . '-UID-nodeid';
+               $nodeId = is_file( $idFile ) ? file_get_contents( $idFile ) : '';
+               // Try to get some ID that uniquely identifies this machine (RFC 4122)...
+               if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) {
+                       wfSuppressWarnings();
+                       if ( wfIsWindows() ) {
+                               // http://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
+                               $m = array();
+                               preg_match( '/\s([0-9a-f]{2}(:[0-9a-f]{2}){5})\s/',
+                                       wfShellExec( '/sbin/ifconfig -a' ), $m );
+                               $nodeId = isset( $m[1] ) ? str_replace( ':', '', $m[1] ) : '';
+                       }
+                       wfRestoreWarnings();
+                       if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) {
+                               $nodeId = MWCryptRand::generateHex( 12, true );
+                               $nodeId[1] = dechex( hexdec( $nodeId[1] ) | 0x1 ); // set multicast bit
+                       }
+                       file_put_contents( $idFile, $nodeId ); // cache
+               }
+               $this->nodeId32 = wfBaseConvert( substr( sha1( $nodeId ), 0, 8 ), 16, 2, 32 );
+               $this->nodeId48 = wfBaseConvert( $nodeId, 16, 2, 48 );
+               // If different processes run as different users, they may have different temp dirs.
+               // This is dealt with by initializing the clock sequence number and counters randomly.
+               $this->lockFile88 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-88';
+               $this->lockFile128 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-128';
+       }
+
+       /**
+        * @return UIDGenerator
+        */
+       protected static function singleton() {
+               if ( self::$instance === null ) {
+                       self::$instance = new self();
+               }
+               return self::$instance;
+       }
+
+       /**
+        * Get a statistically unique 88-bit unsigned integer ID string.
+        * The bits of the UID are prefixed with the time (down to the millisecond).
+        *
+        * These IDs are suitable as values for the shard key of distributed data.
+        * If a column uses these as values, it should be declared UNIQUE to handle collisions.
+        * New rows almost always have higher UIDs, which makes B-TREE updates on INSERT fast.
+        * They can also be stored "DECIMAL(27) UNSIGNED" or BINARY(11) in MySQL.
+        *
+        * UID generation is serialized on each server (as the node ID is for the whole machine).
+        *
+        * @param $base integer Specifies a base other than 10
+        * @return string Number
+        * @throws MWException
+        */
+       public static function newTimestampedUID88( $base = 10 ) {
+               if ( !is_integer( $base ) || $base > 36 || $base < 2 ) {
+                       throw new MWException( "Base must an integer be between 2 and 36" );
+               }
+               $gen = self::singleton();
+               $time = $gen->getTimestampAndDelay( 'lockFile88', 1, 1024 );
+               return wfBaseConvert( $gen->getTimestampedID88( $time ), 2, $base );
+       }
+
+       /**
+        * @param $time array (UIDGenerator::millitime(), clock sequence)
+        * @return string 88 bits
+        */
+       protected function getTimestampedID88( array $info ) {
+               list( $time, $counter ) = $info;
+               // Take the 46 MSBs of "milliseconds since epoch"
+               $id_bin = $this->millisecondsSinceEpochBinary( $time );
+               // Add a 10 bit counter resulting in 56 bits total
+               $id_bin .= str_pad( decbin( $counter ), 10, '0', STR_PAD_LEFT );
+               // Add the 32 bit node ID resulting in 88 bits total
+               $id_bin .= $this->nodeId32;
+               // Convert to a 1-27 digit integer string
+               if ( strlen( $id_bin ) !== 88 ) {
+                       throw new MWException( "Detected overflow for millisecond timestamp." );
+               }
+               return $id_bin;
+       }
+
+       /**
+        * Get a statistically unique 128-bit unsigned integer ID string.
+        * The bits of the UID are prefixed with the time (down to the millisecond).
+        *
+        * These IDs are suitable as globally unique IDs, without any enforced uniqueness.
+        * New rows almost always have higher UIDs, which makes B-TREE updates on INSERT fast.
+        * They can also be stored as "DECIMAL(39) UNSIGNED" or BINARY(16) in MySQL.
+        *
+        * UID generation is serialized on each server (as the node ID is for the whole machine).
+        *
+        * @param $base integer Specifies a base other than 10
+        * @return string Number
+        * @throws MWException
+        */
+       public static function newTimestampedUID128( $base = 10 ) {
+               if ( !is_integer( $base ) || $base > 36 || $base < 2 ) {
+                       throw new MWException( "Base must be an integer between 2 and 36" );
+               }
+               $gen = self::singleton();
+               $time = $gen->getTimestampAndDelay( 'lockFile128', 16384, 1048576 );
+               return wfBaseConvert( $gen->getTimestampedID128( $time ), 2, $base );
+       }
+
+       /**
+        * @param $info array (UIDGenerator::milltime(), counter, clock sequence)
+        * @return string 128 bits
+        */
+       protected function getTimestampedID128( array $info ) {
+               list( $time, $counter, $clkSeq ) = $info;
+               // Take the 46 MSBs of "milliseconds since epoch"
+               $id_bin = $this->millisecondsSinceEpochBinary( $time );
+               // Add a 20 bit counter resulting in 66 bits total
+               $id_bin .= str_pad( decbin( $counter ), 20, '0', STR_PAD_LEFT );
+               // Add a 14 bit clock sequence number resulting in 80 bits total
+               $id_bin .= str_pad( decbin( $clkSeq ), 14, '0', STR_PAD_LEFT );
+               // Add the 48 bit node ID resulting in 128 bits total
+               $id_bin .= $this->nodeId48;
+               // Convert to a 1-39 digit integer string
+               if ( strlen( $id_bin ) !== 128 ) {
+                       throw new MWException( "Detected overflow for millisecond timestamp." );
+               }
+               return $id_bin;
+       }
+
+       /**
+        * Return an RFC4122 compliant v4 UUID
+        *
+        * @param $flags integer Bitfield (supports UIDGenerator::QUICK_RAND)
+        * @return string
+        * @throws MWException
+        */
+       public static function newUUIDv4( $flags = 0 ) {
+               $hex = ( $flags & self::QUICK_RAND )
+                       ? wfRandomString( 31 )
+                       : MWCryptRand::generateHex( 31 );
+
+               return sprintf( '%s-%s-%s-%s-%s',
+                       // "time_low" (32 bits)
+                       substr( $hex, 0, 8 ),
+                       // "time_mid" (16 bits)
+                       substr( $hex, 8, 4 ),
+                       // "time_hi_and_version" (16 bits)
+                       '4' . substr( $hex, 12, 3 ),
+                       // "clk_seq_hi_res (8 bits, variant is binary 10x) and "clk_seq_low" (8 bits)
+                       dechex( 0x8 | ( hexdec( $hex[15] ) & 0x3 ) ) . $hex[16] . substr( $hex, 17, 2 ),
+                       // "node" (48 bits)
+                       substr( $hex, 19, 12 )
+               );
+       }
+
+       /**
+        * Return an RFC4122 compliant v4 UUID
+        *
+        * @param $flags integer Bitfield (supports UIDGenerator::QUICK_RAND)
+        * @return string 32 hex characters with no hyphens
+        * @throws MWException
+        */
+       public static function newRawUUIDv4( $flags = 0 ) {
+               return str_replace( '-', '', self::newUUIDv4( $flags ) );
+       }
+
+       /**
+        * Get a (time,counter,clock sequence) where (time,counter) is higher
+        * than any previous (time,counter) value for the given clock sequence.
+        * This is useful for making UIDs sequential on a per-node bases.
+        *
+        * @param $lockFile string Name of a local lock file
+        * @param $clockSeqSize integer The number of possible clock sequence values
+        * @param $counterSize integer The number of possible counter values
+        * @return Array (result of UIDGenerator::millitime(), counter, clock sequence)
+        * @throws MWException
+        */
+       protected function getTimestampAndDelay( $lockFile, $clockSeqSize, $counterSize ) {
+               // Get the UID lock file handle
+               if ( isset( $this->fileHandles[$lockFile] ) ) {
+                       $handle = $this->fileHandles[$lockFile];
+               } else {
+                       $handle = fopen( $this->$lockFile, 'cb+' );
+                       $this->fileHandles[$lockFile] = $handle ?: null; // cache
+               }
+               // Acquire the UID lock file
+               if ( $handle === false ) {
+                       throw new MWException( "Could not open '{$this->$lockFile}'." );
+               } elseif ( !flock( $handle, LOCK_EX ) ) {
+                       throw new MWException( "Could not acquire '{$this->$lockFile}'." );
+               }
+               // Get the current timestamp, clock sequence number, last time, and counter
+               rewind( $handle );
+               $data = explode( ' ', fgets( $handle ) ); // "<clk seq> <sec> <msec> <counter> <offset>"
+               $clockChanged = false; // clock set back significantly?
+               if ( count( $data ) == 5 ) { // last UID info already initialized
+                       $clkSeq = (int) $data[0] % $clockSeqSize;
+                       $prevTime = array( (int) $data[1], (int) $data[2] );
+                       $offset = (int) $data[4] % $counterSize; // random counter offset
+                       $counter = 0; // counter for UIDs with the same timestamp
+                       // Delay until the clock reaches the time of the last ID.
+                       // This detects any microtime() drift among processes.
+                       $time = $this->timeWaitUntil( $prevTime );
+                       if ( !$time ) { // too long to delay?
+                               $clockChanged = true; // bump clock sequence number
+                               $time = self::millitime();
+                       } elseif ( $time == $prevTime ) {
+                               // Bump the counter if there are timestamp collisions
+                               $counter = (int) $data[3] % $counterSize;
+                               if ( ++$counter >= $counterSize ) { // sanity (starts at 0)
+                                       flock( $handle, LOCK_UN ); // abort
+                                       throw new MWException( "Counter overflow for timestamp value." );
+                               }
+                       }
+               } else { // last UID info not initialized
+                       $clkSeq = mt_rand( 0, $clockSeqSize - 1 );
+                       $counter = 0;
+                       $offset = mt_rand( 0, $counterSize - 1 );
+                       $time = self::millitime();
+               }
+               // microtime() and gettimeofday() can drift from time() at least on Windows.
+               // The drift is immediate for processes running while the system clock changes.
+               // time() does not have this problem. See https://bugs.php.net/bug.php?id=42659.
+               if ( abs( time() - $time[0] ) >= 2 ) {
+                       // We don't want processes using too high or low timestamps to avoid duplicate
+                       // UIDs and clock sequence number churn. This process should just be restarted.
+                       flock( $handle, LOCK_UN ); // abort
+                       throw new MWException( "Process clock is outdated or drifted." );
+               }
+               // If microtime() is synced and a clock change was detected, then the clock went back
+               if ( $clockChanged ) {
+                       // Bump the clock sequence number and also randomize the counter offset,
+                       // which is useful for UIDs that do not include the clock sequence number.
+                       $clkSeq = ( $clkSeq + 1 ) % $clockSeqSize;
+                       $offset = mt_rand( 0, $counterSize - 1 );
+                       trigger_error( "Clock was set back; sequence number incremented." );
+               }
+               // Update the (clock sequence number, timestamp, counter)
+               ftruncate( $handle, 0 );
+               rewind( $handle );
+               fwrite( $handle, "{$clkSeq} {$time[0]} {$time[1]} {$counter} {$offset}" );
+               fflush( $handle );
+               // Release the UID lock file
+               flock( $handle, LOCK_UN );
+
+               return array( $time, ( $counter + $offset ) % $counterSize, $clkSeq );
+       }
+
+       /**
+        * Wait till the current timestamp reaches $time and return the current
+        * timestamp. This returns false if it would have to wait more than 10ms.
+        *
+        * @param $time array Result of UIDGenerator::millitime()
+        * @return Array|bool UIDGenerator::millitime() result or false
+        */
+       protected function timeWaitUntil( array $time ) {
+               do {
+                       $ct = self::millitime();
+                       if ( $ct >= $time ) { // http://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 );
+
+               return false;
+       }
+
+       /**
+        * @param $time array Result of UIDGenerator::millitime()
+        * @return string 46 MSBs of "milliseconds since epoch" in binary (rolls over in 4201)
+        */
+       protected function millisecondsSinceEpochBinary( array $time ) {
+               list( $sec, $msec ) = $time;
+               if ( PHP_INT_SIZE >= 8 ) { // 64 bit integers
+                       $ts = ( 1000 * $sec + $msec );
+                       $id_bin = str_pad( decbin( $ts % pow( 2, 46 ) ), 46, '0', STR_PAD_LEFT );
+               } elseif ( extension_loaded( 'gmp' ) ) {
+                       $ts = gmp_mod( // wrap around
+                               gmp_add( gmp_mul( (string) $sec, (string) 1000 ), (string) $msec ),
+                               gmp_pow( '2', '46' )
+                       );
+                       $id_bin = str_pad( gmp_strval( $ts, 2 ), 46, '0', STR_PAD_LEFT );
+               } elseif ( extension_loaded( 'bcmath' ) ) {
+                       $ts = bcmod( // wrap around
+                               bcadd( bcmul( $sec, 1000 ), $msec ),
+                               bcpow( 2, 46 )
+                       );
+                       $id_bin = wfBaseConvert( $ts, 10, 2, 46 );
+               } else {
+                       throw new MWException( 'bcmath or gmp extension required for 32 bit machines.' );
+               }
+               return $id_bin;
+       }
+
+       /**
+        * @return Array (current time in seconds, milliseconds since then)
+        */
+       protected static function millitime() {
+               list( $msec, $sec ) = explode( ' ', microtime() );
+               return array( (int) $sec, (int) ( $msec * 1000 ) );
+       }
+
+       function __destruct() {
+               array_map( 'fclose', $this->fileHandles );
+       }
+}
index ab3fd20..de34bfc 100644 (file)
@@ -547,7 +547,7 @@ class User {
         * @return Bool
         */
        public static function isIP( $name ) {
-               return preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/',$name) || IP::isIPv6($name);
+               return preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/', $name ) || IP::isIPv6( $name );
        }
 
        /**
@@ -1451,7 +1451,7 @@ class User {
                        // But this is a crappy hack and should die.
                        return false;
                }
-               return !$this->isAllowed('noratelimit');
+               return !$this->isAllowed( 'noratelimit' );
        }
 
        /**
@@ -1467,7 +1467,7 @@ class User {
        public function pingLimiter( $action = 'edit' ) {
                # Call the 'PingLimiter' hook
                $result = false;
-               if( !wfRunHooks( 'PingLimiter', array( &$this, $action, $result ) ) ) {
+               if( !wfRunHooks( 'PingLimiter', array( &$this, $action, &$result ) ) ) {
                        return $result;
                }
 
@@ -1569,7 +1569,7 @@ class User {
         * @param $bFromSlave Bool Whether to check the slave database instead of the master
         * @return Block|null
         */
-       public function getBlock( $bFromSlave = true ){
+       public function getBlock( $bFromSlave = true ) {
                $this->getBlockedStatus( $bFromSlave );
                return $this->mBlock instanceof Block ? $this->mBlock : null;
        }
@@ -2046,7 +2046,9 @@ class User {
        /**
         * Set the password and reset the random token unconditionally.
         *
-        * @param $str String New password to set
+        * @param $str string|null New password to set or null to set an invalid
+        *        password hash meaning that the user will not be able to log in
+        *        through the web interface.
         */
        public function setInternalPassword( $str ) {
                $this->load();
@@ -2229,7 +2231,7 @@ class User {
                # set it, and then it was disabled removing their ability to change it).  But
                # we don't want to erase the preferences in the database in case the preference
                # is re-enabled again.  So don't touch $mOptions, just override the returned value
-               if( in_array( $oname, $wgHiddenPrefs ) && !$ignoreHidden ){
+               if( in_array( $oname, $wgHiddenPrefs ) && !$ignoreHidden ) {
                        return self::getDefaultOption( $oname );
                }
 
@@ -2255,9 +2257,9 @@ class User {
                # set it, and then it was disabled removing their ability to change it).  But
                # we don't want to erase the preferences in the database in case the preference
                # is re-enabled again.  So don't touch $mOptions, just override the returned value
-               foreach( $wgHiddenPrefs as $pref ){
+               foreach( $wgHiddenPrefs as $pref ) {
                        $default = self::getDefaultOption( $pref );
-                       if( $default !== null ){
+                       if( $default !== null ) {
                                $options[$pref] = $default;
                        }
                }
@@ -2284,7 +2286,7 @@ class User {
         * @return Int User's current value for the option
         * @see getOption()
         */
-       public function getIntOption( $oname, $defaultOverride=0 ) {
+       public function getIntOption( $oname, $defaultOverride = 0 ) {
                $val = $this->getOption( $oname );
                if( $val == '' ) {
                        $val = $defaultOverride;
@@ -2620,7 +2622,7 @@ class User {
                        if( $this->getId() ) {
                                $dbw->insert( 'user_groups',
                                        array(
-                                               'ug_user'  => $this->getID(),
+                                               'ug_user' => $this->getID(),
                                                'ug_group' => $group,
                                        ),
                                        __METHOD__,
@@ -2645,13 +2647,13 @@ class User {
                        $dbw = wfGetDB( DB_MASTER );
                        $dbw->delete( 'user_groups',
                                array(
-                                       'ug_user'  => $this->getID(),
+                                       'ug_user' => $this->getID(),
                                        'ug_group' => $group,
                                ), __METHOD__ );
                        // Remember that the user was in this group
                        $dbw->insert( 'user_former_groups',
                                array(
-                                       'ufg_user'  => $this->getID(),
+                                       'ufg_user' => $this->getID(),
                                        'ufg_group' => $group,
                                ),
                                __METHOD__,
@@ -2690,8 +2692,8 @@ class User {
         */
        public function isAllowedAny( /*...*/ ) {
                $permissions = func_get_args();
-               foreach( $permissions as $permission ){
-                       if( $this->isAllowed( $permission ) ){
+               foreach( $permissions as $permission ) {
+                       if( $this->isAllowed( $permission ) ) {
                                return true;
                        }
                }
@@ -2705,8 +2707,8 @@ class User {
         */
        public function isAllowedAll( /*...*/ ) {
                $permissions = func_get_args();
-               foreach( $permissions as $permission ){
-                       if( !$this->isAllowed( $permission ) ){
+               foreach( $permissions as $permission ) {
+                       if( !$this->isAllowed( $permission ) ) {
                                return false;
                        }
                }
@@ -2874,13 +2876,17 @@ class User {
         * the next change of any watched page.
         */
        public function clearAllNotifications() {
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
                global $wgUseEnotif, $wgShowUpdatedMarker;
                if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
                        $this->setNewtalk( false );
                        return;
                }
                $id = $this->getId();
-               if( $id != 0 )  {
+               if( $id != 0 ) {
                        $dbw = wfGetDB( DB_MASTER );
                        $dbw->update( 'watchlist',
                                array( /* SET */
@@ -3264,8 +3270,8 @@ class User {
        public function getPageRenderingHash() {
                wfDeprecated( __METHOD__, '1.17' );
 
-               global $wgUseDynamicDates, $wgRenderHashAppend, $wgLang, $wgContLang;
-               if( $this->mHash ){
+               global $wgRenderHashAppend, $wgLang, $wgContLang;
+               if( $this->mHash ) {
                        return $this->mHash;
                }
 
@@ -3275,9 +3281,6 @@ class User {
 
                $confstr =        $this->getOption( 'math' );
                $confstr .= '!' . $this->getStubThreshold();
-               if ( $wgUseDynamicDates ) { # This is wrong (bug 24714)
-                       $confstr .= '!' . $this->getDatePreference();
-               }
                $confstr .= '!' . ( $this->getOption( 'numberheadings' ) ? '1' : '' );
                $confstr .= '!' . $wgLang->getCode();
                $confstr .= '!' . $this->getOption( 'thumbsize' );
@@ -3306,7 +3309,7 @@ class User {
         */
        public function isBlockedFromCreateAccount() {
                $this->getBlockedStatus();
-               if( $this->mBlock && $this->mBlock->prevents( 'createaccount' ) ){
+               if( $this->mBlock && $this->mBlock->prevents( 'createaccount' ) ) {
                        return $this->mBlock;
                }
 
@@ -4058,7 +4061,7 @@ class User {
                        $groups = array_merge_recursive(
                                $groups, $this->changeableByGroup( $addergroup )
                        );
-                       $groups['add']    = array_unique( $groups['add'] );
+                       $groups['add'] = array_unique( $groups['add'] );
                        $groups['remove'] = array_unique( $groups['remove'] );
                        $groups['add-self'] = array_unique( $groups['add-self'] );
                        $groups['remove-self'] = array_unique( $groups['remove-self'] );
@@ -4217,54 +4220,73 @@ class User {
        }
 
        /**
-        * Add a newuser log entry for this user. Before 1.19 the return value was always true.
+        * Add a newuser log entry for this user.
+        * Before 1.19 the return value was always true.
+        *
+        * @param $action string|bool: account creation type.
+        *   - String, one of the following values:
+        *     - 'create' for an anonymous user creating an account for himself.
+        *       This will force the action's performer to be the created user itself,
+        *       no matter the value of $wgUser
+        *     - 'create2' for a logged in user creating an account for someone else
+        *     - 'byemail' when the created user will receive its password by e-mail
+        *   - Boolean means whether the account was created by e-mail (deprecated):
+        *     - true will be converted to 'byemail'
+        *     - false will be converted to 'create' if this object is the same as
+        *       $wgUser and to 'create2' otherwise
         *
-        * @param $byEmail Boolean: account made by email?
         * @param $reason String: user supplied reason
         *
         * @return int|bool True if not $wgNewUserLog; otherwise ID of log item or 0 on failure
         */
-       public function addNewUserLogEntry( $byEmail = false, $reason = '' ) {
-               global $wgUser, $wgContLang, $wgNewUserLog;
+       public function addNewUserLogEntry( $action = false, $reason = '' ) {
+               global $wgUser, $wgNewUserLog;
                if( empty( $wgNewUserLog ) ) {
                        return true; // disabled
                }
 
-               if( $this->getName() == $wgUser->getName() ) {
-                       $action = 'create';
-               } else {
-                       $action = 'create2';
-                       if ( $byEmail ) {
-                               if ( $reason === '' ) {
-                                       $reason = wfMessage( 'newuserlog-byemail' )->inContentLanguage()->text();
-                               } else {
-                                       $reason = $wgContLang->commaList( array(
-                                               $reason, wfMessage( 'newuserlog-byemail' )->inContentLanguage()->text() ) );
-                               }
+               if ( $action === true ) {
+                       $action = 'byemail';
+               } elseif ( $action === false ) {
+                       if ( $this->getName() == $wgUser->getName() ) {
+                               $action = 'create';
+                       } else {
+                               $action = 'create2';
                        }
                }
-               $log = new LogPage( 'newusers' );
-               return (int)$log->addEntry(
-                       $action,
-                       $this->getUserPage(),
-                       $reason,
-                       array( $this->getId() )
-               );
+
+               if ( $action === 'create' || $action === 'autocreate' ) {
+                       $performer = $this;
+               } else {
+                       $performer = $wgUser;
+               }
+
+               $logEntry = new ManualLogEntry( 'newusers', $action );
+               $logEntry->setPerformer( $performer );
+               $logEntry->setTarget( $this->getUserPage() );
+               $logEntry->setComment( $reason );
+               $logEntry->setParameters( array(
+                       '4::userid' => $this->getId(),
+               ) );
+               $logid = $logEntry->insert();
+
+               if ( $action !== 'autocreate' ) {
+                       $logEntry->publish( $logid );
+               }
+
+               return (int)$logid;
        }
 
        /**
         * Add an autocreate newuser log entry for this user
         * Used by things like CentralAuth and perhaps other authplugins.
+        * Consider calling addNewUserLogEntry() directly instead.
         *
         * @return bool
         */
        public function addNewUserLogEntryAutoCreate() {
-               global $wgNewUserLog;
-               if( !$wgNewUserLog ) {
-                       return true; // disabled
-               }
-               $log = new LogPage( 'newusers', false );
-               $log->addEntry( 'autocreate', $this->getUserPage(), '', array( $this->getId() ), $this );
+               $this->addNewUserLogEntry( 'autocreate' );
+
                return true;
        }
 
index 324e7ce..7d11342 100644 (file)
@@ -136,10 +136,10 @@ class UserMailer {
                global $wgSMTP, $wgServer;
 
                $msgid = uniqid( wfWikiID() . ".", true ); /* true required for cygwin */
-               if ( is_array($wgSMTP) && isset($wgSMTP['IDHost']) && $wgSMTP['IDHost'] ) {
+               if ( is_array( $wgSMTP ) && isset( $wgSMTP['IDHost'] ) && $wgSMTP['IDHost'] ) {
                        $domain = $wgSMTP['IDHost'];
                } else {
-                       $url = wfParseUrl($wgServer);
+                       $url = wfParseUrl( $wgServer );
                        $domain = $url['host'];
                }
                return "<$msgid@$domain>";
@@ -340,7 +340,7 @@ class UserMailer {
                        #
                        # PHP mail()
                        #
-                       if( count($to) > 1 ) {
+                       if( count( $to ) > 1 ) {
                                $headers['To'] = 'undisclosed-recipients:;';
                        }
                        $headers = self::arrayToHeaderString( $headers, $endl );
@@ -517,9 +517,9 @@ class EmailNotification {
                                                        array( /* SET */
                                                                'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
                                                        ), array( /* WHERE */
-                                                               'wl_user'      => $watchers,
+                                                               'wl_user' => $watchers,
                                                                'wl_namespace' => $title->getNamespace(),
-                                                               'wl_title'     => $title->getDBkey(),
+                                                               'wl_title' => $title->getDBkey(),
                                                        ), $fname
                                                );
                                                $dbw->commit( $fname );
@@ -710,16 +710,16 @@ class EmailNotification {
                        if ( !$wgEnotifImpersonal ) {
                                // For personal mail, also show a link to the diff of all changes
                                // since last visited.
-                               $keys['$NEWPAGE'] .= "\n\n" .  wfMessage( 'enotif_lastvisited',
+                               $keys['$NEWPAGE'] .= "\n\n" . wfMessage( 'enotif_lastvisited',
                                        $this->title->getCanonicalUrl( 'diff=0&oldid=' . $this->oldid ) )
                                        ->inContentLanguage()->text();
                        }
-                       $keys['$OLDID']   = $this->oldid;
+                       $keys['$OLDID'] = $this->oldid;
                        // @deprecated Remove in MediaWiki 1.23.
                        $keys['$CHANGEDORCREATED'] = wfMessage( 'changed' )->inContentLanguage()->text();
                } else {
                        # clear $OLDID placeholder in the message template
-                       $keys['$OLDID']   = '';
+                       $keys['$OLDID'] = '';
                        $keys['$NEWPAGE'] = '';
                        // @deprecated Remove in MediaWiki 1.23.
                        $keys['$CHANGEDORCREATED'] = wfMessage( 'created' )->inContentLanguage()->text();
@@ -771,13 +771,13 @@ class EmailNotification {
                {
                        $editorAddress = new MailAddress( $this->editor );
                        if ( $wgEnotifFromEditor ) {
-                               $this->from    = $editorAddress;
+                               $this->from = $editorAddress;
                        } else {
-                               $this->from    = $adminAddress;
+                               $this->from = $adminAddress;
                                $this->replyto = $editorAddress;
                        }
                } else {
-                       $this->from    = $adminAddress;
+                       $this->from = $adminAddress;
                        $this->replyto = new MailAddress( $wgNoReplyAddress );
                }
        }
index ffdc285..240ebc7 100644 (file)
@@ -162,22 +162,22 @@ class WatchedItem {
                // if there's already an entry for this page
                $dbw = wfGetDB( DB_MASTER );
                $dbw->insert( 'watchlist',
-                 array(
-                       'wl_user' => $this->getUserId(),
-                       'wl_namespace' => MWNamespace::getSubject($this->getTitleNs()),
-                       'wl_title' => $this->getTitleDBkey(),
-                       'wl_notificationtimestamp' => null
-                 ), __METHOD__, 'IGNORE' );
+                       array(
+                               'wl_user' => $this->getUserId(),
+                               'wl_namespace' => MWNamespace::getSubject( $this->getTitleNs() ),
+                               'wl_title' => $this->getTitleDBkey(),
+                               'wl_notificationtimestamp' => null
+                       ), __METHOD__, 'IGNORE' );
 
                // Every single watched page needs now to be listed in watchlist;
                // namespace:page and namespace_talk:page need separate entries:
                $dbw->insert( 'watchlist',
-                 array(
-                       'wl_user' => $this->getUserId(),
-                       'wl_namespace' => MWNamespace::getTalk($this->getTitleNs()),
-                       'wl_title' => $this->getTitleDBkey(),
-                       'wl_notificationtimestamp' => null
-                 ), __METHOD__, 'IGNORE' );
+                       array(
+                               'wl_user' => $this->getUserId(),
+                               'wl_namespace' => MWNamespace::getTalk( $this->getTitleNs() ),
+                               'wl_title' => $this->getTitleDBkey(),
+                               'wl_notificationtimestamp' => null
+                       ), __METHOD__, 'IGNORE' );
 
                $this->watched = true;
 
@@ -197,7 +197,7 @@ class WatchedItem {
                $dbw->delete( 'watchlist',
                        array(
                                'wl_user' => $this->getUserId(),
-                               'wl_namespace' => MWNamespace::getSubject($this->getTitleNs()),
+                               'wl_namespace' => MWNamespace::getSubject( $this->getTitleNs() ),
                                'wl_title' => $this->getTitleDBkey(),
                        ), __METHOD__
                );
@@ -212,7 +212,7 @@ class WatchedItem {
                $dbw->delete( 'watchlist',
                        array(
                                'wl_user' => $this->getUserId(),
-                               'wl_namespace' => MWNamespace::getTalk($this->getTitleNs()),
+                               'wl_namespace' => MWNamespace::getTalk( $this->getTitleNs() ),
                                'wl_title' => $this->getTitleDBkey(),
                        ), __METHOD__
                );
index 68d22a8..cd43ffb 100644 (file)
@@ -76,7 +76,7 @@ class WebRequest {
         *
         * @return Array: Any query arguments found in path matches.
         */
-       static public function getPathInfo( $want = 'all' ) {
+       public static function getPathInfo( $want = 'all' ) {
                global $wgUsePathInfo;
                // PATH_INFO is mangled due to http://bugs.php.net/bug.php?id=31892
                // And also by Apache 2.x, double slashes are converted to single slashes.
@@ -128,7 +128,7 @@ class WebRequest {
                                global $wgVariantArticlePath, $wgContLang;
                                if( $wgVariantArticlePath ) {
                                        $router->add( $wgVariantArticlePath,
-                                               array( 'variant' => '$2'),
+                                               array( 'variant' => '$2' ),
                                                array( '$2' => $wgContLang->getVariants() )
                                        );
                                }
@@ -144,7 +144,7 @@ class WebRequest {
                                // Also reported when ini_get('cgi.fix_pathinfo')==false
                                $matches['title'] = substr( $_SERVER['ORIG_PATH_INFO'], 1 );
 
-                       } elseif ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != '') ) {
+                       } elseif ( isset( $_SERVER['PATH_INFO'] ) && $_SERVER['PATH_INFO'] != '' ) {
                                // Regular old PATH_INFO yay
                                $matches['title'] = substr( $_SERVER['PATH_INFO'], 1 );
                        }
@@ -565,9 +565,9 @@ class WebRequest {
         *
         * @return Array
         */
-        public function getQueryValues() {
+       public function getQueryValues() {
                return $_GET;
-        }
+       }
 
        /**
         * Get the HTTP method used for this request.
@@ -619,7 +619,7 @@ class WebRequest {
                        global $wgCookiePrefix;
                        $prefix = $wgCookiePrefix;
                }
-               return $this->getGPCVal( $_COOKIE, $prefix . $key , $default );
+               return $this->getGPCVal( $_COOKIE, $prefix . $key, $default );
        }
 
        /**
@@ -720,7 +720,7 @@ class WebRequest {
                $newquery = $this->getQueryValues();
                unset( $newquery['title'] );
                $newquery = array_merge( $newquery, $array );
-               $query = wfArrayToCGI( $newquery );
+               $query = wfArrayToCgi( $newquery );
                return $onlyquery ? $query : $wgTitle->getLocalURL( $query );
        }
 
@@ -849,7 +849,7 @@ class WebRequest {
                } else {
                        foreach ( $_SERVER as $name => $value ) {
                                if ( substr( $name, 0, 5 ) === 'HTTP_' ) {
-                                       $name = str_replace( '_', '-',  substr( $name, 5 ) );
+                                       $name = str_replace( '_', '-', substr( $name, 5 ) );
                                        $this->headers[$name] = $value;
                                } elseif ( $name === 'CONTENT_LENGTH' ) {
                                        $this->headers['CONTENT-LENGTH'] = $value;
index e467738..4276fb0 100644 (file)
@@ -42,7 +42,8 @@ class WebResponse {
         * Set the browser cookie
         * @param $name String: name of cookie
         * @param $value String: value to give cookie
-        * @param $expire Int: number of seconds til cookie expires
+        * @param $expire Int: Unix timestamp (in seconds) when the cookie should expire.
+        *        0 (the default) causes it to expire $wgCookieExpiration seconds from now.
         * @param $prefix String: Prefix to use, if not $wgCookiePrefix (use '' for no prefix)
         * @param $domain String: Cookie domain to use, if not $wgCookieDomain
         * @param $forceSecure Bool:
@@ -52,7 +53,7 @@ class WebResponse {
         */
        public function setcookie( $name, $value, $expire = 0, $prefix = null, $domain = null, $forceSecure = null ) {
                global $wgCookiePath, $wgCookiePrefix, $wgCookieDomain;
-               global $wgCookieSecure,$wgCookieExpiration, $wgCookieHttpOnly;
+               global $wgCookieSecure, $wgCookieExpiration, $wgCookieHttpOnly;
                if ( $expire == 0 ) {
                        $expire = time() + $wgCookieExpiration;
                }
@@ -69,7 +70,11 @@ class WebResponse {
                        $secureCookie = $forceSecure;
                }
 
-               $httpOnlySafe = wfHttpOnlySafe() && $wgCookieHttpOnly;
+               // Mark the cookie as httpOnly if $wgCookieHttpOnly is true,
+               // unless the requesting user-agent is known to have trouble with
+               // httpOnly cookies.
+               $httpOnlySafe = $wgCookieHttpOnly && wfHttpOnlySafe();
+
                wfDebugLog( 'cookie',
                        'setcookie: "' . implode( '", "',
                                array(
@@ -159,7 +164,7 @@ class FauxResponse extends WebResponse {
         * @param $name string
         * @return string
         */
-       public function getcookie( $name )  {
+       public function getcookie( $name ) {
                if ( isset( $this->cookies[$name] ) ) {
                        return $this->cookies[$name];
                }
index 247f810..48767d0 100644 (file)
@@ -27,7 +27,7 @@
 # This must be done before any globals are set by the code
 if ( ini_get( 'register_globals' ) ) {
        if ( isset( $_REQUEST['GLOBALS'] ) || isset( $_FILES['GLOBALS'] ) ) {
-               die( '<a href="http://www.hardened-php.net/globals-problem">$GLOBALS overwrite vulnerability</a>');
+               die( '<a href="http://www.hardened-php.net/globals-problem">$GLOBALS overwrite vulnerability</a>' );
        }
        $verboten = array(
                'GLOBALS',
@@ -62,7 +62,7 @@ if ( ini_get( 'register_globals' ) ) {
 # points and when $wgOut gets disabled or overridden.
 header( 'X-Content-Type-Options: nosniff' );
 
-$wgRequestTime = microtime(true);
+$wgRequestTime = microtime( true );
 # getrusage() does not exist on the Microsoft Windows platforms, catching this
 if ( function_exists ( 'getrusage' ) ) {
        $wgRUstart = getrusage();
@@ -80,11 +80,15 @@ define( 'MEDIAWIKI', true );
 
 # Full path to working directory.
 # Makes it possible to for example to have effective exclude path in apc.
-# Also doesn't break installations using symlinked includes, like
-# __DIR__ would do.
+# __DIR__ breaks symlinked includes, but realpath() returns false
+# if we don't have permissions on parent directories.
 $IP = getenv( 'MW_INSTALL_PATH' );
 if ( $IP === false ) {
-       $IP = realpath( '.' );
+       if( realpath( '.' ) ) {
+               $IP = realpath( '.' );
+       } else {
+               $IP = dirname( __DIR__ );
+       }
 }
 
 if ( isset( $_SERVER['MW_COMPILED'] ) ) {
@@ -119,7 +123,7 @@ if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
        MWFunction::call( MW_CONFIG_CALLBACK );
 } else {
        if ( !defined( 'MW_CONFIG_FILE' ) ) {
-               define('MW_CONFIG_FILE', MWInit::interpretedPath( 'LocalSettings.php' ) );
+               define( 'MW_CONFIG_FILE', MWInit::interpretedPath( 'LocalSettings.php' ) );
        }
 
        # LocalSettings.php is the per site customization file. If it does not exist
index 7604241..21a7d9a 100644 (file)
@@ -126,7 +126,7 @@ class MediaWiki {
         * @return Title
         */
        public function getTitle() {
-               if( $this->context->getTitle() === null ){
+               if( $this->context->getTitle() === null ) {
                        $this->context->setTitle( $this->parseTitle() );
                }
                return $this->context->getTitle();
@@ -507,7 +507,7 @@ class MediaWiki {
                        && $request->getMethod() == 'GET'
                ) {
                        $redirUrl = $request->getFullRequestURL();
-                       $redirUrl = str_replace( 'http://' , 'https://' , $redirUrl );
+                       $redirUrl = str_replace( 'http://', 'https://', $redirUrl );
 
                        // Setup dummy Title, otherwise OutputPage::redirect will fail
                        $title = Title::newFromText( NS_MAIN, 'REDIR' );
index 0114cce..fa23072 100644 (file)
@@ -42,7 +42,7 @@ class WikiFilePage extends WikiPage {
 
        public function getActionOverrides() {
                $overrides = parent::getActionOverrides();
-               $overrides[ 'revert' ] = 'RevertFileAction';
+               $overrides['revert'] = 'RevertFileAction';
                return $overrides;
        }
 
index e2cd5d9..6048294 100644 (file)
@@ -23,7 +23,7 @@
 /**
  * Abstract class for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
  */
-abstract class Page {}
+interface Page {}
 
 /**
  * Class representing a MediaWiki article and history.
@@ -33,7 +33,7 @@ abstract class Page {}
  *
  * @internal documentation reviewed 15 Mar 2010
  */
-class WikiPage extends Page implements IDBAccessObject {
+class WikiPage implements Page, IDBAccessObject {
        // Constants for $mDataLoadedFrom and related
 
        /**
@@ -1139,7 +1139,7 @@ class WikiPage extends Page implements IDBAccessObject {
        public function doPurge() {
                global $wgUseSquid;
 
-               if( !wfRunHooks( 'ArticlePurge', array( &$this ) ) ){
+               if( !wfRunHooks( 'ArticlePurge', array( &$this ) ) ) {
                        return false;
                }
 
@@ -1948,7 +1948,7 @@ class WikiPage extends Page implements IDBAccessObject {
        public function prepareTextForEdit( $text, $revid = null, User $user = null ) {
                ContentHandler::deprecated( __METHOD__, '1.21' );
                $content = ContentHandler::makeContent( $text, $this->getTitle() );
-               return $this->prepareContentForEdit( $content, $revid , $user );
+               return $this->prepareContentForEdit( $content, $revid, $user );
        }
 
        /**
@@ -2151,7 +2151,7 @@ class WikiPage extends Page implements IDBAccessObject {
                ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $content = ContentHandler::makeContent( $text, $this->getTitle() );
-               return $this->doQuickEditContent( $content, $user, $comment , $minor );
+               return $this->doQuickEditContent( $content, $user, $comment, $minor );
        }
 
        /**
@@ -2274,9 +2274,14 @@ class WikiPage extends Page implements IDBAccessObject {
 
                $encodedExpiry = array();
                $protectDescription = '';
+               # Some bots may parse IRC lines, which are generated from log entries which contain plain
+               # protect description text. Keep them in old format to avoid breaking compatibility.
+               # TODO: Fix protection log to store structured description and format it on-the-fly.
+               $protectDescriptionLog = '';
                foreach ( $limit as $action => $restrictions ) {
                        $encodedExpiry[$action] = $dbw->encodeExpiry( $expiry[$action] );
                        if ( $restrictions != '' ) {
+                               $protectDescriptionLog .= $wgContLang->getDirMark() . "[$action=$restrictions] (";
                                # $action is one of $wgRestrictionTypes = array( 'create', 'edit', 'move', 'upload' ).
                                # All possible message keys are listed here for easier grepping:
                                # * restriction-create
@@ -2292,8 +2297,8 @@ class WikiPage extends Page implements IDBAccessObject {
                                if ( $encodedExpiry[$action] != 'infinity' ) {
                                        $expiryText = wfMessage(
                                                'protect-expiring',
-                                               $wgContLang->timeanddate( $expiry[$action], false, false ) ,
-                                               $wgContLang->date( $expiry[$action], false, false ) ,
+                                               $wgContLang->timeanddate( $expiry[$action], false, false ),
+                                               $wgContLang->date( $expiry[$action], false, false ),
                                                $wgContLang->time( $expiry[$action], false, false )
                                        )->inContentLanguage()->text();
                                } else {
@@ -2307,8 +2312,10 @@ class WikiPage extends Page implements IDBAccessObject {
                                $protectDescription .= wfMessage( 'protect-summary-desc' )
                                        ->params( $actionText, $restrictionsText, $expiryText )
                                        ->inContentLanguage()->text();
+                               $protectDescriptionLog .= $expiryText . ') ';
                        }
                }
+               $protectDescriptionLog = trim( $protectDescriptionLog );
 
                if ( $id ) { // Protection of existing page
                        if ( !wfRunHooks( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
@@ -2350,7 +2357,7 @@ class WikiPage extends Page implements IDBAccessObject {
                                )->inContentLanguage()->text()
                        );
                        if ( $reason ) {
-                               $editComment .= ": $reason";
+                               $editComment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
                        }
                        if ( $protectDescription ) {
                                $editComment .= wfMessage( 'word-separator' )->inContentLanguage()->text();
@@ -2413,7 +2420,7 @@ class WikiPage extends Page implements IDBAccessObject {
                if ( $logAction == 'unprotect' ) {
                        $logParams = array();
                } else {
-                       $logParams = array( $protectDescription, $cascade ? 'cascade' : '' );
+                       $logParams = array( $protectDescriptionLog, $cascade ? 'cascade' : '' );
                }
 
                // Update the protection log
@@ -3027,10 +3034,10 @@ class WikiPage extends Page implements IDBAccessObject {
                $removeFields = array( 'cat_pages = cat_pages - 1' );
 
                if ( $ns == NS_CATEGORY ) {
-                       $addFields[]    = 'cat_subcats = cat_subcats + 1';
+                       $addFields[] = 'cat_subcats = cat_subcats + 1';
                        $removeFields[] = 'cat_subcats = cat_subcats - 1';
                } elseif ( $ns == NS_FILE ) {
-                       $addFields[]    = 'cat_files = cat_files + 1';
+                       $addFields[] = 'cat_files = cat_files + 1';
                        $removeFields[] = 'cat_files = cat_files - 1';
                }
 
@@ -3308,7 +3315,7 @@ class PoolWorkArticleView extends PoolCounterWork {
         * @param $content Content|String: content to parse or null to load it; may also be given as a wikitext string, for BC
         */
        function __construct( Page $page, ParserOptions $parserOptions, $revid, $useParserCache, $content = null ) {
-               if ( is_string($content) ) { // BC: old style call
+               if ( is_string( $content ) ) { // BC: old style call
                        $modelId = $page->getRevision()->getContentModel();
                        $format = $page->getRevision()->getContentFormat();
                        $content = ContentHandler::makeContent( $content, $page->getTitle(), $modelId, $format );
@@ -3451,4 +3458,3 @@ class PoolWorkArticleView extends PoolCounterWork {
                return false;
        }
 }
-
index d5e9189..158a6b5 100644 (file)
@@ -86,7 +86,7 @@ class Xml {
         * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default)
         * @return string
         */
-       public static function elementClean( $element, $attribs = array(), $contents = '') {
+       public static function elementClean( $element, $attribs = array(), $contents = '' ) {
                global $wgContLang;
                if( $attribs ) {
                        $attribs = array_map( array( 'UtfNormal', 'cleanUp' ), $attribs );
@@ -192,7 +192,7 @@ class Xml {
                } elseif( $encMonth ) {
                        $thisMonth = intval( gmdate( 'n' ) );
                        $thisYear = intval( gmdate( 'Y' ) );
-                       if( intval($encMonth) > $thisMonth ) {
+                       if( intval( $encMonth ) > $thisMonth ) {
                                $thisYear--;
                        }
                        $encYear = $thisYear;
@@ -369,10 +369,10 @@ class Xml {
                $a = array( 'for' => $id );
 
                # FIXME avoid copy pasting below:
-               if( isset( $attribs['class'] ) ){
+               if( isset( $attribs['class'] ) ) {
                                $a['class'] = $attribs['class'];
                }
-               if( isset( $attribs['title'] ) ){
+               if( isset( $attribs['title'] ) ) {
                                $a['title'] = $attribs['title'];
                }
 
@@ -500,7 +500,7 @@ class Xml {
                                } elseif ( substr( $value, 0, 1) == '*' && substr( $value, 1, 1) != '*' ) {
                                        // A new group is starting ...
                                        $value = trim( substr( $value, 1 ) );
-                                       if( $optgroup ) $options .= self::closeElement('optgroup');
+                                       if( $optgroup ) $options .= self::closeElement( 'optgroup' );
                                        $options .= self::openElement( 'optgroup', array( 'label' => $value ) );
                                        $optgroup = true;
                                } elseif ( substr( $value, 0, 2) == '**' ) {
@@ -509,13 +509,13 @@ class Xml {
                                        $options .= self::option( $value, $value, $selected === $value );
                                } else {
                                        // groupless reason list
-                                       if( $optgroup ) $options .= self::closeElement('optgroup');
+                                       if( $optgroup ) $options .= self::closeElement( 'optgroup' );
                                        $options .= self::option( $value, $value, $selected === $value );
                                        $optgroup = false;
                                }
                        }
 
-                       if( $optgroup ) $options .= self::closeElement('optgroup');
+                       if( $optgroup ) $options .= self::closeElement( 'optgroup' );
 
                $attribs = array();
 
@@ -636,10 +636,10 @@ class Xml {
                } elseif ( is_null( $value ) ) {
                        $s = 'null';
                } elseif ( is_int( $value ) || is_float( $value ) ) {
-                       $s = strval($value);
+                       $s = strval( $value );
                } elseif ( is_array( $value ) && // Make sure it's not associative.
-                                       array_keys($value) === range( 0, count($value) - 1 ) ||
-                                       count($value) == 0
+                                       array_keys( $value ) === range( 0, count( $value ) - 1 ) ||
+                                       count( $value ) == 0
                                ) {
                        $s = '[';
                        foreach ( $value as $elt ) {
@@ -764,7 +764,7 @@ class Xml {
                foreach( $fields as $labelmsg => $input ) {
                        $id = "mw-$labelmsg";
                        $form .= Xml::openElement( 'tr', array( 'id' => $id ) );
-                       $form .= Xml::tags( 'td', array('class' => 'mw-label'), wfMessage( $labelmsg )->parse() );
+                       $form .= Xml::tags( 'td', array( 'class' => 'mw-label' ), wfMessage( $labelmsg )->parse() );
                        $form .= Xml::openElement( 'td', array( 'class' => 'mw-input' ) ) . $input . Xml::closeElement( 'td' );
                        $form .= Xml::closeElement( 'tr' );
                }
index ccdf2bb..fc36b1f 100644 (file)
@@ -181,7 +181,7 @@ class ZipDirectoryReader {
         * Throw an error, and log a debug message
         */
        function error( $code, $debugMessage ) {
-               wfDebug( __CLASS__.": Fatal error: $debugMessage\n" );
+               wfDebug( __CLASS__ . ": Fatal error: $debugMessage\n" );
                throw new ZipDirectoryReaderError( $code );
        }
 
@@ -220,7 +220,7 @@ class ZipDirectoryReader {
                if ( $structSize + $this->eocdr['file comment length'] != strlen( $block ) - $sigPos ) {
                        $this->error( 'zip-bad', 'trailing bytes after the end of the file comment' );
                }
-               if (   $this->eocdr['disk'] !== 0
+               if ( $this->eocdr['disk'] !== 0
                        || $this->eocdr['CD start disk'] !== 0 )
                {
                        $this->error( 'zip-unsupported', 'more than one disk (in EOCDR)' );
@@ -262,7 +262,7 @@ class ZipDirectoryReader {
         * may replace the regular "end of central directory record" in ZIP64 files.
         */
        function readZip64EndOfCentralDirectoryRecord() {
-               if (   $this->eocdr64Locator['eocdr64 start disk'] != 0
+               if ( $this->eocdr64Locator['eocdr64 start disk'] != 0
                        || $this->eocdr64Locator['number of disks'] != 0 )
                {
                        $this->error( 'zip-unsupported', 'more than one disk (in EOCDR64 locator)' );
@@ -286,7 +286,7 @@ class ZipDirectoryReader {
                if ( $data['signature'] !== "PK\x06\x06" ) {
                        $this->error( 'zip-bad', 'wrong signature on Zip64 end of central directory record' );
                }
-               if (   $data['disk'] !== 0
+               if ( $data['disk'] !== 0
                        || $data['CD start disk'] !== 0 )
                {
                        $this->error( 'zip-unsupported', 'more than one disk (in EOCDR64)' );
@@ -327,7 +327,7 @@ class ZipDirectoryReader {
                $offset = $this->eocdr['CD offset'];
                $numEntries = $this->eocdr['CD entries total'];
                $endPos = $this->eocdr['position'];
-               if (   $size == 0xffffffff
+               if ( $size == 0xffffffff
                        || $offset == 0xffffffff
                        || $numEntries == 0xffff )
                {
@@ -395,7 +395,7 @@ class ZipDirectoryReader {
                        $data += $this->unpack( $block, $variableInfo, $pos );
                        $pos += $this->getStructSize( $variableInfo );
 
-                       if (   $this->zip64 && (
+                       if ( $this->zip64 && (
                                   $data['compressed size'] == 0xffffffff
                                || $data['uncompressed size'] == 0xffffffff
                                || $data['local header offset'] == 0xffffffff ) )
@@ -618,7 +618,7 @@ class ZipDirectoryReader {
                                        $pos += $fieldSize;
                                        break;
                                default:
-                                       throw new MWException( __METHOD__.": invalid type \"$typeName\"" );
+                                       throw new MWException( __METHOD__ . ": invalid type \"$typeName\"" );
                                }
                        } else {
                                // Unsigned little-endian integer
index 051fa42..d26228a 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 /**
- * This class handles printing the history page for an article.  In order to
+ * This class handles printing the history page for an article. In order to
  * be efficient, it uses timestamps rather than offsets for paging, to avoid
  * costly LIMIT,offset queries.
  *
@@ -132,7 +132,7 @@ class HistoryAction extends FormlessAction {
                                array( 'delete', 'move' ),
                                $this->getTitle(),
                                '',
-                               array(  'lim' => 10,
+                               array( 'lim' => 10,
                                        'conds' => array( "log_action != 'revision'" ),
                                        'showIfEmpty' => false,
                                        'msgKey' => array( 'moveddeleted-notice' )
@@ -176,7 +176,7 @@ class HistoryAction extends FormlessAction {
                        ) .
                        Html::hidden( 'title', $this->getTitle()->getPrefixedDBKey() ) . "\n" .
                        Html::hidden( 'action', 'history' ) . "\n" .
-                       Xml::dateMenu( $year, $month ) . '&#160;' .
+                       Xml::dateMenu( ( $year == null ? date( "Y" ) : $year ), $month ) . '&#160;' .
                        ( $tagSelector ? ( implode( '&#160;', $tagSelector ) . '&#160;' ) : '' ) .
                        $checkDeleted .
                        Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "\n" .
@@ -515,7 +515,7 @@ class HistoryPager extends ReverseChronologicalPager {
        function submitButton( $message, $attributes = array() ) {
                # Disable submit button if history has 1 revision only
                if ( $this->getNumRows() > 1 ) {
-                       return Xml::submitButton( $message , $attributes );
+                       return Xml::submitButton( $message, $attributes );
                } else {
                        return '';
                }
@@ -609,7 +609,7 @@ class HistoryPager extends ReverseChronologicalPager {
                                ? $this->parentLens[$row->rev_parent_id]
                                : 0;
                        $sDiff = ChangesList::showCharacterDifference( $prevSize, $rev->getSize() );
-                       $fSize = Linker::formatRevisionSize($rev->getSize());
+                       $fSize = Linker::formatRevisionSize( $rev->getSize() );
                        $s .= ' <span class="mw-changeslist-separator">. .</span> ' . "$fSize $sDiff";
                }
 
@@ -617,7 +617,7 @@ class HistoryPager extends ReverseChronologicalPager {
                $s2 = Linker::revComment( $rev, false, true );
 
                if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
-                       $s2 .= ' <span class="updatedmarker">' .  $this->msg( 'updatedmarker' )->escaped() . '</span>';
+                       $s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>';
                        $classes[] = 'mw-history-line-updated';
                }
 
@@ -671,7 +671,7 @@ class HistoryPager extends ReverseChronologicalPager {
                        $s .= ' <span class="mw-changeslist-separator">. .</span> ' . $s2;
                }
 
-               wfRunHooks( 'PageHistoryLineEnding', array( $this, &$row , &$s, &$classes ) );
+               wfRunHooks( 'PageHistoryLineEnding', array( $this, &$row, &$s, &$classes ) );
 
                $attribs = array();
                if ( $classes ) {
index 956104c..b61978c 100644 (file)
@@ -81,11 +81,11 @@ class InfoAction extends FormlessAction {
 
                // Hide "This page is a member of # hidden categories" explanation
                $content .= Html::element( 'style', array(),
-                       '.mw-hiddenCategoriesExplanation { display: none; }' );
+                       '.mw-hiddenCategoriesExplanation { display: none; }' ) . "\n";
 
                // Hide "Templates used on this page" explanation
                $content .= Html::element( 'style', array(),
-                       '.mw-templatesUsedExplanation { display: none; }' );
+                       '.mw-templatesUsedExplanation { display: none; }' ) . "\n";
 
                // Get page information
                $pageInfo = $this->pageInfo();
@@ -95,14 +95,14 @@ class InfoAction extends FormlessAction {
 
                // Render page information
                foreach ( $pageInfo as $header => $infoTable ) {
-                       $content .= $this->makeHeader( $this->msg( "pageinfo-${header}" )->escaped() );
-                       $table = '';
+                       $content .= $this->makeHeader( $this->msg( "pageinfo-${header}" )->escaped() ) . "\n";
+                       $table = "\n";
                        foreach ( $infoTable as $infoRow ) {
                                $name = ( $infoRow[0] instanceof Message ) ? $infoRow[0]->escaped() : $infoRow[0];
                                $value = ( $infoRow[1] instanceof Message ) ? $infoRow[1]->escaped() : $infoRow[1];
-                               $table = $this->addRow( $table, $name, $value );
+                               $table = $this->addRow( $table, $name, $value ) . "\n";
                        }
-                       $content = $this->addTable( $content, $table );
+                       $content = $this->addTable( $content, $table ) . "\n";
                }
 
                // Page footer
@@ -125,8 +125,7 @@ class InfoAction extends FormlessAction {
         * @return string The HTML.
         */
        protected function makeHeader( $header ) {
-               global $wgParser;
-               $spanAttribs = array( 'class' => 'mw-headline', 'id' => $wgParser->guessSectionNameFromWikiText( $header ) );
+               $spanAttribs = array( 'class' => 'mw-headline', 'id' => Sanitizer::escapeId( $header ) );
                return Html::rawElement( 'h2', array(), Html::element( 'span', $spanAttribs, $header ) );
        }
 
@@ -274,6 +273,11 @@ class InfoAction extends FormlessAction {
                        $pageInfo['header-basic'][] = array(
                                $this->msg( 'pageinfo-watchers' ), $lang->formatNum( $pageCounts['watchers'] )
                        );
+               } elseif ( $wgUnwatchedPageThreshold !== false ) {
+                       $pageInfo['header-basic'][] = array(
+                               $this->msg( 'pageinfo-watchers' ),
+                               $this->msg( 'pageinfo-few-watchers' )->numParams( $wgUnwatchedPageThreshold )
+                       );
                }
 
                // Redirects to this page
@@ -386,6 +390,22 @@ class InfoAction extends FormlessAction {
                $pageInfo['header-edits'] = array();
 
                $firstRev = $this->page->getOldestRevision();
+               $lastRev = $this->page->getRevision();
+               $batch = new LinkBatch;
+
+               $firstRevUser = $firstRev->getUserText( Revision::FOR_THIS_USER );
+               if ( $firstRevUser !== '' ) {
+                       $batch->add( NS_USER, $firstRevUser );
+                       $batch->add( NS_USER_TALK, $firstRevUser );
+               }
+
+               $lastRevUser = $lastRev->getUserText( Revision::FOR_THIS_USER );
+               if ( $lastRevUser !== '' ) {
+                       $batch->add( NS_USER, $lastRevUser );
+                       $batch->add( NS_USER_TALK, $lastRevUser );
+               }
+
+               $batch->execute();
 
                // Page creator
                $pageInfo['header-edits'][] = array(
@@ -407,7 +427,7 @@ class InfoAction extends FormlessAction {
                // Latest editor
                $pageInfo['header-edits'][] = array(
                        $this->msg( 'pageinfo-lastuser' ),
-                       Linker::revUserTools( $this->page->getRevision() )
+                       Linker::revUserTools( $lastRev )
                );
 
                // Date of latest edit
index cd58889..4c5171c 100644 (file)
@@ -62,7 +62,7 @@ class PurgeAction extends FormAction {
                $this->checkCanExecute( $this->getUser() );
 
                if ( $this->getUser()->isAllowed( 'purge' ) ) {
-                       $this->redirectParams = wfArrayToCGI( array_diff_key(
+                       $this->redirectParams = wfArrayToCgi( array_diff_key(
                                $this->getRequest()->getQueryValues(),
                                array( 'title' => null, 'action' => null )
                        ) );
index 71cb397..da6ba1e 100644 (file)
@@ -204,7 +204,7 @@ class RawAction extends FormlessAction {
                                        $oldid = $this->page->getLatest();
                                }
                                $prev = $this->getTitle()->getPreviousRevisionId( $oldid );
-                               $oldid = $prev ? $prev : -1 ;
+                               $oldid = $prev ? $prev : -1;
                                break;
                        case 'cur':
                                $oldid = 0;
index 78525e0..aff7a2e 100644 (file)
@@ -66,7 +66,15 @@ abstract class ApiBase extends ContextSource {
        const LIMIT_SML1 = 50; // Slow query, std user limit
        const LIMIT_SML2 = 500; // Slow query, bot/sysop limit
 
+       /**
+        * getAllowedParams() flag: When set, the result could take longer to generate,
+        * but should be more thorough. E.g. get the list of generators for ApiSandBox extension
+        * @since 1.21
+        */
+       const GET_VALUES_FOR_HELP = 1;
+
        private $mMainModule, $mModuleName, $mModulePrefix;
+       private $mSlaveDB = null;
        private $mParamCache = array();
 
        /**
@@ -105,7 +113,7 @@ abstract class ApiBase extends ContextSource {
         * The result data should be stored in the ApiResult object available
         * through getResult().
         */
-       public abstract function execute();
+       abstract public function execute();
 
        /**
         * Returns a string that identifies the version of the extending class.
@@ -127,6 +135,16 @@ abstract class ApiBase extends ContextSource {
                return $this->mModuleName;
        }
 
+
+       /**
+        * Get the module manager, or null if this module has no sub-modules
+        * @since 1.21
+        * @return ApiModuleManager
+        */
+       public function getModuleManager() {
+               return null;
+       }
+
        /**
         * Get parameter prefix (usually two letters or an empty string).
         * @return string
@@ -212,21 +230,27 @@ abstract class ApiBase extends ContextSource {
        public function setWarning( $warning ) {
                $result = $this->getResult();
                $data = $result->getData();
-               if ( isset( $data['warnings'][$this->getModuleName()] ) ) {
+               $moduleName = $this->getModuleName();
+               if ( isset( $data['warnings'][$moduleName] ) ) {
                        // Don't add duplicate warnings
-                       $warn_regex = preg_quote( $warning, '/' );
-                       if ( preg_match( "/{$warn_regex}(\\n|$)/", $data['warnings'][$this->getModuleName()]['*'] ) ) {
-                               return;
+                       $oldWarning = $data['warnings'][$moduleName]['*'];
+                       $warnPos = strpos( $oldWarning, $warning );
+                       // If $warning was found in $oldWarning, check if it starts at 0 or after "\n"
+                       if ( $warnPos !== false && ( $warnPos === 0 || $oldWarning[$warnPos - 1] === "\n" ) ) {
+                               // Check if $warning is followed by "\n" or the end of the $oldWarning
+                               $warnPos += strlen( $warning );
+                               if ( strlen( $oldWarning ) <= $warnPos || $oldWarning[$warnPos] === "\n" ) {
+                                       return;
+                               }
                        }
-                       $oldwarning = $data['warnings'][$this->getModuleName()]['*'];
                        // If there is a warning already, append it to the existing one
-                       $warning = "$oldwarning\n$warning";
-                       $result->unsetValue( 'warnings', $this->getModuleName() );
+                       $warning = "$oldWarning\n$warning";
                }
                $msg = array();
                ApiResult::setContent( $msg, $warning );
                $result->disableSizeCheck();
-               $result->addValue( 'warnings', $this->getModuleName(), $msg );
+               $result->addValue( 'warnings', $moduleName,
+                       $msg, ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP );
                $result->enableSizeCheck();
        }
 
@@ -258,6 +282,8 @@ abstract class ApiBase extends ContextSource {
                        }
                        $msg = $lnPrfx . implode( $lnPrfx, $msg ) . "\n";
 
+                       $msg .= $this->makeHelpArrayToString( $lnPrfx, false, $this->getHelpUrls() );
+
                        if ( $this->isReadMode() ) {
                                $msg .= "\nThis module requires read rights";
                        }
@@ -301,8 +327,6 @@ abstract class ApiBase extends ContextSource {
                                        }
                                }
                        }
-
-                       $msg .= $this->makeHelpArrayToString( $lnPrfx, "Help page", $this->getHelpUrls() );
                }
 
                return $msg;
@@ -348,7 +372,7 @@ abstract class ApiBase extends ContextSource {
         * @return string or false
         */
        public function makeHelpMsgParameters() {
-               $params = $this->getFinalParams();
+               $params = $this->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
                if ( $params ) {
 
                        $paramsDescription = $this->getFinalParamDescription();
@@ -496,15 +520,22 @@ abstract class ApiBase extends ContextSource {
         * value) or (parameter name) => (array with PARAM_* constants as keys)
         * Don't call this function directly: use getFinalParams() to allow
         * hooks to modify parameters as needed.
+        *
+        * Some derived classes may choose to handle an integer $flags parameter
+        * in the overriding methods. Callers of this method can pass zero or
+        * more OR-ed flags like GET_VALUES_FOR_HELP.
+        *
         * @return array|bool
         */
-       protected function getAllowedParams() {
+       protected function getAllowedParams( /* $flags = 0 */ ) {
+               // int $flags is not declared because it causes "Strict standards"
+               // warning. Most derived classes do not implement it.
                return false;
        }
 
        /**
         * Returns an array of parameter descriptions.
-        * Don't call this functon directly: use getFinalParamDescription() to
+        * Don't call this function directly: use getFinalParamDescription() to
         * allow hooks to modify descriptions as needed.
         * @return array|bool False on no parameter descriptions
         */
@@ -516,11 +547,13 @@ abstract class ApiBase extends ContextSource {
         * Get final list of parameters, after hooks have had a chance to
         * tweak it as needed.
         *
+        * @param $flags int Zero or more flags like GET_VALUES_FOR_HELP
         * @return array|Bool False on no parameters
+        * @since 1.21 $flags param added
         */
-       public function getFinalParams() {
-               $params = $this->getAllowedParams();
-               wfRunHooks( 'APIGetAllowedParams', array( &$this, &$params ) );
+       public function getFinalParams( $flags = 0 ) {
+               $params = $this->getAllowedParams( $flags );
+               wfRunHooks( 'APIGetAllowedParams', array( &$this, &$params, $flags ) );
                return $params;
        }
 
@@ -654,7 +687,7 @@ abstract class ApiBase extends ContextSource {
                        array( $this, "parameterNotEmpty" ) ) ), $required );
 
                if ( count( $intersection ) > 1 ) {
-                       $this->dieUsage( "The parameters {$p}" . implode( ", {$p}",  $intersection ) . ' can not be used together', "{$p}invalidparammix" );
+                       $this->dieUsage( "The parameters {$p}" . implode( ", {$p}", $intersection ) . ' can not be used together', "{$p}invalidparammix" );
                } elseif ( count( $intersection ) == 0 ) {
                        $this->dieUsage( "One of the parameters {$p}" . implode( ", {$p}", $required ) . ' is required', "{$p}missingparam" );
                }
@@ -1303,8 +1336,8 @@ abstract class ApiBase extends ContextSource {
                // uploadMsgs
                'invalid-file-key' => array( 'code' => 'invalid-file-key', 'info' => 'Not a valid file key' ),
                'nouploadmodule' => array( 'code' => 'nouploadmodule', 'info' => 'No upload module set' ),
-               'uploaddisabled' => array( 'code' => 'uploaddisabled', 'info' => 'Uploads are not enabled.  Make sure $wgEnableUploads is set to true in LocalSettings.php and the PHP ini setting file_uploads is true' ),
-               'copyuploaddisabled' => array( 'code' => 'copyuploaddisabled', 'info' => 'Uploads by URL is not enabled.  Make sure $wgAllowCopyUploads is set to true in LocalSettings.php.' ),
+               'uploaddisabled' => array( 'code' => 'uploaddisabled', 'info' => 'Uploads are not enabled. Make sure $wgEnableUploads is set to true in LocalSettings.php and the PHP ini setting file_uploads is true' ),
+               'copyuploaddisabled' => array( 'code' => 'copyuploaddisabled', 'info' => 'Uploads by URL is not enabled. Make sure $wgAllowCopyUploads is set to true in LocalSettings.php.' ),
                'copyuploadbaddomain' => array( 'code' => 'copyuploadbaddomain', 'info' => 'Uploads by URL are not allowed from this domain.' ),
 
                'filename-tooshort' => array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ),
@@ -1369,7 +1402,7 @@ abstract class ApiBase extends ContextSource {
 
                // Check whether the error array was nested
                // array( array( <code>, <params> ), array( <another_code>, <params> ) )
-               if( is_array( $key ) ){
+               if( is_array( $key ) ) {
                        $error = $key;
                        $key = array_shift( $error );
                }
@@ -1640,10 +1673,16 @@ abstract class ApiBase extends ContextSource {
        }
 
        /**
+        * Gets a default slave database connection object
         * @return DatabaseBase
         */
        protected function getDB() {
-               return wfGetDB( DB_SLAVE, 'api' );
+               if ( !isset( $this->mSlaveDB ) ) {
+                       $this->profileDBIn();
+                       $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
+                       $this->profileDBOut();
+               }
+               return $this->mSlaveDB;
        }
 
        /**
index b58be11..2e4155a 100644 (file)
  */
 class ApiBlock extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Blocks the user specified in the parameters for the given expiry, with the
         * given reason, and with all other settings provided in the params. If the block
@@ -108,7 +104,7 @@ class ApiBlock extends ApiBase {
                $res['userID'] = $target instanceof User ? $target->getId() : 0;
 
                $block = Block::newFromTarget( $target );
-               if( $block instanceof Block ){
+               if( $block instanceof Block ) {
                        $res['expiry'] = $block->mExpiry == $this->getDB()->getInfinity()
                                ? 'infinite'
                                : wfTimestamp( TS_ISO_8601, $block->mExpiry );
index 230ed33..6b894c1 100644 (file)
 
 class ApiComparePages extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $params = $this->extractRequestParams();
 
@@ -85,11 +81,11 @@ class ApiComparePages extends ApiBase {
         * @return int
         */
        private function revisionOrTitleOrId( $revision, $titleText, $titleId ) {
-               if( $revision ){
+               if( $revision ) {
                        return $revision;
                } elseif( $titleText ) {
                        $title = Title::newFromText( $titleText );
-                       if( !$title ){
+                       if( !$title ) {
                                $this->dieUsageMsg( array( 'invalidtitle', $titleText ) );
                        }
                        return $title->getLatestRevID();
index 0209fb1..b6c6210 100644 (file)
@@ -89,8 +89,16 @@ class ApiCreateAccount extends ApiBase {
                        // Save settings (including confirmation token)
                        $user->saveSettings();
 
-                       wfRunHooks( 'AddNewAccount', array( $user, false ) );
-                       $user->addNewUserLogEntry( $this->getUser()->isAnon(), $params['reason'] );
+                       wfRunHooks( 'AddNewAccount', array( $user, $params['mailpassword'] ) );
+
+                       if ( $params['mailpassword'] ) {
+                               $logAction = 'byemail';
+                       } elseif ( $this->getUser()->isLoggedIn() ) {
+                               $logAction = 'create2';
+                       } else {
+                               $logAction = 'create';
+                       }
+                       $user->addNewUserLogEntry( $logAction, (string)$params['reason'] );
 
                        // Add username, id, and token to result.
                        $result['username'] = $user->getName();
@@ -181,15 +189,15 @@ class ApiCreateAccount extends ApiBase {
        public function getParamDescription() {
                $p = $this->getModulePrefix();
                return array(
-                       'name' => 'User Name',
+                       'name' => 'Username',
                        'password' => "Password (ignored if {$p}mailpassword is set)",
-                       'domain' => 'Domain (optional)',
+                       'domain' => 'Domain for external authentication (optional)',
                        'token' => 'Account creation token obtained in first request',
-                       'email' => 'Email address of user',
-                       'realname' => 'Real Name of user',
-                       'mailpassword' => 'Whether to generate and mail a random password to the user',
-                       'reason' => "Optional reason for creating the account (used when {$p}mailpassword is set)",
-                       'language' => 'Language code to set for the user.'
+                       'email' => 'E-mail address of user (optional)',
+                       'realname' => 'Real name of user (optional)',
+                       'mailpassword' => 'If set to any value, a random password will be e-mailed to the user',
+                       'reason' => 'Optional reason for creating the account to be put in the logs',
+                       'language' => 'Language code to set as default for the user (optional, defaults to content language)'
                );
        }
 
@@ -256,6 +264,6 @@ class ApiCreateAccount extends ApiBase {
        }
 
        public function getHelpUrls() {
-               return 'https://www.mediawiki.org/wiki/API:Account creation';
+               return 'https://www.mediawiki.org/wiki/API:Account_creation';
        }
 }
index cfa8035..422524d 100644 (file)
  */
 class ApiDelete extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Extracts the title, token, and reason from the request parameters and invokes
         * the local delete() function with these as arguments. It does not make use of
index ebcfa01..e5ef3b7 100644 (file)
  */
 class ApiDisabled extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $this->dieUsage( "The \"{$this->getModuleName()}\" module has been disabled.", 'moduledisabled' );
        }
index 74d3e14..b642c6d 100644 (file)
  */
 class ApiEditPage extends ApiBase {
 
-       public function __construct( $query, $moduleName ) {
-               parent::__construct( $query, $moduleName );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
@@ -307,7 +303,13 @@ class ApiEditPage extends ApiBase {
                // TODO: Make them not or check if they still do
                $wgTitle = $titleObj;
 
-               $articleObject = new Article( $titleObj );
+               $articleContext = new RequestContext;
+               $articleContext->setRequest( $req );
+               $articleContext->setWikiPage( $pageObj );
+               $articleContext->setUser( $this->getUser() );
+
+               $articleObject = Article::newFromWikiPage( $pageObj, $articleContext );
+
                $ep = new EditPage( $articleObject );
 
                // allow editing of non-textual content.
@@ -407,7 +409,6 @@ class ApiEditPage extends ApiBase {
                                } else {
                                        $r['oldrevid'] = intval( $oldRevId );
                                        $r['newrevid'] = intval( $newRevId );
-                                       $pageObj->clear();
                                        $r['newtimestamp'] = wfTimestamp( TS_ISO_8601,
                                                $pageObj->getTimestamp() );
                                }
index ba8edc0..5a5c572 100644 (file)
  */
 class ApiEmailUser extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $params = $this->extractRequestParams();
 
index f740cf8..826171b 100644 (file)
  */
 class ApiExpandTemplates extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                // Cache may vary on $wgUser because ParserOptions gets data from it
                $this->getMain()->setCacheMode( 'anon-public-user-private' );
index 2f02674..015a992 100644 (file)
  */
 class ApiFeedContributions extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * This module uses a custom feed wrapper printer.
         *
index 7a91641..a3b4682 100644 (file)
  */
 class ApiFeedWatchlist extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * This module uses a custom feed wrapper printer.
         *
index 1e463e5..9520dc7 100644 (file)
@@ -37,10 +37,6 @@ class ApiFileRevert extends ApiBase {
 
        protected $params;
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $this->params = $this->extractRequestParams();
                // Extract the file and archiveName from the request parameters
@@ -73,8 +69,8 @@ class ApiFileRevert extends ApiBase {
        protected function checkPermissions( $user ) {
                $title = $this->file->getTitle();
                $permissionErrors = array_merge(
-                       $title->getUserPermissionsErrors( 'edit' , $user ),
-                       $title->getUserPermissionsErrors( 'upload' , $user )
+                       $title->getUserPermissionsErrors( 'edit', $user ),
+                       $title->getUserPermissionsErrors( 'upload', $user )
                );
 
                if ( $permissionErrors ) {
index e8edb3d..a24953a 100644 (file)
@@ -58,7 +58,7 @@ abstract class ApiFormatBase extends ApiBase {
         * This method is not called if getIsHtml() returns true.
         * @return string
         */
-       public abstract function getMimeType();
+       abstract public function getMimeType();
 
        /**
         * Whether this formatter needs raw data such as _element tags
@@ -123,11 +123,13 @@ abstract class ApiFormatBase extends ApiBase {
 
        /**
         * Initialize the printer function and prepare the output headers, etc.
-        * This method must be the first outputing method during execution.
-        * A help screen's header is printed for the HTML-based output
-        * @param $isError bool Whether an error message is printed
+        * This method must be the first outputting method during execution.
+        * A human-targeted notice about available formats is printed for the HTML-based output,
+        * except for help screens (caused by either an error in the API parameters,
+        * the calling of action=help, or requesting the root script api.php).
+        * @param $isHelpScreen bool Whether a help screen is going to be shown
         */
-       function initPrinter( $isError ) {
+       function initPrinter( $isHelpScreen ) {
                if ( $this->mDisabled ) {
                        return;
                }
@@ -164,7 +166,7 @@ abstract class ApiFormatBase extends ApiBase {
 <?php
 
 
-                       if ( !$isError ) {
+                       if ( !$isHelpScreen ) {
 ?>
 <br />
 <small>
@@ -175,15 +177,18 @@ To see the non HTML representation of the <?php echo( $this->mFormat ); ?> forma
 See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>, or
 <a href='<?php echo( $script ); ?>'>API help</a> for more information.
 </small>
+<pre style='white-space: pre-wrap;'>
 <?php
 
 
-                       }
+                       } else { // don't wrap the contents of the <pre> for help screens
+                                 // because these are actually formatted to rely on
+                                 // the monospaced font for layout purposes
 ?>
 <pre>
 <?php
 
-
+                       }
                }
        }
 
@@ -248,7 +253,7 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
        }
 
        /**
-        * Sets whether the pretty-printer should format *bold* and $italics$
+        * Sets whether the pretty-printer should format *bold*
         * @param $help bool
         */
        public function setHelp( $help = true ) {
@@ -264,22 +269,19 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
        protected function formatHTML( $text ) {
                // Escape everything first for full coverage
                $text = htmlspecialchars( $text );
-
                // encode all comments or tags as safe blue strings
                $text = str_replace( '&lt;', '<span style="color:blue;">&lt;', $text );
                $text = str_replace( '&gt;', '&gt;</span>', $text );
-               // identify URLs
-               $protos = wfUrlProtocolsWithoutProtRel();
-               // This regex hacks around bug 13218 (&quot; included in the URL)
-               $text = preg_replace( "#(((?i)$protos).*?)(&quot;)?([ \\'\"<>\n]|&lt;|&gt;|&quot;)#", '<a href="\\1">\\1</a>\\3\\4', $text );
                // identify requests to api.php
                $text = preg_replace( "#api\\.php\\?[^ <\n\t]+#", '<a href="\\0">\\0</a>', $text );
                if ( $this->mHelp ) {
                        // make strings inside * bold
                        $text = preg_replace( "#\\*[^<>\n]+\\*#", '<b>\\0</b>', $text );
-                       // make strings inside $ italic
-                       $text = preg_replace( "#\\$[^<>\n]+\\$#", '<b><i>\\0</i></b>', $text );
                }
+               // identify URLs
+               $protos = wfUrlProtocolsWithoutProtRel();
+               // This regex hacks around bug 13218 (&quot; included in the URL)
+               $text = preg_replace( "#(((?i)$protos).*?)(&quot;)?([ \\'\"<>\n]|&lt;|&gt;|&quot;)#", '<a href="\\1">\\1</a>\\3\\4', $text );
 
                /**
                 * Temporary fix for bad links in help messages. As a special case,
index f280a29..1b2e02c 100644 (file)
  */
 class ApiFormatDbg extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                // This looks like it should be text/plain, but IE7 is so
                // brain-damaged it tries to parse text/plain as HTML if it
index db66083..62253e1 100644 (file)
  */
 class ApiFormatDump extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                // This looks like it should be text/plain, but IE7 is so
                // brain-damaged it tries to parse text/plain as HTML if it
index bee1ac9..78023af 100644 (file)
  */
 class ApiFormatNone extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'text/plain';
        }
index 99a047a..b2d1f04 100644 (file)
  */
 class ApiFormatPhp extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'application/vnd.php.serialized';
        }
index 3e1f592..4130e70 100644 (file)
  */
 class ApiFormatTxt extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                // This looks like it should be text/plain, but IE7 is so
                // brain-damaged it tries to parse text/plain as HTML if it
index fd1b327..62b69bb 100644 (file)
  */
 class ApiFormatWddx extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'text/xml';
        }
index 582e405..b4e8e33 100644 (file)
@@ -36,10 +36,6 @@ class ApiFormatXml extends ApiFormatBase {
        private $mIncludeNamespace = false;
        private $mXslt = null;
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'text/xml';
        }
@@ -92,7 +88,7 @@ class ApiFormatXml extends ApiFormatBase {
         *
         * @par Example:
         * @verbatim
-        * name='root',  value = array( '_element'=>'page', 'x', 'y', 'z')
+        * name='root', value = array( '_element'=>'page', 'x', 'y', 'z')
         * @endverbatim
         * creates:
         * @verbatim
@@ -105,7 +101,7 @@ class ApiFormatXml extends ApiFormatBase {
         *
         * @par Example:
         * @verbatim
-        * name='root',  value = array( '*'=>'text', 'lang'=>'en', 'id'=>10)
+        * name='root', value = array( '*'=>'text', 'lang'=>'en', 'id'=>10)
         * @endverbatim
         * creates:
         * @verbatim
@@ -205,7 +201,13 @@ class ApiFormatXml extends ApiFormatBase {
                                // ignore
                                break;
                        default:
-                               $retval .= $indstr . Xml::element( $elemName, null, $elemValue );
+                               // to make sure null value doesn't produce unclosed element,
+                               // which is what Xml::element( $elemName, null, null ) returns
+                               if ( $elemValue === null ) {
+                                       $retval .= $indstr . Xml::element( $elemName );
+                               } else {
+                                       $retval .= $indstr . Xml::element( $elemName, null, $elemValue );
+                               }
                                break;
                }
                return $retval;
index 28bb2e9..9cafc5b 100644 (file)
  */
 class ApiHelp extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Module for displaying help
         */
@@ -47,43 +43,62 @@ class ApiHelp extends ApiBase {
                }
 
                $this->getMain()->setHelp();
-
                $result = $this->getResult();
-               $queryObj = new ApiQuery( $this->getMain(), 'query' );
-               $r = array();
-               if ( is_array( $params['modules'] ) ) {
-                       $modArr = $this->getMain()->getModules();
 
-                       foreach ( $params['modules'] as $m ) {
-                               if ( !isset( $modArr[$m] ) ) {
-                                       $r[] = array( 'name' => $m, 'missing' => '' );
-                                       continue;
-                               }
-                               $module = new $modArr[$m]( $this->getMain(), $m );
-
-                               $r[] = $this->buildModuleHelp( $module, 'action' );
-                       }
+               if ( is_array( $params['modules'] ) ) {
+                       $modules = $params['modules'];
+               } else {
+                       $modules = array();
                }
 
                if ( is_array( $params['querymodules'] ) ) {
-                       $qmodArr = $queryObj->getModules();
+                       $queryModules = $params['querymodules'];
+                       foreach ( $queryModules as $m ) {
+                               $modules[] = 'query+' . $m;
+                       }
+               } else {
+                       $queryModules = array();
+               }
 
-                       foreach ( $params['querymodules'] as $qm ) {
-                               if ( !isset( $qmodArr[$qm] ) ) {
-                                       $r[] = array( 'name' => $qm, 'missing' => '' );
-                                       continue;
+               $r = array();
+               foreach ( $modules as $m ) {
+                       // sub-modules could be given in the form of "name[+name[+name...]]"
+                       $subNames = explode( '+', $m );
+                       if ( count( $subNames ) === 1 ) {
+                               // In case the '+' was typed into URL, it resolves as a space
+                               $subNames = explode( ' ', $m );
+                       }
+                       $module = $this->getMain();
+                       for ( $i = 0; $i < count( $subNames ); $i++ ) {
+                               $subs = $module->getModuleManager();
+                               if ( $subs === null ) {
+                                       $module = null;
+                               } else {
+                                       $module = $subs->getModule( $subNames[$i] );
                                }
-                               $module = new $qmodArr[$qm]( $this, $qm );
-                               $type = $queryObj->getModuleType( $qm );
-
-                               if ( $type === null ) {
-                                       $r[] = array( 'name' => $qm, 'missing' => '' );
-                                       continue;
+                               if ( $module === null ) {
+                                       if ( count( $subNames ) === 2
+                                                       && $i === 1
+                                                       && $subNames[0] === 'query'
+                                                       && in_array( $subNames[1], $queryModules )
+                                       ) {
+                                               // Legacy: This is one of the renamed 'querymodule=...' parameters,
+                                               // do not use '+' notation in the output, use submodule's name instead.
+                                               $name = $subNames[1];
+                                       } else {
+                                               $name = implode( '+', array_slice( $subNames, 0, $i + 1 ) );
+                                       }
+                                       $r[] = array( 'name' => $name, 'missing' => '' );
+                                       break;
+                               } else {
+                                       $type = $subs->getModuleGroup( $subNames[$i] );
                                }
-
+                       }
+                       if ( $module !== null ) {
                                $r[] = $this->buildModuleHelp( $module, $type );
                        }
                }
+
                $result->setIndexedTagName( $r, 'module' );
                $result->addValue( null, $this->getModuleName(), $r );
        }
@@ -118,15 +133,16 @@ class ApiHelp extends ApiBase {
                                ApiBase::PARAM_ISMULTI => true
                        ),
                        'querymodules' => array(
-                               ApiBase::PARAM_ISMULTI => true
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_DEPRECATED => true
                        ),
                );
        }
 
        public function getParamDescription() {
                return array(
-                       'modules' => 'List of module names (value of the action= parameter)',
-                       'querymodules' => 'List of query module names (value of prop=, meta= or list= parameter)',
+                       'modules' => 'List of module names (value of the action= parameter). Can specify submodules with a \'+\'',
+                       'querymodules' => 'Use modules=query+value instead. List of query module names (value of prop=, meta= or list= parameter)',
                );
        }
 
@@ -138,9 +154,8 @@ class ApiHelp extends ApiBase {
                return array(
                        'api.php?action=help' => 'Whole help page',
                        'api.php?action=help&modules=protect' => 'Module (action) help page',
-                       'api.php?action=help&querymodules=categorymembers' => 'Query (list) modules help page',
-                       'api.php?action=help&querymodules=info' => 'Query (prop) modules help page',
-                       'api.php?action=help&querymodules=siteinfo' => 'Query (meta) modules help page',
+                       'api.php?action=help&modules=query+categorymembers' => 'Help for the query/categorymembers module',
+                       'api.php?action=help&modules=login|query+info' => 'Help for the login and query/info modules',
                );
        }
 
index f5636bd..408805e 100644 (file)
  */
 class ApiImport extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
@@ -150,7 +146,7 @@ class ApiImport extends ApiBase {
 
        public function getDescription() {
                return array(
-                       'Import a page from another wiki, or an XML file.' ,
+                       'Import a page from another wiki, or an XML file.',
                        'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
                        'sending a file for the "xml" parameter.'
                );
index 00dd625..2ba92a6 100644 (file)
  */
 class ApiLogout extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $oldName = $user->getName();
index 3f82d3c..c3ae8b1 100644 (file)
@@ -131,8 +131,9 @@ class ApiMain extends ApiBase {
         */
        private $mPrinter;
 
-       private $mModules, $mModuleNames, $mFormats, $mFormatNames;
-       private $mResult, $mAction, $mEnableWrite;
+       private $mModuleMgr, $mResult;
+       private $mAction;
+       private $mEnableWrite;
        private $mInternalMode, $mSquidMaxage, $mModule;
 
        private $mCacheMode = 'private';
@@ -180,12 +181,11 @@ class ApiMain extends ApiBase {
                        }
                }
 
-               global $wgAPIModules; // extension modules
-               $this->mModules = $wgAPIModules + self::$Modules;
-
-               $this->mModuleNames = array_keys( $this->mModules );
-               $this->mFormats = self::$Formats;
-               $this->mFormatNames = array_keys( $this->mFormats );
+               global $wgAPIModules;
+               $this->mModuleMgr = new ApiModuleManager( $this );
+               $this->mModuleMgr->addModules( self::$Modules, 'action' );
+               $this->mModuleMgr->addModules( $wgAPIModules, 'action' );
+               $this->mModuleMgr->addModules( self::$Formats, 'format' );
 
                $this->mResult = new ApiResult( $this );
                $this->mEnableWrite = $enableWrite;
@@ -332,10 +332,11 @@ class ApiMain extends ApiBase {
         * @return ApiFormatBase
         */
        public function createPrinterByName( $format ) {
-               if ( !isset( $this->mFormats[$format] ) ) {
+               $printer = $this->mModuleMgr->getModule( $format, 'format' );
+               if ( $printer === null ) {
                        $this->dieUsage( "Unrecognized format: {$format}", 'unknown_format' );
                }
-               return new $this->mFormats[$format] ( $this, $format );
+               return $printer;
        }
 
        /**
@@ -384,7 +385,7 @@ class ApiMain extends ApiBase {
                                }
                        }
 
-                       // Handle any kind of exception by outputing properly formatted error message.
+                       // Handle any kind of exception by outputting properly formatted error message.
                        // If this fails, an unhandled exception should be thrown so that global error
                        // handler will process and log it.
 
@@ -604,7 +605,7 @@ class ApiMain extends ApiBase {
                if ( !isset ( $this->mPrinter ) ) {
                        // The printer has not been created yet. Try to manually get formatter value.
                        $value = $this->getRequest()->getVal( 'format', self::API_DEFAULT_FORMAT );
-                       if ( !in_array( $value, $this->mFormatNames ) ) {
+                       if ( !$this->mModuleMgr->isDefined( $value, 'format' ) ) {
                                $value = self::API_DEFAULT_FORMAT;
                        }
 
@@ -622,7 +623,6 @@ class ApiMain extends ApiBase {
                        if ( $this->mPrinter->getWantsHelp() || $this->mAction == 'help' ) {
                                ApiResult::setContent( $errMessage, $this->makeHelpMsg() );
                        }
-
                } else {
                        global $wgShowSQLErrors, $wgShowExceptionDetails;
                        // Something is seriously wrong
@@ -639,6 +639,10 @@ class ApiMain extends ApiBase {
                        ApiResult::setContent( $errMessage, $wgShowExceptionDetails ? "\n\n{$e->getTraceAsString()}\n\n" : '' );
                }
 
+               // Remember all the warnings to re-add them later
+               $oldResult = $result->getData();
+               $warnings = isset( $oldResult['warnings'] ) ? $oldResult['warnings'] : null;
+
                $result->reset();
                $result->disableSizeCheck();
                // Re-add the id
@@ -646,11 +650,13 @@ class ApiMain extends ApiBase {
                if ( !is_null( $requestid ) ) {
                        $result->addValue( null, 'requestid', $requestid );
                }
-
                if ( $wgShowHostnames ) {
                        // servedby is especially useful when debugging errors
                        $result->addValue( null, 'servedby', wfHostName() );
                }
+               if ( $warnings !== null ) {
+                       $result->addValue( null, 'warnings', $warnings );
+               }
 
                $result->addValue( null, 'error', $errMessage );
 
@@ -695,9 +701,10 @@ class ApiMain extends ApiBase {
         */
        protected function setupModule() {
                // Instantiate the module requested by the user
-               $module = new $this->mModules[$this->mAction] ( $this, $this->mAction );
-               $this->mModule = $module;
-
+               $module = $this->mModuleMgr->getModule( $this->mAction, 'action' );
+               if ( $module === null ) {
+                       $this->dieUsage( 'The API requires a valid action parameter', 'unknown_action' );
+               }
                $moduleParams = $module->extractRequestParams();
 
                // Die if token required, but not provided (unless there is a gettoken parameter)
@@ -809,6 +816,7 @@ class ApiMain extends ApiBase {
        protected function executeAction() {
                $params = $this->setupExecuteAction();
                $module = $this->setupModule();
+               $this->mModule = $module;
 
                $this->checkExecutePermissions( $module );
 
@@ -913,7 +921,13 @@ class ApiMain extends ApiBase {
                $paramsUsed = $this->getParamsUsed();
                $allParams = $this->getRequest()->getValueNames();
 
-               $unusedParams = array_diff( $allParams, $paramsUsed );
+               // Printer has not yet executed; don't warn that its parameters are unused
+               $printerParams = array_map(
+                       array( $this->mPrinter, 'encodeParamName' ),
+                       array_keys( $this->mPrinter->getFinalParams() ?: array() )
+               );
+
+               $unusedParams = array_diff( $allParams, $paramsUsed, $printerParams );
                if( count( $unusedParams ) ) {
                        $s = count( $unusedParams ) > 1 ? 's' : '';
                        $this->setWarning( "Unrecognized parameter$s: '" . implode( $unusedParams, "', '" ) . "'" );
@@ -928,7 +942,7 @@ class ApiMain extends ApiBase {
        protected function printResult( $isError ) {
                global $wgDebugAPI;
                if( $wgDebugAPI !== false ) {
-                       $this->getResult()->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
+                       $this->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
                }
 
                $this->getResult()->cleanUpUTF8();
@@ -940,10 +954,10 @@ class ApiMain extends ApiBase {
                 * tell the printer not to escape ampersands so that our links do
                 * not break.
                 */
-               $printer->setUnescapeAmps( ( $this->mAction == 'help' || $isError )
-                               && $printer->getFormat() == 'XML' && $printer->getIsHtml() );
+               $isHelp = $isError || $this->mAction == 'help';
+               $printer->setUnescapeAmps( $isHelp && $printer->getFormat() == 'XML' && $printer->getIsHtml() );
 
-               $printer->initPrinter( $isError );
+               $printer->initPrinter( $isHelp );
 
                $printer->execute();
                $printer->closePrinter();
@@ -966,11 +980,11 @@ class ApiMain extends ApiBase {
                return array(
                        'format' => array(
                                ApiBase::PARAM_DFLT => ApiMain::API_DEFAULT_FORMAT,
-                               ApiBase::PARAM_TYPE => $this->mFormatNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'format' )
                        ),
                        'action' => array(
                                ApiBase::PARAM_DFLT => 'help',
-                               ApiBase::PARAM_TYPE => $this->mModuleNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'action' )
                        ),
                        'maxlag'  => array(
                                ApiBase::PARAM_TYPE => 'integer'
@@ -1087,7 +1101,7 @@ class ApiMain extends ApiBase {
                        '    Victor Vasiliev - vasilvv at gee mail dot com',
                        '    Bryan Tong Minh - bryan . tongminh @ gmail . com',
                        '    Sam Reed - sam @ reedyboy . net',
-                       '    Yuri Astrakhan "<Firstname><Lastname>@gmail.com" (creator, lead developer Sep 2006-Sep 2007)',
+                       '    Yuri Astrakhan "<Firstname><Lastname>@gmail.com" (creator, lead developer Sep 2006-Sep 2007, 2012)',
                        '',
                        'Please send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org',
                        'or file a bug report at https://bugzilla.wikimedia.org/'
@@ -1138,8 +1152,9 @@ class ApiMain extends ApiBase {
 
                $astriks = str_repeat( '*** ', 14 );
                $msg .= "\n\n$astriks Modules  $astriks\n\n";
-               foreach ( array_keys( $this->mModules ) as $moduleName ) {
-                       $module = new $this->mModules[$moduleName] ( $this, $moduleName );
+
+               foreach ( $this->mModuleMgr->getNames( 'action' ) as $name ) {
+                       $module = $this->mModuleMgr->getModule( $name );
                        $msg .= self::makeHelpMsgHeader( $module, 'action' );
 
                        $msg2 = $module->makeHelpMsg();
@@ -1157,8 +1172,8 @@ class ApiMain extends ApiBase {
                }
 
                $msg .= "\n$astriks Formats  $astriks\n\n";
-               foreach ( array_keys( $this->mFormats ) as $formatName ) {
-                       $module = $this->createPrinterByName( $formatName );
+               foreach ( $this->mModuleMgr->getNames( 'format' ) as $name ) {
+                       $module = $this->mModuleMgr->getModule( $name );
                        $msg .= self::makeHelpMsgHeader( $module, 'format' );
                        $msg2 = $module->makeHelpMsg();
                        if ( $msg2 !== false ) {
@@ -1210,45 +1225,57 @@ class ApiMain extends ApiBase {
                return false;
        }
 
+       /**
+        * Overrides to return this instance's module manager.
+        * @return ApiModuleManager
+        */
+       public function getModuleManager() {
+               return $this->mModuleMgr;
+       }
+
        /**
         * Add or overwrite a module in this ApiMain instance. Intended for use by extending
         * classes who wish to add their own modules to their lexicon or override the
         * behavior of inherent ones.
         *
-        * @param $mdlName String The identifier for this module.
-        * @param $mdlClass String The class where this module is implemented.
+        * @deprecated since 1.21, Use getModuleManager()->addModule() instead.
+        * @param $name string The identifier for this module.
+        * @param $class ApiBase The class where this module is implemented.
         */
-       protected function addModule( $mdlName, $mdlClass ) {
-               $this->mModules[$mdlName] = $mdlClass;
+       protected function addModule( $name, $class ) {
+               $this->getModuleManager()->addModule( $name, 'action', $class );
        }
 
        /**
         * Add or overwrite an output format for this ApiMain. Intended for use by extending
         * classes who wish to add to or modify current formatters.
         *
-        * @param $fmtName string The identifier for this format.
-        * @param $fmtClass ApiFormatBase The class implementing this format.
+        * @deprecated since 1.21, Use getModuleManager()->addModule() instead.
+        * @param $name string The identifier for this format.
+        * @param $class ApiFormatBase The class implementing this format.
         */
-       protected function addFormat( $fmtName, $fmtClass ) {
-               $this->mFormats[$fmtName] = $fmtClass;
+       protected function addFormat( $name, $class ) {
+               $this->getModuleManager->addModule( $name, 'format', $class );
        }
 
        /**
         * Get the array mapping module names to class names
+        * @deprecated since 1.21, Use getModuleManager()'s methods instead.
         * @return array
         */
        function getModules() {
-               return $this->mModules;
+               return $this->getModuleManager()->getNamesWithClasses( 'action' );
        }
 
        /**
         * Returns the list of supported formats in form ( 'format' => 'ClassName' )
         *
         * @since 1.18
+        * @deprecated since 1.21, Use getModuleManager()'s methods instead.
         * @return array
         */
        public function getFormats() {
-               return $this->mFormats;
+               return $this->getModuleManager()->getNamesWithClasses( 'format' );
        }
 }
 
diff --git a/includes/api/ApiModuleManager.php b/includes/api/ApiModuleManager.php
new file mode 100644 (file)
index 0000000..db1d36d
--- /dev/null
@@ -0,0 +1,171 @@
+<?php
+/**
+ *
+ *
+ * Created on Dec 27, 2012
+ *
+ * Copyright © 2012 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ *
+ * 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.21
+ */
+
+/**
+ * This class holds a list of modules and handles instantiation
+ *
+ * @since 1.21
+ * @ingroup API
+ */
+class ApiModuleManager extends ContextSource {
+
+       private $mParent;
+       private $mInstances = array();
+       private $mGroups = array();
+       private $mModules = array();
+
+       /**
+        * Construct new module manager
+        * @param ApiBase $parentModule Parent module instance will be used during instantiation
+        */
+       public function __construct( ApiBase $parentModule ) {
+               $this->mParent = $parentModule;
+       }
+
+       /**
+        * Add a list of modules to the manager
+        * @param array $modules A map of ModuleName => ModuleClass
+        * @param string $group Which group modules belong to (action,format,...)
+        */
+       public function addModules( array $modules, $group ) {
+               foreach ( $modules as $name => $class ) {
+                       $this->addModule( $name, $group, $class );
+               }
+       }
+
+       /**
+        * Add or overwrite a module in this ApiMain instance. Intended for use by extending
+        * classes who wish to add their own modules to their lexicon or override the
+        * behavior of inherent ones.
+        *
+        * @param $group string Name of the module group
+        * @param $name string The identifier for this module.
+        * @param $class string The class where this module is implemented.
+        */
+       public function addModule( $name, $group, $class ) {
+               $this->mGroups[$group] = null;
+               $this->mModules[$name] = array( $group, $class );
+       }
+
+       /**
+        * Get module instance by name, or instantiate it if it does not exist
+        * @param $moduleName string module name
+        * @param $group string optionally validate that the module is in a specific group
+        * @param $ignoreCache bool if true, force-creates a new instance and does not cache it
+        * @return mixed the new module instance, or null if failed
+        */
+       public function getModule( $moduleName, $group = null, $ignoreCache = false ) {
+               if ( !isset( $this->mModules[$moduleName] ) ) {
+                       return null;
+               }
+               $grpCls = $this->mModules[$moduleName];
+               if ( $group !== null && $grpCls[0] !== $group ) {
+                       return null;
+               }
+               if ( !$ignoreCache && isset( $this->mInstances[$moduleName] ) ) {
+                       // already exists
+                       return $this->mInstances[$moduleName];
+               } else {
+                       // new instance
+                       $class = $grpCls[1];
+                       $instance = new $class ( $this->mParent, $moduleName );
+                       if ( !$ignoreCache ) {
+                               // cache this instance in case it is needed later
+                               $this->mInstances[$moduleName] = $instance;
+                       }
+                       return $instance;
+               }
+       }
+
+       /**
+        * Get an array of modules in a specific group or all if no group is set.
+        * @param string $group optional group filter
+        * @return array list of module names
+        */
+       public function getNames( $group = null ) {
+               if ( $group === null ) {
+                       return array_keys( $this->mModules );
+               }
+               $result = array();
+               foreach ( $this->mModules as $name => $grpCls ) {
+                       if ( $grpCls[0] === $group ) {
+                               $result[] = $name;
+                       }
+               }
+               return $result;
+       }
+
+       /**
+        * Create an array of (moduleName => moduleClass) for a specific group or for all.
+        * @param string $group name of the group to get or null for all
+        * @return array name=>class map
+        */
+       public function getNamesWithClasses( $group = null ) {
+               $result = array();
+               foreach ( $this->mModules as $name => $grpCls ) {
+                       if ( $group === null || $grpCls[0] === $group ) {
+                               $result[$name] = $grpCls[1];
+                       }
+               }
+               return $result;
+       }
+
+       /**
+        * Returns true if the specific module is defined at all or in a specific group.
+        * @param string $moduleName module name
+        * @param string $group group name to check against, or null to check all groups,
+        * @return boolean true if defined
+        */
+       public function isDefined( $moduleName, $group = null ) {
+               if ( isset( $this->mModules[$moduleName] ) ) {
+                       return $group === null || $this->mModules[$moduleName][0] === $group;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Returns the group name for the given module
+        * @param string $moduleName
+        * @return string group name or null if missing
+        */
+       public function getModuleGroup( $moduleName ) {
+               if ( isset( $this->mModules[$moduleName] ) ) {
+                       return $this->mModules[$moduleName][0];
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Get a list of groups this manager contains.
+        * @return array
+        */
+       public function getGroups() {
+               return array_keys( $this->mGroups );
+       }
+}
index bbf4089..3f54fee 100644 (file)
  */
 class ApiMove extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
index 6403bd6..caf361a 100644 (file)
  */
 class ApiOpenSearch extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function getCustomPrinter() {
                return $this->getMain()->createPrinterByName( 'json' );
        }
index eff05de..faebcdc 100644 (file)
  */
 class ApiOptions extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Changes preferences of the current user.
         */
index e2f4dae..954e5a1 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Created on Sep 24, 2006
  *
- * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ * Copyright © 2006, 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
  *
  * 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 second instance for all their work.
  *
  * @ingroup API
+ * @since 1.21 derives from ApiBase instead of ApiQueryBase
  */
-class ApiPageSet extends ApiQueryBase {
+class ApiPageSet extends ApiBase {
 
-       private $mAllPages; // [ns][dbkey] => page_id or negative when missing
-       private $mTitles, $mGoodTitles, $mMissingTitles, $mInvalidTitles;
-       private $mMissingPageIDs, $mRedirectTitles, $mSpecialTitles;
-       private $mNormalizedTitles, $mInterwikiTitles;
-       private $mResolveRedirects, $mPendingRedirectIDs;
-       private $mConvertTitles, $mConvertedTitles;
-       private $mGoodRevIDs, $mMissingRevIDs;
-       private $mFakePageId;
+       /**
+        * Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter
+        * @since 1.21
+        */
+       const DISABLE_GENERATORS = 1;
 
-       private $mRequestedPageFields;
+       private $mDbSource, $mParams;
+       private $mResolveRedirects, $mConvertTitles, $mAllowGenerator;
+
+       private $mAllPages = array(); // [ns][dbkey] => page_id or negative when missing
+       private $mTitles = array();
+       private $mGoodTitles = array();
+       private $mMissingTitles = array();
+       private $mInvalidTitles = array();
+       private $mMissingPageIDs = array();
+       private $mRedirectTitles = array();
+       private $mSpecialTitles = array();
+       private $mNormalizedTitles = array();
+       private $mInterwikiTitles = array();
+       private $mPendingRedirectIDs = array();
+       private $mConvertedTitles = array();
+       private $mGoodRevIDs = array();
+       private $mMissingRevIDs = array();
+       private $mFakePageId = -1;
+       private $mCacheMode = 'public';
+       private $mRequestedPageFields = array();
 
        /**
         * Constructor
-        * @param $query ApiBase
-        * @param $resolveRedirects bool Whether redirects should be resolved
-        * @param $convertTitles bool
-        */
-       public function __construct( $query, $resolveRedirects = false, $convertTitles = false ) {
-               parent::__construct( $query, 'query' );
-
-               $this->mAllPages = array();
-               $this->mTitles = array();
-               $this->mGoodTitles = array();
-               $this->mMissingTitles = array();
-               $this->mInvalidTitles = array();
-               $this->mMissingPageIDs = array();
-               $this->mRedirectTitles = array();
-               $this->mNormalizedTitles = array();
-               $this->mInterwikiTitles = array();
-               $this->mGoodRevIDs = array();
-               $this->mMissingRevIDs = array();
-               $this->mSpecialTitles = array();
-
-               $this->mRequestedPageFields = array();
-               $this->mResolveRedirects = $resolveRedirects;
-               if ( $resolveRedirects ) {
-                       $this->mPendingRedirectIDs = array();
-               }
+        * @param $dbSource ApiBase Module implementing getDB().
+        *        Allows PageSet to reuse existing db connection from the shared state like ApiQuery.
+        * @param $flags int Zero or more flags like DISABLE_GENERATORS
+        * @since 1.21 accepts $flags instead of two boolean values
+        */
+       public function __construct( ApiBase $dbSource, $flags = 0 ) {
+               parent::__construct( $dbSource->getMain(), $dbSource->getModuleName() );
+               $this->mDbSource = $dbSource;
+               $this->mAllowGenerator = ( $flags & ApiPageSet::DISABLE_GENERATORS ) == 0;
 
-               $this->mConvertTitles = $convertTitles;
-               $this->mConvertedTitles = array();
+               $this->profileIn();
+               $this->mParams = $this->extractRequestParams();
+               $this->mResolveRedirects = $this->mParams['redirects'];
+               $this->mConvertTitles = $this->mParams['converttitles'];
+               $this->profileOut();
+       }
 
-               $this->mFakePageId = - 1;
+       /**
+        * Populate the PageSet from the request parameters.
+        */
+       public function execute() {
+               $this->profileIn();
+
+               $generatorName = $this->mAllowGenerator ? $this->mParams['generator'] : null;
+               if ( isset( $generatorName ) ) {
+                       $dbSource = $this->mDbSource;
+                       $isQuery = $dbSource instanceof ApiQuery;
+                       if ( !$isQuery ) {
+                               // If the parent container of this pageset is not ApiQuery, we must create it to run generator
+                               $dbSource = $this->getMain()->getModuleManager()->getModule( 'query' );
+                               // Enable profiling for query module because it will be used for db sql profiling
+                               $dbSource->profileIn();
+                       }
+                       $generator = $dbSource->getModuleManager()->getModule( $generatorName, null, true );
+                       if ( $generator === null ) {
+                               $this->dieUsage( 'Unknown generator=' . $generatorName, 'badgenerator' );
+                       }
+                       if ( !$generator instanceof ApiQueryGeneratorBase ) {
+                               $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
+                       }
+                       // Create a temporary pageset to store generator's output,
+                       // add any additional fields generator may need, and execute pageset to populate titles/pageids
+                       $tmpPageSet = new ApiPageSet( $dbSource, ApiPageSet::DISABLE_GENERATORS );
+                       $generator->setGeneratorMode( $tmpPageSet );
+                       $this->mCacheMode = $generator->getCacheMode( $generator->extractRequestParams() );
+                       $generator->requestExtraData( $tmpPageSet );
+                       $tmpPageSet->execute();
+
+                       // populate this pageset with the generator output
+                       $this->profileOut();
+                       $generator->profileIn();
+                       $generator->executeGenerator( $this );
+                       wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$this ) );
+                       $this->resolvePendingRedirects();
+                       $generator->profileOut();
+                       $this->profileIn();
+
+                       if ( !$isQuery ) {
+                               // If this pageset is not part of the query, we called profileIn() above
+                               $dbSource->profileOut();
+                       }
+               } else {
+                       // Only one of the titles/pageids/revids is allowed at the same time
+                       $dataSource = null;
+                       if ( isset( $this->mParams['titles'] ) ) {
+                               $dataSource = 'titles';
+                       }
+                       if ( isset( $this->mParams['pageids'] ) ) {
+                               if ( isset( $dataSource ) ) {
+                                       $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
+                               }
+                               $dataSource = 'pageids';
+                       }
+                       if ( isset( $this->mParams['revids'] ) ) {
+                               if ( isset( $dataSource ) ) {
+                                       $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
+                               }
+                               $dataSource = 'revids';
+                       }
+                       // Populate page information with the original user input
+                       switch( $dataSource ) {
+                               case 'titles':
+                                       $this->initFromTitles( $this->mParams['titles'] );
+                                       break;
+                               case 'pageids':
+                                       $this->initFromPageIds( $this->mParams['pageids'] );
+                                       break;
+                               case 'revids':
+                                       if ( $this->mResolveRedirects ) {
+                                               $this->setWarning( 'Redirect resolution cannot be used together with the revids= parameter. ' .
+                                                       'Any redirects the revids= point to have not been resolved.' );
+                                       }
+                                       $this->mResolveRedirects = false;
+                                       $this->initFromRevIDs( $this->mParams['revids'] );
+                                       break;
+                               default:
+                                       // Do nothing - some queries do not need any of the data sources.
+                                       break;
+                       }
+               }
+               $this->profileOut();
        }
 
        /**
@@ -93,8 +181,8 @@ class ApiPageSet extends ApiQueryBase {
        }
 
        /**
-        * Request an additional field from the page table. Must be called
-        * before execute()
+        * Request an additional field from the page table.
+        * Must be called before execute()
         * @param $fieldName string Field name
         */
        public function requestField( $fieldName ) {
@@ -207,13 +295,38 @@ class ApiPageSet extends ApiQueryBase {
 
        /**
         * Get a list of redirect resolutions - maps a title to its redirect
-        * target.
-        * @return array prefixed_title (string) => Title object
+        * target, as an array of output-ready arrays
+        * @return array
         */
        public function getRedirectTitles() {
                return $this->mRedirectTitles;
        }
 
+       /**
+        * Get a list of redirect resolutions - maps a title to its redirect
+        * target.
+        * @param $result ApiResult
+        * @return array of prefixed_title (string) => Title object
+        * @since 1.21
+        */
+       public function getRedirectTitlesAsResult( $result = null ) {
+               $values = array();
+               foreach ( $this->getRedirectTitles() as $titleStrFrom => $titleTo ) {
+                       $r = array(
+                               'from' => strval( $titleStrFrom ),
+                               'to' => $titleTo->getPrefixedText(),
+                       );
+                       if ( $titleTo->getFragment() !== '' ) {
+                               $r['tofragment'] = $titleTo->getFragment();
+                       }
+                       $values[] = $r;
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'r' );
+               }
+               return $values;
+       }
+
        /**
         * Get a list of title normalizations - maps a title to its normalized
         * version.
@@ -223,6 +336,27 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mNormalizedTitles;
        }
 
+       /**
+        * Get a list of title normalizations - maps a title to its normalized
+        * version in the form of result array.
+        * @param $result ApiResult
+        * @return array of raw_prefixed_title (string) => prefixed_title (string)
+        * @since 1.21
+        */
+       public function getNormalizedTitlesAsResult( $result = null  ) {
+               $values = array();
+               foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
+                       $values[] = array(
+                               'from' => $rawTitleStr,
+                               'to' => $titleStr
+                       );
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'n' );
+               }
+               return $values;
+       }
+
        /**
         * Get a list of title conversions - maps a title to its converted
         * version.
@@ -232,6 +366,27 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mConvertedTitles;
        }
 
+       /**
+        * Get a list of title conversions - maps a title to its converted
+        * version as a result array.
+        * @param $result ApiResult
+        * @return array of (from, to) strings
+        * @since 1.21
+        */
+       public function getConvertedTitlesAsResult( $result = null ) {
+               $values = array();
+               foreach ( $this->getConvertedTitles() as $rawTitleStr => $titleStr ) {
+                       $values[] = array(
+                               'from' => $rawTitleStr,
+                               'to' => $titleStr
+                       );
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'c' );
+               }
+               return $values;
+       }
+
        /**
         * Get a list of interwiki titles - maps a title to its interwiki
         * prefix.
@@ -241,6 +396,33 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mInterwikiTitles;
        }
 
+       /**
+        * Get a list of interwiki titles - maps a title to its interwiki
+        * prefix as result.
+        * @param $result ApiResult
+        * @param $iwUrl boolean
+        * @return array raw_prefixed_title (string) => interwiki_prefix (string)
+        * @since 1.21
+        */
+       public function getInterwikiTitlesAsResult( $result = null, $iwUrl = false ) {
+               $values = array();
+               foreach ( $this->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
+                       $item = array(
+                               'title' => $rawTitleStr,
+                               'iw' => $interwikiStr,
+                       );
+                       if ( $iwUrl ) {
+                               $title = Title::newFromText( $rawTitleStr );
+                               $item['url'] = $title->getFullURL( '', false, PROTO_CURRENT );
+                       }
+                       $values[] = $item;
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'i' );
+               }
+               return $values;
+       }
+
        /**
         * Get the list of revision IDs (requested with the revids= parameter)
         * @return array revID (int) => pageID (int)
@@ -257,6 +439,25 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mMissingRevIDs;
        }
 
+       /**
+        * Revision IDs that were not found in the database as result array.
+        * @param $result ApiResult
+        * @return array of revision IDs
+        * @since 1.21
+        */
+       public function getMissingRevisionIDsAsResult( $result = null ) {
+               $values = array();
+               foreach ( $this->getMissingRevisionIDs() as $revid ) {
+                       $values[$revid] = array(
+                               'revid' => $revid
+                       );
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'rev' );
+               }
+               return $values;
+       }
+
        /**
         * Get the list of titles with negative namespace
         * @return array Title
@@ -273,53 +474,6 @@ class ApiPageSet extends ApiQueryBase {
                return count( $this->getRevisionIDs() );
        }
 
-       /**
-        * Populate the PageSet from the request parameters.
-        */
-       public function execute() {
-               $this->profileIn();
-               $params = $this->extractRequestParams();
-
-               // Only one of the titles/pageids/revids is allowed at the same time
-               $dataSource = null;
-               if ( isset( $params['titles'] ) ) {
-                       $dataSource = 'titles';
-               }
-               if ( isset( $params['pageids'] ) ) {
-                       if ( isset( $dataSource ) ) {
-                               $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
-                       }
-                       $dataSource = 'pageids';
-               }
-               if ( isset( $params['revids'] ) ) {
-                       if ( isset( $dataSource ) ) {
-                               $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
-                       }
-                       $dataSource = 'revids';
-               }
-
-               switch ( $dataSource ) {
-                       case 'titles':
-                               $this->initFromTitles( $params['titles'] );
-                               break;
-                       case 'pageids':
-                               $this->initFromPageIds( $params['pageids'] );
-                               break;
-                       case 'revids':
-                               if ( $this->mResolveRedirects ) {
-                                       $this->setWarning( 'Redirect resolution cannot be used together with the revids= parameter. ' .
-                                       'Any redirects the revids= point to have not been resolved.' );
-                               }
-                               $this->mResolveRedirects = false;
-                               $this->initFromRevIDs( $params['revids'] );
-                               break;
-                       default:
-                               // Do nothing - some queries do not need any of the data sources.
-                               break;
-               }
-               $this->profileOut();
-       }
-
        /**
         * Populate this PageSet from a list of Titles
         * @param $titles array of Title objects
@@ -385,12 +539,11 @@ class ApiPageSet extends ApiQueryBase {
        }
 
        /**
-        * Resolve redirects, if applicable
+        * Do not use, does nothing, will be removed
+        * @deprecated 1.21
         */
        public function finishPageSetGeneration() {
-               $this->profileIn();
-               $this->resolvePendingRedirects();
-               $this->profileOut();
+               wfDeprecated( __METHOD__, '1.21' );
        }
 
        /**
@@ -437,7 +590,7 @@ class ApiPageSet extends ApiQueryBase {
         * @param $pageids array of page IDs
         */
        private function initFromPageIds( $pageids ) {
-               if ( !count( $pageids ) ) {
+               if ( !$pageids ) {
                        return;
                }
 
@@ -447,7 +600,7 @@ class ApiPageSet extends ApiQueryBase {
                $pageids = self::getPositiveIntegers( $pageids );
 
                $res = null;
-               if ( count( $pageids ) ) {
+               if ( !empty( $pageids ) ) {
                        $set = array(
                                'page_id' => $pageids
                        );
@@ -499,7 +652,7 @@ class ApiPageSet extends ApiQueryBase {
                                $this->processDbRow( $row );
 
                                // Need gender information
-                               if( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
+                               if ( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
                                        $usernames[] = $row->page_title;
                                }
                        }
@@ -518,7 +671,7 @@ class ApiPageSet extends ApiQueryBase {
                                                $this->mTitles[] = $title;
 
                                                // need gender information
-                                               if( MWNamespace::hasGenderDistinction( $ns ) ) {
+                                               if ( MWNamespace::hasGenderDistinction( $ns ) ) {
                                                        $usernames[] = $dbkey;
                                                }
                                        }
@@ -544,7 +697,7 @@ class ApiPageSet extends ApiQueryBase {
         * @param $revids array of revision IDs
         */
        private function initFromRevIDs( $revids ) {
-               if ( !count( $revids ) ) {
+               if ( !$revids ) {
                        return;
                }
 
@@ -555,14 +708,14 @@ class ApiPageSet extends ApiQueryBase {
 
                $revids = self::getPositiveIntegers( $revids );
 
-               if ( count( $revids ) ) {
+               if ( !empty( $revids ) ) {
                        $tables = array( 'revision', 'page' );
                        $fields = array( 'rev_id', 'rev_page' );
                        $where = array( 'rev_id' => $revids, 'rev_page = page_id' );
 
                        // Get pageIDs data from the `page` table
                        $this->profileDBIn();
-                       $res = $db->select( $tables, $fields, $where,  __METHOD__ );
+                       $res = $db->select( $tables, $fields, $where, __METHOD__ );
                        foreach ( $res as $row ) {
                                $revid = intval( $row->rev_id );
                                $pageid = intval( $row->rev_page );
@@ -669,6 +822,23 @@ class ApiPageSet extends ApiQueryBase {
                return $lb;
        }
 
+       /**
+        * Get the cache mode for the data generated by this module.
+        * All PageSet users should take into account whether this returns a more-restrictive
+        * cache mode than the using module itself. For possible return values and other
+        * details about cache modes, see ApiMain::setCacheMode()
+        *
+        * Public caching will only be allowed if *all* the modules that supply
+        * data for a given request return a cache mode of public.
+        *
+        * @param $params
+        * @return string
+        * @since 1.21
+        */
+       public function getCacheMode( $params = null ) {
+               return $this->mCacheMode;
+       }
+
        /**
         * Given an array of title strings, convert them into Title objects.
         * Alternativelly, an array of Title objects may be given.
@@ -742,6 +912,14 @@ class ApiPageSet extends ApiQueryBase {
                return $linkBatch;
        }
 
+       /**
+        * Get the database connection (read-only)
+        * @return DatabaseBase
+        */
+       protected function getDB() {
+               return $this->mDbSource->getDB();
+       }
+
        /**
         * Returns the input array of integers with all values < 0 removed
         *
@@ -752,7 +930,7 @@ class ApiPageSet extends ApiQueryBase {
                // bug 25734 API: possible issue with revids validation
                // It seems with a load of revision rows, MySQL gets upset
                // Remove any < 0 integers, as they can't be valid
-               foreach( $array as $i => $int ) {
+               foreach ( $array as $i => $int ) {
                        if ( $int < 0 ) {
                                unset( $array[$i] );
                        }
@@ -761,8 +939,8 @@ class ApiPageSet extends ApiQueryBase {
                return $array;
        }
 
-       public function getAllowedParams() {
-               return array(
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
                        'titles' => array(
                                ApiBase::PARAM_ISMULTI => true
                        ),
@@ -773,15 +951,59 @@ class ApiPageSet extends ApiQueryBase {
                        'revids' => array(
                                ApiBase::PARAM_TYPE => 'integer',
                                ApiBase::PARAM_ISMULTI => true
-                       )
+                       ),
+                       'redirects' => false,
+                       'converttitles' => false,
                );
+               if ( $this->mAllowGenerator ) {
+                       if ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
+                               $result['generator'] = array(
+                                       ApiBase::PARAM_TYPE => $this->getGenerators()
+                               );
+                       } else {
+                               $result['generator'] = null;
+                       }
+               }
+               return $result;
+       }
+
+       private static $generators = null;
+
+       /**
+        * Get an array of all available generators
+        * @return array
+        */
+       private function getGenerators() {
+               if ( self::$generators === null ) {
+                       $query = $this->mDbSource;
+                       if ( !( $query instanceof ApiQuery ) ) {
+                               // If the parent container of this pageset is not ApiQuery,
+                               // we must create it to get module manager
+                               $query = $this->getMain()->getModuleManager()->getModule( 'query' );
+                       }
+                       $gens = array();
+                       $mgr = $query->getModuleManager();
+                       foreach ( $mgr->getNamesWithClasses() as $name => $class ) {
+                               if ( is_subclass_of( $class, 'ApiQueryGeneratorBase' ) ) {
+                                       $gens[] = $name;
+                               }
+                       }
+                       sort( $gens );
+                       self::$generators = $gens;
+               }
+               return self::$generators;
        }
 
        public function getParamDescription() {
                return array(
                        'titles' => 'A list of titles to work on',
                        'pageids' => 'A list of page IDs to work on',
-                       'revids' => 'A list of revision IDs to work on'
+                       'revids' => 'A list of revision IDs to work on',
+                       'generator' => array( 'Get the list of pages to work on by executing the specified query module.',
+                               'NOTE: generator parameter names must be prefixed with a \'g\', see examples' ),
+                       'redirects' => 'Automatically resolve redirects',
+                       'converttitles' => array( 'Convert titles to other variants if necessary. Only works if the wiki\'s content language supports variant conversion.',
+                               'Languages that support variant conversion include ' . implode( ', ', LanguageConverter::$languagesWithVariants ) ),
                );
        }
 
@@ -789,6 +1011,7 @@ class ApiPageSet extends ApiQueryBase {
                return array_merge( parent::getPossibleErrors(), array(
                        array( 'code' => 'multisource', 'info' => "Cannot use 'pageids' at the same time as 'dataSource'" ),
                        array( 'code' => 'multisource', 'info' => "Cannot use 'revids' at the same time as 'dataSource'" ),
+                       array( 'code' => 'badgenerator', 'info' => 'Module $generatorName cannot be used as a generator' ),
                ) );
        }
 }
index 42c490e..6978a75 100644 (file)
@@ -42,42 +42,13 @@ class ApiParamInfo extends ApiBase {
        public function execute() {
                // Get parameters
                $params = $this->extractRequestParams();
-               $result = $this->getResult();
+               $resultObj = $this->getResult();
 
                $res = array();
-               if ( is_array( $params['modules'] ) ) {
-                       $modules = $this->getMain()->getModules();
-                       $res['modules'] = array();
-                       foreach ( $params['modules'] as $mod ) {
-                               if ( !isset( $modules[$mod] ) ) {
-                                       $res['modules'][] = array( 'name' => $mod, 'missing' => '' );
-                                       continue;
-                               }
-                               $obj = new $modules[$mod]( $this->getMain(), $mod );
 
-                               $item = $this->getClassInfo( $obj );
-                               $item['name'] = $mod;
-                               $res['modules'][] = $item;
-                       }
-                       $result->setIndexedTagName( $res['modules'], 'module' );
-               }
+               $this->addModulesInfo( $params, 'modules', $res, $resultObj );
 
-               if ( is_array( $params['querymodules'] ) ) {
-                       $queryModules = $this->queryObj->getModules();
-                       $res['querymodules'] = array();
-                       foreach ( $params['querymodules'] as $qm ) {
-                               if ( !isset( $queryModules[$qm] ) ) {
-                                       $res['querymodules'][] = array( 'name' => $qm, 'missing' => '' );
-                                       continue;
-                               }
-                               $obj = new $queryModules[$qm]( $this, $qm );
-                               $item = $this->getClassInfo( $obj );
-                               $item['name'] = $qm;
-                               $item['querytype'] = $this->queryObj->getModuleType( $qm );
-                               $res['querymodules'][] = $item;
-                       }
-                       $result->setIndexedTagName( $res['querymodules'], 'module' );
-               }
+               $this->addModulesInfo( $params, 'querymodules', $res, $resultObj );
 
                if ( $params['mainmodule'] ) {
                        $res['mainmodule'] = $this->getClassInfo( $this->getMain() );
@@ -88,29 +59,50 @@ class ApiParamInfo extends ApiBase {
                        $res['pagesetmodule'] = $this->getClassInfo( $pageSet );
                }
 
-               if ( is_array( $params['formatmodules'] ) ) {
-                       $formats = $this->getMain()->getFormats();
-                       $res['formatmodules'] = array();
-                       foreach ( $params['formatmodules'] as $f ) {
-                               if ( !isset( $formats[$f] ) ) {
-                                       $res['formatmodules'][] = array( 'name' => $f, 'missing' => '' );
-                                       continue;
-                               }
-                               $obj = new $formats[$f]( $this, $f );
-                               $item = $this->getClassInfo( $obj );
-                               $item['name'] = $f;
-                               $res['formatmodules'][] = $item;
+               $this->addModulesInfo( $params, 'formatmodules', $res, $resultObj );
+
+               $resultObj->addValue( null, $this->getModuleName(), $res );
+       }
+
+       /**
+        * If the type is requested in parameters, adds a section to res with module info.
+        * @param array $params user parameters array
+        * @param string $type parameter name
+        * @param array $res store results in this array
+        * @param array $resultObj results object to set indexed tag.
+        */
+       private function addModulesInfo( $params, $type, &$res, $resultObj ) {
+               if ( !is_array( $params[$type] ) ) {
+                       return;
+               }
+               $isQuery = ( $type === 'querymodules' );
+               if ( $isQuery ) {
+                       $mgr = $this->queryObj->getModuleManager();
+               } else {
+                       $mgr = $this->getMain()->getModuleManager();
+               }
+               $res[$type] = array();
+               foreach ( $params[$type] as $mod ) {
+                       if ( !$mgr->isDefined( $mod ) ) {
+                               $res[$type][] = array( 'name' => $mod, 'missing' => '' );
+                               continue;
+                       }
+                       $obj = $mgr->getModule( $mod );
+                       $item = $this->getClassInfo( $obj );
+                       $item['name'] = $mod;
+                       if ( $isQuery ) {
+                               $item['querytype'] = $mgr->getModuleGroup( $mod );
                        }
-                       $result->setIndexedTagName( $res['formatmodules'], 'module' );
+                       $res[$type][] = $item;
                }
-               $result->addValue( null, $this->getModuleName(), $res );
+               $resultObj->setIndexedTagName( $res[$type], 'module' );
        }
 
        /**
         * @param $obj ApiBase
         * @return ApiResult
         */
-       function getClassInfo( $obj ) {
+       private function getClassInfo( $obj ) {
                $result = $this->getResult();
                $retval['classname'] = get_class( $obj );
                $retval['description'] = implode( "\n", (array)$obj->getFinalDescription() );
@@ -133,7 +125,7 @@ class ApiParamInfo extends ApiBase {
                        $retval['generator'] = '';
                }
 
-               $allowedParams = $obj->getFinalParams();
+               $allowedParams = $obj->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
                if ( !is_array( $allowedParams ) ) {
                        return $retval;
                }
@@ -150,7 +142,7 @@ class ApiParamInfo extends ApiBase {
                        if ( is_string( $examples ) ) {
                                $examples = array( $examples );
                        }
-                       foreach( $examples as $k => $v ) {
+                       foreach ( $examples as $k => $v ) {
                                if ( strlen( $retval['examples'] ) ) {
                                        $retval['examples'] .= ' ';
                                }
@@ -181,7 +173,7 @@ class ApiParamInfo extends ApiBase {
                        }
 
                        //handle shorthand
-                       if( !is_array( $p ) ) {
+                       if ( !is_array( $p ) ) {
                                $p = array(
                                        ApiBase::PARAM_DFLT => $p,
                                );
@@ -208,11 +200,11 @@ class ApiParamInfo extends ApiBase {
 
                        if ( isset( $p[ApiBase::PARAM_DFLT] ) ) {
                                $type = $p[ApiBase::PARAM_TYPE];
-                               if( $type === 'boolean' ) {
+                               if ( $type === 'boolean' ) {
                                        $a['default'] = ( $p[ApiBase::PARAM_DFLT] ? 'true' : 'false' );
-                               } elseif( $type === 'string' ) {
+                               } elseif ( $type === 'string' ) {
                                        $a['default'] = strval( $p[ApiBase::PARAM_DFLT] );
-                               } elseif( $type === 'integer' ) {
+                               } elseif ( $type === 'integer' ) {
                                        $a['default'] = intval( $p[ApiBase::PARAM_DFLT] );
                                } else {
                                        $a['default'] = $p[ApiBase::PARAM_DFLT];
@@ -319,11 +311,11 @@ class ApiParamInfo extends ApiBase {
        }
 
        public function getAllowedParams() {
-               $modules = array_keys( $this->getMain()->getModules() );
+               $modules = $this->getMain()->getModuleManager()->getNames( 'action' );
                sort( $modules );
-               $querymodules = array_keys( $this->queryObj->getModules() );
+               $querymodules = $this->queryObj->getModuleManager()->getNames();
                sort( $querymodules );
-               $formatmodules = array_keys( $this->getMain()->getFormats() );
+               $formatmodules = $this->getMain()->getModuleManager()->getNames( 'format' );
                sort( $formatmodules );
                return array(
                        'modules' => array(
index 143540b..b81e5c7 100644 (file)
@@ -36,10 +36,6 @@ class ApiParse extends ApiBase {
        /** @var Content $pstContent */
        private $pstContent = null;
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                // The data is hot but user-dependent, like page views, so we set vary cookies
                $this->getMain()->setCacheMode( 'anon-public-user-private' );
@@ -102,10 +98,10 @@ class ApiParse extends ApiBase {
                                $popts->enableLimitReport( !$params['disablepp'] );
 
                                // If for some reason the "oldid" is actually the current revision, it may be cached
-                               if ( $rev->isCurrent() )  {
+                               if ( $rev->isCurrent() ) {
                                        // May get from/save to parser cache
                                        $p_result = $this->getParsedContent( $pageObj, $popts,
-                                               $pageid, isset( $prop['wikitext'] ) ) ;
+                                               $pageid, isset( $prop['wikitext'] ) );
                                } else { // This is an old revision, so get the text differently
                                        $this->content = $rev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
 
@@ -161,7 +157,7 @@ class ApiParse extends ApiBase {
 
                                // Potentially cached
                                $p_result = $this->getParsedContent( $pageObj, $popts, $pageid,
-                                       isset( $prop['wikitext'] ) ) ;
+                                       isset( $prop['wikitext'] ) );
                        }
                } else { // Not $oldid, $pageid, $page. Hence based on $text
                        $titleObj = Title::newFromText( $title );
index 336068f..4d4fbba 100644 (file)
  */
 class ApiPatrol extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Patrols the article or provides the reason the patrol failed.
         */
index fa6da52..95fdbce 100644 (file)
  */
 class ApiProtect extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                global $wgRestrictionLevels;
                $params = $this->extractRequestParams();
index e1ba759..bd92077 100644 (file)
  */
 class ApiPurge extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
+       private $mPageSet;
+
+       /**
+        * Add all items from $values into the result
+        * @param $result array output
+        * @param $values array values to add
+        * @param $flag string the name of the boolean flag to mark this element
+        * @param $name string 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 = array();
+                               ApiQueryBase::addTitleInfo( $v, $val );
+                       } elseif( $name !== null ) {
+                               $v = array( $name => $val );
+                       } else {
+                               $v = $val;
+                       }
+                       if( $flag !== null ) {
+                               $v[$flag] = '';
+                       }
+                       $result[] = $v;
+               }
        }
 
        /**
         * Purges the cache of a page
         */
        public function execute() {
-               $user = $this->getUser();
                $params = $this->extractRequestParams();
-               if ( !$user->isAllowed( 'purge' ) && !$this->getMain()->isInternalMode() &&
-                               !$this->getRequest()->wasPosted() ) {
-                       $this->dieUsageMsg( array( 'mustbeposted', $this->getModuleName() ) );
-               }
 
                $forceLinkUpdate = $params['forcelinkupdate'];
-               $pageSet = new ApiPageSet( $this );
+               $pageSet = $this->getPageSet();
                $pageSet->execute();
 
                $result = array();
-               foreach( $pageSet->getInvalidTitles() as $title ) {
+               self::addValues( $result, $pageSet->getInvalidTitles(), 'invalid', 'title' );
+               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->getMissingTitles(), 'missing' );
+               self::addValues( $result, $pageSet->getInterwikiTitlesAsResult() );
+
+               foreach ( $pageSet->getGoodTitles() as $title ) {
                        $r = array();
-                       $r['title'] = $title;
-                       $r['invalid'] = '';
-                       $result[] = $r;
-               }
-               foreach( $pageSet->getMissingPageIDs() as $p ) {
-                       $page = array();
-                       $page['pageid'] = $p;
-                       $page['missing'] = '';
-                       $result[] = $page;
-               }
-               foreach( $pageSet->getMissingRevisionIDs() as $r ) {
-                       $rev = array();
-                       $rev['revid'] = $r;
-                       $rev['missing'] = '';
-                       $result[] = $rev;
-               }
-
-               foreach ( $pageSet->getTitles() as $title ) {
-                       $r = array();
-
                        ApiQueryBase::addTitleInfo( $r, $title );
-                       if ( !$title->exists() ) {
-                               $r['missing'] = '';
-                               $result[] = $r;
-                               continue;
-                       }
-
                        $page = WikiPage::factory( $title );
                        $page->doPurge(); // Directly purge and skip the UI part of purge().
                        $r['purged'] = '';
 
-                       if( $forceLinkUpdate ) {
-                               if ( !$user->pingLimiter() ) {
+                       if ( $forceLinkUpdate ) {
+                               if ( !$this->getUser()->pingLimiter() ) {
                                        global $wgEnableParserCache;
 
                                        $popts = $page->makeParserOptions( 'canonical' );
@@ -116,24 +114,52 @@ class ApiPurge extends ApiBase {
                $apiResult = $this->getResult();
                $apiResult->setIndexedTagName( $result, 'page' );
                $apiResult->addValue( null, $this->getModuleName(), $result );
+
+               $values = $pageSet->getNormalizedTitlesAsResult( $apiResult );
+               if ( $values ) {
+                       $apiResult->addValue( null, 'normalized', $values );
+               }
+               $values = $pageSet->getConvertedTitlesAsResult( $apiResult );
+               if ( $values ) {
+                       $apiResult->addValue( null, 'converted', $values );
+               }
+               $values = $pageSet->getRedirectTitlesAsResult( $apiResult );
+               if ( $values ) {
+                       $apiResult->addValue( null, 'redirects', $values );
+               }
+       }
+
+       /**
+        * Get a cached instance of an ApiPageSet object
+        * @return ApiPageSet
+        */
+       private function getPageSet() {
+               if ( !isset( $this->mPageSet ) ) {
+                       $this->mPageSet = new ApiPageSet( $this );
+               }
+               return $this->mPageSet;
        }
 
        public function isWriteMode() {
                return true;
        }
 
-       public function getAllowedParams() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getAllowedParams() + array(
-                       'forcelinkupdate' => false,
-               );
+       public function mustBePosted() {
+               // Anonymous users are not allowed a non-POST request
+               return !$this->getUser()->isAllowed( 'purge' );
+       }
+
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array( 'forcelinkupdate' => false );
+               if ( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags );
+               }
+               return $result;
        }
 
        public function getParamDescription() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getParamDescription() + array(
-                       'forcelinkupdate' => 'Update the links tables',
-               );
+               return $this->getPageSet()->getParamDescription()
+                       + array( 'forcelinkupdate' => 'Update the links tables' );
        }
 
        public function getResultProperties() {
@@ -157,9 +183,14 @@ class ApiPurge extends ApiBase {
                                        ApiBase::PROP_NULLABLE => true
                                ),
                                'invalid' => 'boolean',
+                               'special' => 'boolean',
                                'missing' => 'boolean',
                                'purged' => 'boolean',
-                               'linkupdate' => 'boolean'
+                               'linkupdate' => 'boolean',
+                               'iw' => array(
+                                       ApiBase::PROP_TYPE => 'string',
+                                       ApiBase::PROP_NULLABLE => true
+                               ),
                        )
                );
        }
@@ -171,10 +202,9 @@ class ApiPurge extends ApiBase {
        }
 
        public function getPossibleErrors() {
-               $psModule = new ApiPageSet( $this );
                return array_merge(
                        parent::getPossibleErrors(),
-                       $psModule->getPossibleErrors()
+                       $this->getPageSet()->getPossibleErrors()
                );
        }
 
index e5e6ca4..a25e78c 100644 (file)
  */
 class ApiQuery extends ApiBase {
 
-       private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
-
-       /**
-        * @var ApiPageSet
-        */
-       private $mPageSet;
-
-       private $params, $redirects, $convertTitles, $iwUrl;
-
        /**
         * List of Api Query prop modules
         * @var array
         */
-       private $mQueryPropModules = array(
+       private static $QueryPropModules = array(
                'categories' => 'ApiQueryCategories',
                'categoryinfo' => 'ApiQueryCategoryInfo',
                'duplicatefiles' => 'ApiQueryDuplicateFiles',
@@ -71,7 +62,7 @@ class ApiQuery extends ApiBase {
         * List of Api Query list modules
         * @var array
         */
-       private $mQueryListModules = array(
+       private static $QueryListModules = array(
                'allcategories' => 'ApiQueryAllCategories',
                'allimages' => 'ApiQueryAllImages',
                'alllinks' => 'ApiQueryAllLinks',
@@ -105,49 +96,21 @@ class ApiQuery extends ApiBase {
         * List of Api Query meta modules
         * @var array
         */
-       private $mQueryMetaModules = array(
+       private static $QueryMetaModules = array(
                'allmessages' => 'ApiQueryAllMessages',
                'siteinfo' => 'ApiQuerySiteinfo',
                'userinfo' => 'ApiQueryUserInfo',
        );
 
        /**
-        * List of Api Query generator modules
-        * Defined in code, rather than being derived at runtime,
-        * due to performance reasons
-        * @var array
+        * @var ApiPageSet
         */
-       private $mQueryGenerators = array(
-               'allcategories' => 'ApiQueryAllCategories',
-               'allimages' => 'ApiQueryAllImages',
-               'alllinks' => 'ApiQueryAllLinks',
-               'allpages' => 'ApiQueryAllPages',
-               'alltransclusions' => 'ApiQueryAllLinks',
-               'backlinks' => 'ApiQueryBacklinks',
-               'categories' => 'ApiQueryCategories',
-               'categorymembers' => 'ApiQueryCategoryMembers',
-               'duplicatefiles' => 'ApiQueryDuplicateFiles',
-               'embeddedin' => 'ApiQueryBacklinks',
-               'exturlusage' => 'ApiQueryExtLinksUsage',
-               'images' => 'ApiQueryImages',
-               'imageusage' => 'ApiQueryBacklinks',
-               'iwbacklinks' => 'ApiQueryIWBacklinks',
-               'langbacklinks' => 'ApiQueryLangBacklinks',
-               'links' => 'ApiQueryLinks',
-               'protectedtitles' => 'ApiQueryProtectedTitles',
-               'querypage' => 'ApiQueryQueryPage',
-               'random' => 'ApiQueryRandom',
-               'recentchanges' => 'ApiQueryRecentChanges',
-               'search' => 'ApiQuerySearch',
-               'templates' => 'ApiQueryLinks',
-               'watchlist' => 'ApiQueryWatchlist',
-               'watchlistraw' => 'ApiQueryWatchlistRaw',
-       );
+       private $mPageSet;
 
-       private $mSlaveDB = null;
+       private $params;
+       private $iwUrl;
        private $mNamedDB = array();
-
-       protected $mAllowedGenerators;
+       private $mModuleMgr;
 
        /**
         * @param $main ApiMain
@@ -156,43 +119,27 @@ class ApiQuery extends ApiBase {
        public function __construct( $main, $action ) {
                parent::__construct( $main, $action );
 
-               // Allow custom modules to be added in LocalSettings.php
-               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules, $wgAPIGeneratorModules;
-               self::appendUserModules( $this->mQueryPropModules, $wgAPIPropModules );
-               self::appendUserModules( $this->mQueryListModules, $wgAPIListModules );
-               self::appendUserModules( $this->mQueryMetaModules, $wgAPIMetaModules );
-               self::appendUserModules( $this->mQueryGenerators, $wgAPIGeneratorModules );
-
-               $this->mPropModuleNames = array_keys( $this->mQueryPropModules );
-               $this->mListModuleNames = array_keys( $this->mQueryListModules );
-               $this->mMetaModuleNames = array_keys( $this->mQueryMetaModules );
-               $this->mAllowedGenerators = array_keys( $this->mQueryGenerators );
-       }
+               $this->mModuleMgr = new ApiModuleManager( $this );
 
-       /**
-        * Helper function to append any add-in modules to the list
-        * @param $modules array Module array
-        * @param $newModules array Module array to add to $modules
-        */
-       private static function appendUserModules( &$modules, $newModules ) {
-               if ( is_array( $newModules ) ) {
-                       foreach ( $newModules as $moduleName => $moduleClass ) {
-                               $modules[$moduleName] = $moduleClass;
-                       }
-               }
+               // Allow custom modules to be added in LocalSettings.php
+               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules;
+               $this->mModuleMgr->addModules( self::$QueryPropModules, 'prop' );
+               $this->mModuleMgr->addModules( $wgAPIPropModules, 'prop' );
+               $this->mModuleMgr->addModules( self::$QueryListModules, 'list' );
+               $this->mModuleMgr->addModules( $wgAPIListModules, 'list' );
+               $this->mModuleMgr->addModules( self::$QueryMetaModules, 'meta' );
+               $this->mModuleMgr->addModules( $wgAPIMetaModules, 'meta' );
+
+               // Create PageSet that will process titles/pageids/revids/generator
+               $this->mPageSet = new ApiPageSet( $this );
        }
 
        /**
-        * Gets a default slave database connection object
-        * @return DatabaseBase
+        * Overrides to return this instance's module manager.
+        * @return ApiModuleManager
         */
-       public function getDB() {
-               if ( !isset( $this->mSlaveDB ) ) {
-                       $this->profileDBIn();
-                       $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
-                       $this->profileDBOut();
-               }
-               return $this->mSlaveDB;
+       public function getModuleManager() {
+               return $this->mModuleMgr;
        }
 
        /**
@@ -224,39 +171,38 @@ class ApiQuery extends ApiBase {
 
        /**
         * Get the array mapping module names to class names
+        * @deprecated since 1.21, use getModuleManager()'s methods instead
         * @return array array(modulename => classname)
         */
        public function getModules() {
-               return array_merge( $this->mQueryPropModules, $this->mQueryListModules, $this->mQueryMetaModules );
+               wfDeprecated( __METHOD__, '1.21' );
+               return $this->getModuleManager()->getNamesWithClasses();
        }
 
        /**
         * Get the generators array mapping module names to class names
+        * @deprecated since 1.21, list of generators is maintained by ApiPageSet
         * @return array array(modulename => classname)
         */
        public function getGenerators() {
-               return $this->mQueryGenerators;
+               wfDeprecated( __METHOD__, '1.21' );
+               $gens = array();
+               foreach ( $this->mModuleMgr->getNamesWithClasses() as $name => $class ) {
+                       if ( is_subclass_of( $class, 'ApiQueryGeneratorBase' ) ) {
+                               $gens[$name] = $class;
+                       }
+               }
+               return $gens;
        }
 
        /**
         * Get whether the specified module is a prop, list or a meta query module
+        * @deprecated since 1.21, use getModuleManager()->getModuleGroup()
         * @param $moduleName string Name of the module to find type for
         * @return mixed string or null
         */
        function getModuleType( $moduleName ) {
-               if ( isset( $this->mQueryPropModules[$moduleName] ) ) {
-                       return 'prop';
-               }
-
-               if ( isset( $this->mQueryListModules[$moduleName] ) ) {
-                       return 'list';
-               }
-
-               if ( isset( $this->mQueryMetaModules[$moduleName] ) ) {
-                       return 'meta';
-               }
-
-               return null;
+               return $this->getModuleManager()->getModuleGroup( $moduleName );
        }
 
        /**
@@ -286,34 +232,29 @@ class ApiQuery extends ApiBase {
         */
        public function execute() {
                $this->params = $this->extractRequestParams();
-               $this->redirects = $this->params['redirects'];
-               $this->convertTitles = $this->params['converttitles'];
                $this->iwUrl = $this->params['iwurl'];
 
-               // Create PageSet
-               $this->mPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
-
                // Instantiate requested modules
                $modules = array();
-               $this->instantiateModules( $modules, 'prop', $this->mQueryPropModules );
-               $this->instantiateModules( $modules, 'list', $this->mQueryListModules );
-               $this->instantiateModules( $modules, 'meta', $this->mQueryMetaModules );
-
-               $cacheMode = 'public';
-
-               // If given, execute generator to substitute user supplied data with generated data.
-               if ( isset( $this->params['generator'] ) ) {
-                       $generator = $this->newGenerator( $this->params['generator'] );
-                       $params = $generator->extractRequestParams();
-                       $cacheMode = $this->mergeCacheMode( $cacheMode,
-                               $generator->getCacheMode( $params ) );
-                       $this->executeGeneratorModule( $generator, $modules );
-               } else {
-                       // Append custom fields and populate page/revision information
-                       $this->addCustomFldsToPageSet( $modules, $this->mPageSet );
-                       $this->mPageSet->execute();
+               $this->instantiateModules( $modules, 'prop' );
+               $this->instantiateModules( $modules, 'list' );
+               $this->instantiateModules( $modules, 'meta' );
+
+               // Query modules may optimize data requests through the $this->getPageSet()
+               // object by adding extra fields from the page table.
+               // This function will gather all the extra request fields from the modules.
+               foreach ( $modules as $module ) {
+                       if ( !$this->getRequest()->wasPosted() && $module->mustBePosted() ) {
+                               $this->dieUsageMsgOrDebug( array( 'mustbeposted', $module->getModuleName() ) );
+                       }
+
+                       $module->requestExtraData( $this->mPageSet );
                }
 
+               // Populate page/revision information
+               $this->mPageSet->execute();
+               $cacheMode = $this->mPageSet->getCacheMode();
+
                // Record page information (title, namespace, if exists, etc)
                $this->outputGeneralPageInfo();
 
@@ -357,33 +298,15 @@ class ApiQuery extends ApiBase {
                return $cacheMode;
        }
 
-       /**
-        * Query modules may optimize data requests through the $this->getPageSet() object
-        * by adding extra fields from the page table.
-        * This function will gather all the extra request fields from the modules.
-        * @param $modules array of module objects
-        * @param $pageSet ApiPageSet
-        */
-       private function addCustomFldsToPageSet( $modules, $pageSet ) {
-               // Query all requested modules.
-               /**
-                * @var $module ApiQueryBase
-                */
-               foreach ( $modules as $module ) {
-                       $module->requestExtraData( $pageSet );
-               }
-       }
-
        /**
         * Create instances of all modules requested by the client
         * @param $modules Array to append instantiated modules to
         * @param $param string Parameter name to read modules from
-        * @param $moduleList Array array(modulename => classname)
         */
-       private function instantiateModules( &$modules, $param, $moduleList ) {
+       private function instantiateModules( &$modules, $param ) {
                if ( isset( $this->params[$param] ) ) {
                        foreach ( $this->params[$param] as $moduleName ) {
-                               $modules[] = new $moduleList[$moduleName] ( $this, $moduleName );
+                               $modules[] = $this->mModuleMgr->getModule( $moduleName );
                        }
                }
        }
@@ -401,85 +324,25 @@ class ApiQuery extends ApiBase {
                // more than 380K. The maximum revision size is in the megabyte range,
                // and the maximum result size must be even higher than that.
 
-               // Title normalizations
-               $normValues = array();
-               foreach ( $pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
-                       $normValues[] = array(
-                               'from' => $rawTitleStr,
-                               'to' => $titleStr
-                       );
+               $values = $pageSet->getNormalizedTitlesAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'normalized', $values );
                }
-
-               if ( count( $normValues ) ) {
-                       $result->setIndexedTagName( $normValues, 'n' );
-                       $result->addValue( 'query', 'normalized', $normValues );
+               $values = $pageSet->getConvertedTitlesAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'converted', $values );
                }
-
-               // Title conversions
-               $convValues = array();
-               foreach ( $pageSet->getConvertedTitles() as $rawTitleStr => $titleStr ) {
-                       $convValues[] = array(
-                               'from' => $rawTitleStr,
-                               'to' => $titleStr
-                       );
+               $values = $pageSet->getInterwikiTitlesAsResult( $result, $this->iwUrl );
+               if ( $values ) {
+                       $result->addValue( 'query', 'interwiki', $values );
                }
-
-               if ( count( $convValues ) ) {
-                       $result->setIndexedTagName( $convValues, 'c' );
-                       $result->addValue( 'query', 'converted', $convValues );
+               $values = $pageSet->getRedirectTitlesAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'redirects', $values );
                }
-
-               // Interwiki titles
-               $intrwValues = array();
-               foreach ( $pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
-                       $item = array(
-                               'title' => $rawTitleStr,
-                               'iw' => $interwikiStr,
-                       );
-                       if ( $this->iwUrl ) {
-                               $title = Title::newFromText( $rawTitleStr );
-                               $item['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
-                       }
-                       $intrwValues[] = $item;
-               }
-
-               if ( count( $intrwValues ) ) {
-                       $result->setIndexedTagName( $intrwValues, 'i' );
-                       $result->addValue( 'query', 'interwiki', $intrwValues );
-               }
-
-               // Show redirect information
-               $redirValues = array();
-               /**
-                * @var $titleTo Title
-                */
-               foreach ( $pageSet->getRedirectTitles() as $titleStrFrom => $titleTo ) {
-                       $r = array(
-                               'from' => strval( $titleStrFrom ),
-                               'to' => $titleTo->getPrefixedText(),
-                       );
-                       if ( $titleTo->getFragment() !== '' ) {
-                               $r['tofragment'] = $titleTo->getFragment();
-                       }
-                       $redirValues[] = $r;
-               }
-
-               if ( count( $redirValues ) ) {
-                       $result->setIndexedTagName( $redirValues, 'r' );
-                       $result->addValue( 'query', 'redirects', $redirValues );
-               }
-
-               // Missing revision elements
-               $missingRevIDs = $pageSet->getMissingRevisionIDs();
-               if ( count( $missingRevIDs ) ) {
-                       $revids = array();
-                       foreach ( $missingRevIDs as $revid ) {
-                               $revids[$revid] = array(
-                                       'revid' => $revid
-                               );
-                       }
-                       $result->setIndexedTagName( $revids, 'rev' );
-                       $result->addValue( 'query', 'badrevids', $revids );
+               $values = $pageSet->getMissingRevisionIDsAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'badrevids', $values );
                }
 
                // Page elements
@@ -544,8 +407,8 @@ class ApiQuery extends ApiBase {
        }
 
        /**
-        * @param  $pageSet ApiPageSet Pages to be exported
-        * @param  $result ApiResult Result to output to
+        * @param $pageSet ApiPageSet Pages to be exported
+        * @param $result ApiResult Result to output to
         */
        private function doExport( $pageSet, $result ) {
                $exportTitles = array();
@@ -588,80 +451,29 @@ class ApiQuery extends ApiBase {
                $result->enableSizeCheck();
        }
 
-       /**
-        * Create a generator object of the given type and return it
-        * @param $generatorName string Module name
-        * @return ApiQueryGeneratorBase
-        */
-       public function newGenerator( $generatorName ) {
-               // Find class that implements requested generator
-               if ( isset( $this->mQueryListModules[$generatorName] ) ) {
-                       $className = $this->mQueryListModules[$generatorName];
-               } elseif ( isset( $this->mQueryPropModules[$generatorName] ) ) {
-                       $className = $this->mQueryPropModules[$generatorName];
-               } else {
-                       ApiBase::dieDebug( __METHOD__, "Unknown generator=$generatorName" );
-               }
-               $generator = new $className ( $this, $generatorName );
-               if ( !$generator instanceof ApiQueryGeneratorBase ) {
-                       $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
-               }
-               $generator->setGeneratorMode();
-               return $generator;
-       }
-
-       /**
-        * For generator mode, execute generator, and use its output as new
-        * ApiPageSet
-        * @param $generator ApiQueryGeneratorBase Generator Module
-        * @param $modules array of module objects
-        */
-       protected function executeGeneratorModule( $generator, $modules ) {
-               // Generator results
-               $resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
-
-               // Add any additional fields modules may need
-               $generator->requestExtraData( $this->mPageSet );
-               $this->addCustomFldsToPageSet( $modules, $resultPageSet );
-
-               // Populate page information with the original user input
-               $this->mPageSet->execute();
-
-               // populate resultPageSet with the generator output
-               $generator->profileIn();
-               $generator->executeGenerator( $resultPageSet );
-               wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$resultPageSet ) );
-               $resultPageSet->finishPageSetGeneration();
-               $generator->profileOut();
-
-               // Swap the resulting pageset back in
-               $this->mPageSet = $resultPageSet;
-       }
-
-       public function getAllowedParams() {
-               return array(
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
                        'prop' => array(
                                ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mPropModuleNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'prop' )
                        ),
                        'list' => array(
                                ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mListModuleNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'list' )
                        ),
                        'meta' => array(
                                ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mMetaModuleNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'meta' )
                        ),
-                       'generator' => array(
-                               ApiBase::PARAM_TYPE => $this->mAllowedGenerators
-                       ),
-                       'redirects' => false,
-                       'converttitles' => false,
                        'indexpageids' => false,
                        'export' => false,
                        'exportnowrap' => false,
                        'iwurl' => false,
                );
+               if ( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags );
+               }
+               return $result;
        }
 
        /**
@@ -669,42 +481,40 @@ class ApiQuery extends ApiBase {
         * @return string
         */
        public function makeHelpMsg() {
-               // Make sure the internal object is empty
-               // (just in case a sub-module decides to optimize during instantiation)
-               $this->mPageSet = null;
+
+               // Use parent to make default message for the query module
+               $msg = parent::makeHelpMsg();
 
                $querySeparator = str_repeat( '--- ', 12 );
                $moduleSeparator = str_repeat( '*** ', 14 );
-               $msg = "\n$querySeparator Query: Prop  $querySeparator\n\n";
-               $msg .= $this->makeHelpMsgHelper( $this->mQueryPropModules, 'prop' );
+               $msg .= "\n$querySeparator Query: Prop  $querySeparator\n\n";
+               $msg .= $this->makeHelpMsgHelper( 'prop' );
                $msg .= "\n$querySeparator Query: List  $querySeparator\n\n";
-               $msg .= $this->makeHelpMsgHelper( $this->mQueryListModules, 'list' );
+               $msg .= $this->makeHelpMsgHelper( 'list' );
                $msg .= "\n$querySeparator Query: Meta  $querySeparator\n\n";
-               $msg .= $this->makeHelpMsgHelper( $this->mQueryMetaModules, 'meta' );
+               $msg .= $this->makeHelpMsgHelper( 'meta' );
                $msg .= "\n\n$moduleSeparator Modules: continuation  $moduleSeparator\n\n";
 
-               // Use parent to make default message for the query module
-               $msg = parent::makeHelpMsg() . $msg;
-
                return $msg;
        }
 
        /**
-        * For all modules in $moduleList, generate help messages and join them together
-        * @param $moduleList Array array(modulename => classname)
-        * @param $paramName string Parameter name
+        * For all modules of a given group, generate help messages and join them together
+        * @param $group string Module group
         * @return string
         */
-       private function makeHelpMsgHelper( $moduleList, $paramName ) {
+       private function makeHelpMsgHelper( $group ) {
                $moduleDescriptions = array();
 
-               foreach ( $moduleList as $moduleName => $moduleClass ) {
+               $moduleNames = $this->mModuleMgr->getNames( $group );
+               sort( $moduleNames );
+               foreach ( $moduleNames as $name ) {
                        /**
                         * @var $module ApiQueryBase
                         */
-                       $module = new $moduleClass( $this, $moduleName, null );
+                       $module = $this->mModuleMgr->getModule( $name );
 
-                       $msg = ApiMain::makeHelpMsgHeader( $module, $paramName );
+                       $msg = ApiMain::makeHelpMsgHeader( $module, $group );
                        $msg2 = $module->makeHelpMsg();
                        if ( $msg2 !== false ) {
                                $msg .= $msg2;
@@ -718,29 +528,15 @@ class ApiQuery extends ApiBase {
                return implode( "\n", $moduleDescriptions );
        }
 
-       /**
-        * Override to add extra parameters from PageSet
-        * @return string
-        */
-       public function makeHelpMsgParameters() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->makeHelpMsgParameters() . parent::makeHelpMsgParameters();
-       }
-
        public function shouldCheckMaxlag() {
                return true;
        }
 
        public function getParamDescription() {
-               return array(
+               return $this->getPageSet()->getParamDescription() + array(
                        'prop' => 'Which properties to get for the titles/revisions/pageids. Module help is available below',
                        'list' => 'Which lists to get. Module help is available below',
                        'meta' => 'Which metadata to get about the site. Module help is available below',
-                       'generator' => array( 'Use the output of a list as the input for other prop/list/meta items',
-                                       'NOTE: generator parameter names must be prefixed with a \'g\', see examples' ),
-                       'redirects' => 'Automatically resolve redirects',
-                       'converttitles' => array( "Convert titles to other variants if necessary. Only works if the wiki's content language supports variant conversion.",
-                                       'Languages that support variant conversion include ' . implode( ', ', LanguageConverter::$languagesWithVariants ) ),
                        'indexpageids' => 'Include an additional pageids section listing all returned page IDs',
                        'export' => 'Export the current revisions of all given or generated pages',
                        'exportnowrap' => 'Return the export XML without wrapping it in an XML result (same format as Special:Export). Can only be used with export',
@@ -757,9 +553,10 @@ class ApiQuery extends ApiBase {
        }
 
        public function getPossibleErrors() {
-               return array_merge( parent::getPossibleErrors(), array(
-                       array( 'code' => 'badgenerator', 'info' => 'Module $generatorName cannot be used as a generator' ),
-               ) );
+               return array_merge(
+                       parent::getPossibleErrors(),
+                       $this->getPageSet()->getPossibleErrors()
+               );
        }
 
        public function getExamples() {
index bbc5272..adf2037 100644 (file)
@@ -41,7 +41,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
        }
 
        /**
-        * Override parent method to make sure to make sure the repo's DB is used
+        * Override parent method to make sure the repo's DB is used
         * which may not necesarilly be the same as the local DB.
         *
         * TODO: allow querying non-local repos.
@@ -94,7 +94,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                $this->addFields( LocalFile::selectFields() );
 
                $ascendingOrder = true;
-               if ( $params['dir'] == 'descending' || $params['dir'] == 'older') {
+               if ( $params['dir'] == 'descending' || $params['dir'] == 'older' ) {
                        $ascendingOrder = false;
                }
 
index fcc3dba..6b6b1a3 100644 (file)
@@ -116,7 +116,7 @@ class ApiQueryAllMessages extends ApiQueryBase {
                        $lang = $langObj->getCode();
 
                        $customisedMessages = AllmessagesTablePager::getCustomisedStatuses(
-                               array_map( array( $langObj, 'ucfirst'), $messages_target ), $lang, $lang != $wgContLang->getCode() );
+                               array_map( array( $langObj, 'ucfirst' ), $messages_target ), $lang, $lang != $wgContLang->getCode() );
 
                        $customised = $params['customised'] === 'modified';
                }
index 02d071b..20751e1 100644 (file)
@@ -351,7 +351,7 @@ abstract class ApiQueryBase extends ApiBase {
                }
                $result = $this->getResult();
                $fit = $result->addValue( array( 'query', 'pages', $pageId,
-                                        $this->getModuleName() ), null, $item );
+                       $this->getModuleName() ), null, $item );
                if ( !$fit ) {
                        return false;
                }
@@ -370,7 +370,7 @@ abstract class ApiQueryBase extends ApiBase {
                $msg = array( $paramName => $paramValue );
                $result = $this->getResult();
                $result->disableSizeCheck();
-               $result->addValue( 'query-continue', $this->getModuleName(), $msg );
+               $result->addValue( 'query-continue', $this->getModuleName(), $msg, ApiResult::ADD_ON_TOP );
                $result->enableSizeCheck();
        }
 
@@ -393,8 +393,7 @@ abstract class ApiQueryBase extends ApiBase {
         */
        protected function getDB() {
                if ( is_null( $this->mDb ) ) {
-                       $apiQuery = $this->getQuery();
-                       $this->mDb = $apiQuery->getDB();
+                       $this->mDb = $this->getQuery()->getDB();
                }
                return $this->mDb;
        }
@@ -585,24 +584,32 @@ abstract class ApiQueryBase extends ApiBase {
  */
 abstract class ApiQueryGeneratorBase extends ApiQueryBase {
 
-       private $mIsGenerator;
+       private $mGeneratorPageSet = null;
 
        /**
-        * @param $query ApiBase
-        * @param $moduleName string
-        * @param $paramPrefix string
+        * Switch this module to generator mode. By default, generator mode is
+        * switched off and the module acts like a normal query module.
+        * @since 1.21 requires pageset parameter
+        * @param $generatorPageSet ApiPageSet object that the module will get
+        *        by calling getPageSet() when in generator mode.
         */
-       public function __construct( $query, $moduleName, $paramPrefix = '' ) {
-               parent::__construct( $query, $moduleName, $paramPrefix );
-               $this->mIsGenerator = false;
+       public function setGeneratorMode( ApiPageSet $generatorPageSet ) {
+               if ( $generatorPageSet === null ) {
+                       ApiBase::dieDebug( __METHOD__, 'Required parameter missing - $generatorPageSet' );
+               }
+               $this->mGeneratorPageSet = $generatorPageSet;
        }
 
        /**
-        * Switch this module to generator mode. By default, generator mode is
-        * switched off and the module acts like a normal query module.
+        * Get the PageSet object to work on.
+        * If this module is generator, the pageSet object is different from other module's
+        * @return ApiPageSet
         */
-       public function setGeneratorMode() {
-               $this->mIsGenerator = true;
+       protected function getPageSet() {
+               if ( $this->mGeneratorPageSet !== null ) {
+                       return $this->mGeneratorPageSet;
+               }
+               return parent::getPageSet();
        }
 
        /**
@@ -611,7 +618,7 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
         * @return string Prefixed parameter name
         */
        public function encodeParamName( $paramName ) {
-               if ( $this->mIsGenerator ) {
+               if ( $this->mGeneratorPageSet !== null ) {
                        return 'g' . parent::encodeParamName( $paramName );
                } else {
                        return parent::encodeParamName( $paramName );
@@ -623,5 +630,5 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
         * @param $resultPageSet ApiPageSet: All output should be appended to
         *  this object
         */
-       public abstract function executeGenerator( $resultPageSet );
+       abstract public function executeGenerator( $resultPageSet );
 }
index 0d2fa0d..d9be9f2 100644 (file)
@@ -132,10 +132,10 @@ class ApiQueryBlocks extends ApiQueryBase {
                        $this->addWhereIf( 'ipb_user != 0', isset( $show['account'] ) );
                        $this->addWhereIf( 'ipb_user != 0 OR ipb_range_end > ipb_range_start', isset( $show['!ip'] ) );
                        $this->addWhereIf( 'ipb_user = 0 AND ipb_range_end = ipb_range_start', isset( $show['ip'] ) );
-                       $this->addWhereIf( 'ipb_expiry =  '.$db->addQuotes($db->getInfinity()), isset( $show['!temp'] ) );
-                       $this->addWhereIf( 'ipb_expiry != '.$db->addQuotes($db->getInfinity()), isset( $show['temp'] ) );
-                       $this->addWhereIf( "ipb_range_end = ipb_range_start", isset( $show['!range'] ) );
-                       $this->addWhereIf( "ipb_range_end > ipb_range_start", isset( $show['range'] ) );
+                       $this->addWhereIf( 'ipb_expiry = ' . $db->addQuotes( $db->getInfinity() ), isset( $show['!temp'] ) );
+                       $this->addWhereIf( 'ipb_expiry != ' . $db->addQuotes( $db->getInfinity() ), isset( $show['temp'] ) );
+                       $this->addWhereIf( 'ipb_range_end = ipb_range_start', isset( $show['!range'] ) );
+                       $this->addWhereIf( 'ipb_range_end > ipb_range_start', isset( $show['range'] ) );
                }
 
                if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
index 6a392bd..fd9d4c5 100644 (file)
@@ -243,7 +243,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
 
                if ( is_null( $resultPageSet ) ) {
                        $result->setIndexedTagName_internal(
-                                        array( 'query', $this->getModuleName() ), 'cm' );
+                               array( 'query', $this->getModuleName() ), 'cm' );
                }
        }
 
index 27d95ee..31812cf 100644 (file)
@@ -76,13 +76,13 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        // Ignore namespace and unique due to inability to know whether they were purposely set
                        foreach( array( 'from', 'to', 'prefix', /*'namespace',*/ 'continue', /*'unique'*/ ) as $p ) {
                                if ( !is_null( $params[$p] ) ) {
-                                       $this->dieUsage( "The '{$p}' parameter cannot be used in modes 1 or 2", 'badparams');
+                                       $this->dieUsage( "The '{$p}' parameter cannot be used in modes 1 or 2", 'badparams' );
                                }
                        }
                } else {
                        foreach( array( 'start', 'end' ) as $p ) {
                                if ( !is_null( $params[$p] ) ) {
-                                       $this->dieUsage( "The {$p} parameter cannot be used in mode 3", 'badparams');
+                                       $this->dieUsage( "The {$p} parameter cannot be used in mode 3", 'badparams' );
                                }
                        }
                }
index c0929a0..cf0d841 100644 (file)
  */
 class ApiQueryDisabled extends ApiQueryBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $this->setWarning( "The \"{$this->getModuleName()}\" module has been disabled." );
        }
index 2b6ec66..34f78e7 100644 (file)
@@ -30,6 +30,8 @@
  * @ingroup API
  */
 class ApiQueryImageInfo extends ApiQueryBase {
+       const TRANSFORM_LIMIT = 50;
+       private static $transformCount = 0;
 
        public function __construct( $query, $moduleName, $prefix = 'ii' ) {
                // We allow a subclass to override the prefix, to create a related API module.
@@ -52,9 +54,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        $titles = array_keys( $pageIds[NS_FILE] );
                        asort( $titles ); // Ensure the order is always the same
 
-                       $skip = false;
+                       $fromTitle = null;
                        if ( !is_null( $params['continue'] ) ) {
-                               $skip = true;
                                $cont = explode( '|', $params['continue'] );
                                $this->dieContinueUsageIf( count( $cont ) != 2 );
                                $fromTitle = strval( $cont[0] );
@@ -76,15 +77,33 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        } else {
                                $images = RepoGroup::singleton()->findFiles( $titles );
                        }
-                       $resolveRedirects = $this->getPageSet()->isResolvingRedirects();
-                       foreach ( $images as $img ) {
-                               // Skip redirects
-                               if ( $img->getOriginalTitle()->isRedirect() && !$resolveRedirects ) {
+                       foreach ( $titles as $title ) {
+                               $pageId = $pageIds[NS_FILE][$title];
+                               $start = $title === $fromTitle ? $fromTimestamp : $params['start'];
+
+                               if ( !isset( $images[$title] ) ) {
+                                       $result->addValue(
+                                               array( 'query', 'pages', intval( $pageId ) ),
+                                               'imagerepository', ''
+                                       );
+                                       // The above can't fail because it doesn't increase the result size
                                        continue;
                                }
 
-                               $start = $skip ? $fromTimestamp : $params['start'];
-                               $pageId = $pageIds[NS_FILE][$img->getTitle()->getDBkey()];
+                               $img = $images[$title];
+
+                               if ( self::getTransformCount() >= self::TRANSFORM_LIMIT ) {
+                                       if ( count( $pageIds[NS_FILE] ) == 1 ) {
+                                               // See the 'the user is screwed' comment below
+                                               $this->setContinueEnumParameter( 'start',
+                                                       $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
+                                               );
+                                       } else {
+                                               $this->setContinueEnumParameter( 'continue',
+                                                       $this->getContinueStr( $img, $start ) );
+                                       }
+                                       break;
+                               }
 
                                $fit = $result->addValue(
                                        array( 'query', 'pages', intval( $pageId ) ),
@@ -98,10 +117,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                                // thing again. When the violating queries have been
                                                // out-continued, the result will get through
                                                $this->setContinueEnumParameter( 'start',
-                                                       wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
+                                                       $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
+                                               );
                                        } else {
                                                $this->setContinueEnumParameter( 'continue',
-                                                       $this->getContinueStr( $img ) );
+                                                       $this->getContinueStr( $img, $start ) );
                                        }
                                        break;
                                }
@@ -165,18 +185,6 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                if ( !$fit ) {
                                        break;
                                }
-                               $skip = false;
-                       }
-
-                       $data = $this->getResultData();
-                       foreach ( $data['query']['pages'] as $pageid => $arr ) {
-                               if ( is_array( $arr ) && !isset( $arr['imagerepository'] ) ) {
-                                       $result->addValue(
-                                               array( 'query', 'pages', $pageid ),
-                                               'imagerepository', ''
-                                       );
-                               }
-                               // The above can't fail because it doesn't increase the result size
                        }
                }
        }
@@ -344,6 +352,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                if ( $url ) {
                        if ( !is_null( $thumbParams ) ) {
                                $mto = $file->transform( $thumbParams );
+                               self::$transformCount++;
                                if ( $mto && !$mto->isError() ) {
                                        $vals['thumburl'] = wfExpandUrl( $mto->getUrl(), PROTO_CURRENT );
 
@@ -403,6 +412,17 @@ class ApiQueryImageInfo extends ApiQueryBase {
                return $vals;
        }
 
+       /**
+        * Get the count of image transformations performed
+        *
+        * If this is >= TRANSFORM_LIMIT, you should probably stop processing images.
+        *
+        * @return integer count
+        */
+       static function getTransformCount() {
+               return self::$transformCount;
+       }
+
        /**
         *
         * @param $metadata Array
@@ -434,9 +454,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
         * @param $img File
         * @return string
         */
-       protected function getContinueStr( $img ) {
-               return $img->getOriginalTitle()->getText() .
-                       '|' .  $img->getTimestamp();
+       protected function getContinueStr( $img, $start = null ) {
+               if ( $start === null ) {
+                       $start = $img->getTimestamp();
+               }
+               return $img->getOriginalTitle()->getText() . '|' . $start;
        }
 
        public function getAllowedParams() {
@@ -540,7 +562,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                return array(
                        'prop' => self::getPropertyDescriptions( array(), $p ),
                        'urlwidth' => array( "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
-                                           'Only the current version of the image can be scaled' ),
+                                               'Only the current version of the image can be scaled' ),
                        'urlheight' => "Similar to {$p}urlwidth. Cannot be used without {$p}urlwidth",
                        'urlparam' => array( "A handler specific parameter string. For example, pdf's ",
                                "might use 'page15-100px'. {$p}urlwidth must be used and be consistent with {$p}urlparam" ),
index 94b6ad8..7797205 100644 (file)
@@ -96,7 +96,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        'unblock' => array( 'ApiQueryInfo', 'getUnblockToken' ),
                        'email' => array( 'ApiQueryInfo', 'getEmailToken' ),
                        'import' => array( 'ApiQueryInfo', 'getImportToken' ),
-                       'watch' => array( 'ApiQueryInfo', 'getWatchToken'),
+                       'watch' => array( 'ApiQueryInfo', 'getWatchToken' ),
                );
                wfRunHooks( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );
                return $this->tokenFunctions;
index 138d79b..69d81ae 100644 (file)
@@ -238,9 +238,9 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
                $desc = $this->description;
                $name = $this->getModuleName();
                return array(
-                       "api.php?action=query&prop={$name}&titles=Main%20Page" => "Get {$desc}s from the [[Main Page]]:",
-                       "api.php?action=query&generator={$name}&titles=Main%20Page&prop=info" => "Get information about the {$desc} pages in the [[Main Page]]:",
-                       "api.php?action=query&prop={$name}&titles=Main%20Page&{$this->prefix}namespace=2|10" => "Get {$desc}s from the Main Page in the User and Template namespaces:",
+                       "api.php?action=query&prop={$name}&titles=Main%20Page" => "Get {$desc}s from the [[Main Page]]",
+                       "api.php?action=query&generator={$name}&titles=Main%20Page&prop=info" => "Get information about the {$desc} pages in the [[Main Page]]",
+                       "api.php?action=query&prop={$name}&titles=Main%20Page&{$this->prefix}namespace=2|10" => "Get {$desc}s from the Main Page in the User and Template namespaces",
                );
        }
 
index 6b77898..f89c826 100644 (file)
@@ -151,7 +151,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        if ( is_null( $title ) ) {
                                $this->dieUsage( "Bad title value '$prefix'", 'param_prefix' );
                        }
-                       $this->addWhereFld( 'log_namespace',  $title->getNamespace() );
+                       $this->addWhereFld( 'log_namespace', $title->getNamespace() );
                        $this->addWhere( 'log_title ' . $db->buildLike( $title->getDBkey(), $db->anyString() ) );
                }
 
@@ -201,7 +201,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
        public static function addLogParams( $result, &$vals, $params, $type, $action, $ts, $legacy = false ) {
                switch ( $type ) {
                        case 'move':
-                               if ( $legacy ){
+                               if ( $legacy ) {
                                        $targetKey = 0;
                                        $noredirKey = 1;
                                } else {
@@ -223,7 +223,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                $params = null;
                                break;
                        case 'patrol':
-                               if ( $legacy ){
+                               if ( $legacy ) {
                                        $cur = 0;
                                        $prev = 1;
                                        $auto = 2;
index f0c2b1b..41d8f11 100644 (file)
@@ -35,7 +35,7 @@ abstract class ApiQueryORM extends ApiQueryBase {
         *
         * @return IORMTable
         */
-       protected abstract function getTable();
+       abstract protected function getTable();
 
        /**
         * Returns the name of the individual rows.
index 189e15a..2de5710 100644 (file)
@@ -49,7 +49,7 @@ class ApiQueryPageProps extends ApiQueryBase {
 
                $this->addTables( 'page_props' );
                $this->addFields( array( 'pp_page', 'pp_propname', 'pp_value' ) );
-               $this->addWhereFld( 'pp_page',  array_keys( $pages ) );
+               $this->addWhereFld( 'pp_page', array_keys( $pages ) );
 
                if ( $this->params['continue'] ) {
                        $this->addWhere( 'pp_page >=' . intval( $this->params['continue'] ) );
@@ -60,7 +60,10 @@ class ApiQueryPageProps extends ApiQueryBase {
                }
 
                # Force a sort order to ensure that properties are grouped by page
-               $this->addOption( 'ORDER BY', 'pp_page' );
+               # But only if pp_page is not constant in the WHERE clause.
+               if ( count( $pages ) > 1 ) {
+                       $this->addOption( 'ORDER BY', 'pp_page' );
+               }
 
                $res = $this->select( __METHOD__ );
                $currentPage = 0; # Id of the page currently processed
@@ -122,14 +125,16 @@ class ApiQueryPageProps extends ApiQueryBase {
        public function getAllowedParams() {
                return array(
                        'continue' => null,
-                       'prop' => null,
+                       'prop' => array(
+                               ApiBase::PARAM_ISMULTI => true,
+                       ),
                );
        }
 
        public function getParamDescription() {
                return array(
                        'continue' => 'When more results are available, use this to continue',
-                       'prop' => 'Page prop to look on the page for. Useful for checking whether a certain page uses a certain page prop.'
+                       'prop' => 'Only list these props. Useful for checking whether a certain page uses a certain page prop',
                );
        }
 
index 182bc2c..1c9deb7 100644 (file)
@@ -211,7 +211,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
 
        public function getPossibleErrors() {
                return array_merge( parent::getPossibleErrors(), array(
-                        array( 'specialpage-cantexecute' )
+                       array( 'specialpage-cantexecute' )
                ) );
        }
 
index f7a22bd..6acca67 100644 (file)
@@ -234,7 +234,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
                        $this->addFieldsIf( 'rc_user', $this->fld_user );
                        $this->addFieldsIf( 'rc_user_text', $this->fld_user || $this->fld_userid );
-                       $this->addFieldsIf( array( 'rc_minor', 'rc_type', 'rc_bot' ) , $this->fld_flags );
+                       $this->addFieldsIf( array( 'rc_minor', 'rc_type', 'rc_bot' ), $this->fld_flags );
                        $this->addFieldsIf( array( 'rc_old_len', 'rc_new_len' ), $this->fld_sizes );
                        $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
                        $this->addFieldsIf( array( 'rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params' ), $this->fld_loginfo );
@@ -260,7 +260,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'rc_id=ct_rc_id' ) ) ) );
-                       $this->addWhereFld( 'ct_tag' , $params['tag'] );
+                       $this->addWhereFld( 'ct_tag', $params['tag'] );
                        global $wgOldChangeTagsIndex;
                        $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
                }
index 27ea6be..9b54ee5 100644 (file)
@@ -189,7 +189,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'rev_id=ct_rev_id' ) ) ) );
-                       $this->addWhereFld( 'ct_tag' , $params['tag'] );
+                       $this->addWhereFld( 'ct_tag', $params['tag'] );
                        global $wgOldChangeTagsIndex;
                        $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
                }
index a6a6dff..ac13589 100644 (file)
@@ -96,6 +96,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                case 'variables':
                                        $fit = $this->appendVariables( $p );
                                        break;
+                               case 'protocols':
+                                       $fit = $this->appendProtocols( $p );
+                                       break;
                                default:
                                        ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
                        }
@@ -111,7 +114,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
        }
 
        protected function appendGeneralInfo( $property ) {
-               global $wgContLang;
+               global $wgContLang,
+                       $wgDisableLangConversion,
+                       $wgDisableTitleConversion;
 
                $data = array();
                $mainPage = Title::newMainPage();
@@ -120,10 +125,27 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                $data['sitename'] = $GLOBALS['wgSitename'];
                $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
                $data['phpversion'] = phpversion();
-               $data['phpsapi'] = php_sapi_name();
+               $data['phpsapi'] = PHP_SAPI;
                $data['dbtype'] = $GLOBALS['wgDBtype'];
                $data['dbversion'] = $this->getDB()->getServerVersion();
 
+               if ( !$wgDisableLangConversion ) {
+                       $data['langconversion'] = '';
+               }
+
+               if ( !$wgDisableTitleConversion ) {
+                       $data['titleconversion'] = '';
+               }
+
+               if ( $wgContLang->linkPrefixExtension() ) {
+                       $data['linkprefix'] = wfMessage( 'linkprefix' )->inContentLanguage()->text();
+               }
+
+               $linktrail = $wgContLang->linkTrail();
+               if ( $linktrail ) {
+                       $data['linktrail'] = $linktrail;
+               }
+
                $git = SpecialVersion::getGitHeadSha1( $GLOBALS['IP'] );
                if ( $git ) {
                        $data['git-hash'] = $git;
@@ -462,7 +484,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                }
                                if ( isset( $ext['author'] ) ) {
                                        $ret['author'] = is_array( $ext['author'] ) ?
-                                               implode( ', ', $ext['author' ] ) : $ext['author'];
+                                               implode( ', ', $ext['author'] ) : $ext['author'];
                                }
                                if ( isset( $ext['url'] ) ) {
                                        $ret['url'] = $ext['url'];
@@ -530,7 +552,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
        public function appendExtensionTags( $property ) {
                global $wgParser;
                $wgParser->firstCallInit();
-               $tags = array_map( array( $this, 'formatParserTags'), $wgParser->getTags() );
+               $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
                $this->getResult()->setIndexedTagName( $tags, 't' );
                return $this->getResult()->addValue( 'query', $property, $tags );
        }
@@ -549,6 +571,14 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                return $this->getResult()->addValue( 'query', $property, $variables );
        }
 
+       public function appendProtocols( $property ) {
+               global $wgUrlProtocols;
+               // Make a copy of the global so we don't try to set the _element key of it - bug 45130
+               $protocols = array_values( $wgUrlProtocols );
+               $this->getResult()->setIndexedTagName( $protocols, 'p' );
+               return $this->getResult()->addValue( 'query', $property, $protocols );
+       }
+
        private function formatParserTags( $item ) {
                return "<{$item}>";
        }
@@ -559,7 +589,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                ksort( $myWgHooks );
 
                $data = array();
-               foreach ( $myWgHooks as $hook => $hooks )  {
+               foreach ( $myWgHooks as $hook => $hooks ) {
                        $arr = array(
                                'name' => $hook,
                                'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
@@ -601,6 +631,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                        'functionhooks',
                                        'showhooks',
                                        'variables',
+                                       'protocols',
                                )
                        ),
                        'filteriw' => array(
@@ -638,6 +669,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                ' functionhooks         - Returns a list of parser function hooks',
                                ' showhooks             - Returns a list of all subscribed hooks (contents of $wgHooks)',
                                ' variables             - Returns a list of variable IDs',
+                               ' protocols             - Returns a list of protocols that are allowed in external links.',
                        ),
                        'filteriw' =>  'Return only local or only nonlocal entries of the interwiki map',
                        'showalldb' => 'List all database servers, not just the one lagging the most',
index 1b97317..6899375 100644 (file)
@@ -42,7 +42,7 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
                $result = $this->getResult();
 
                if ( !$params['filekey'] && !$params['sessionkey'] ) {
-                       $this->dieUsage( "One of filekey or sessionkey must be supplied", 'nofilekey');
+                       $this->dieUsage( "One of filekey or sessionkey must be supplied", 'nofilekey' );
                }
 
                // Alias sessionkey to filekey, but give an existing filekey precedence.
@@ -139,4 +139,3 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
        }
 
 }
-
index 4d1edf1..2410f05 100644 (file)
@@ -220,7 +220,7 @@ class ApiQueryContributions extends ApiQueryBase {
                ) );
 
                if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                                $this->fld_patrolled ) {
+                               $this->fld_patrolled ) {
                        if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
                                $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' );
                        }
index 03a0b79..50ea587 100644 (file)
@@ -161,7 +161,7 @@ class ApiQueryUsers extends ApiQueryBase {
                                }
 
                                if ( isset( $this->prop['implicitgroups'] ) ) {
-                                       $data[$name]['implicitgroups'] =  $user->getAutomaticGroups();
+                                       $data[$name]['implicitgroups'] = $user->getAutomaticGroups();
                                }
 
                                if ( isset( $this->prop['rights'] ) ) {
index 5f752b3..7ecfa8e 100644 (file)
  */
 class ApiResult extends ApiBase {
 
+       /**
+        * override existing value in addValue() and setElement()
+        * @since 1.21
+        */
+       const OVERRIDE = 1;
+
+       /**
+        * For addValue() and setElement(), if the value does not exist, add it as the first element.
+        * In case the new value has no name (numerical index), all indexes will be renumbered.
+        * @since 1.21
+        */
+       const ADD_ON_TOP = 2;
+
        private $mData, $mIsRawMode, $mSize, $mCheckingSize;
 
        /**
@@ -137,15 +150,24 @@ class ApiResult extends ApiBase {
         * @param $arr array to add $value to
         * @param $name string Index of $arr to add $value at
         * @param $value mixed
-        * @param $overwrite bool Whether overwriting an existing element is allowed
+        * @param $flags int Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP. This parameter used to be
+        *        boolean, and the value of OVERRIDE=1 was specifically chosen so that it would be backwards
+        *        compatible with the new method signature.
+        *
+        * @since 1.21 int $flags replaced boolean $override
         */
-       public static function setElement( &$arr, $name, $value, $overwrite = false ) {
+       public static function setElement( &$arr, $name, $value, $flags = 0 ) {
                if ( $arr === null || $name === null || $value === null || !is_array( $arr ) || is_array( $name ) ) {
                        ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
                }
 
-               if ( !isset ( $arr[$name] ) || $overwrite ) {
-                       $arr[$name] = $value;
+               $exists = isset( $arr[$name] );
+               if ( !$exists || ( $flags & ApiResult::OVERRIDE ) ) {
+                       if ( !$exists && ( $flags & ApiResult::ADD_ON_TOP ) ) {
+                               $arr = array( $name => $value ) + $arr;
+                       } else {
+                               $arr[$name] = $value;
+                       }
                } elseif ( is_array( $arr[$name] ) && is_array( $value ) ) {
                        $merged = array_intersect_key( $arr[$name], $value );
                        if ( !count( $merged ) ) {
@@ -249,11 +271,14 @@ class ApiResult extends ApiBase {
         * @param $path array|string|null
         * @param $name string
         * @param $value mixed
-        * @param $overwrite bool
-        *
+        * @param $flags int Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP. This parameter used to be
+        *        boolean, and the value of OVERRIDE=1 was specifically chosen so that it would be backwards
+        *        compatible with the new method signature.
         * @return bool True if $value fits in the result, false if not
+        *
+        * @since 1.21 int $flags replaced boolean $override
         */
-       public function addValue( $path, $name, $value, $overwrite = false ) {
+       public function addValue( $path, $name, $value, $flags = 0 ) {
                global $wgAPIMaxResultSize;
 
                $data = &$this->mData;
@@ -268,26 +293,34 @@ class ApiResult extends ApiBase {
                        $this->mSize = $newsize;
                }
 
-               if ( !is_null( $path ) ) {
-                       if ( is_array( $path ) ) {
-                               foreach ( $path as $p ) {
-                                       if ( !isset( $data[$p] ) ) {
+               $addOnTop = $flags & ApiResult::ADD_ON_TOP;
+               if ( $path !== null ) {
+                       foreach ( (array) $path as $p ) {
+                               if ( !isset( $data[$p] ) ) {
+                                       if ( $addOnTop ) {
+                                               $data = array( $p => array() ) + $data;
+                                               $addOnTop = false;
+                                       } else {
                                                $data[$p] = array();
                                        }
-                                       $data = &$data[$p];
                                }
-                       } else {
-                               if ( !isset( $data[$path] ) ) {
-                                       $data[$path] = array();
-                               }
-                               $data = &$data[$path];
+                               $data = &$data[$p];
                        }
                }
 
                if ( !$name ) {
-                       $data[] = $value; // Add list element
+                       // Add list element
+                       if ( $addOnTop ) {
+                               // This element needs to be inserted in the beginning
+                               // Numerical indexes will be renumbered
+                               array_unshift( $data, $value );
+                       } else {
+                               // Add new value at the end
+                               $data[] = $value;
+                       }
                } else {
-                       self::setElement( $data, $name, $value, $overwrite ); // Add named element
+                       // Add named element
+                       self::setElement( $data, $name, $value, $flags );
                }
                return true;
        }
@@ -300,7 +333,7 @@ class ApiResult extends ApiBase {
         */
        public function setParsedLimit( $moduleName, $limit ) {
                // Add value, allowing overwriting
-               $this->addValue( 'limits', $moduleName, $limit, true );
+               $this->addValue( 'limits', $moduleName, $limit, ApiResult::OVERRIDE );
        }
 
        /**
index 402bab1..6e55a5e 100644 (file)
  */
 class ApiRollback extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * @var Title
         */
index 752a6be..c4a1328 100644 (file)
  */
 class ApiRsd extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $result = $this->getResult();
 
index 68160fa..3f5ebfe 100644 (file)
@@ -31,9 +31,7 @@
  */
 class ApiSetNotificationTimestamp extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
+       private $mPageSet;
 
        public function execute() {
                $user = $this->getUser();
@@ -45,7 +43,7 @@ class ApiSetNotificationTimestamp extends ApiBase {
                $params = $this->extractRequestParams();
                $this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' );
 
-               $pageSet = new ApiPageSet( $this );
+               $pageSet = $this->getPageSet();
                $args = array_merge( array( $params, 'entirewatchlist' ), array_keys( $pageSet->getAllowedParams() ) );
                call_user_func_array( array( $this, 'requireOnlyOneParameter' ), $args );
 
@@ -96,20 +94,20 @@ class ApiSetNotificationTimestamp extends ApiBase {
                        $result['notificationtimestamp'] = ( is_null( $timestamp ) ? '' : wfTimestamp( TS_ISO_8601, $timestamp ) );
                } else {
                        // First, log the invalid titles
-                       foreach( $pageSet->getInvalidTitles() as $title ) {
+                       foreach ( $pageSet->getInvalidTitles() as $title ) {
                                $r = array();
                                $r['title'] = $title;
                                $r['invalid'] = '';
                                $result[] = $r;
                        }
-                       foreach( $pageSet->getMissingPageIDs() as $p ) {
+                       foreach ( $pageSet->getMissingPageIDs() as $p ) {
                                $page = array();
                                $page['pageid'] = $p;
                                $page['missing'] = '';
                                $page['notwatched'] = '';
                                $result[] = $page;
                        }
-                       foreach( $pageSet->getMissingRevisionIDs() as $r ) {
+                       foreach ( $pageSet->getMissingRevisionIDs() as $r ) {
                                $rev = array();
                                $rev['revid'] = $r;
                                $rev['missing'] = '';
@@ -161,6 +159,17 @@ class ApiSetNotificationTimestamp extends ApiBase {
                $apiResult->addValue( null, $this->getModuleName(), $result );
        }
 
+       /**
+        * Get a cached instance of an ApiPageSet object
+        * @return ApiPageSet
+        */
+       private function getPageSet() {
+               if ( !isset( $this->mPageSet ) ) {
+                       $this->mPageSet = new ApiPageSet( $this );
+               }
+               return $this->mPageSet;
+       }
+
        public function mustBePosted() {
                return true;
        }
@@ -177,9 +186,8 @@ class ApiSetNotificationTimestamp extends ApiBase {
                return '';
        }
 
-       public function getAllowedParams() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getAllowedParams() + array(
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
                        'entirewatchlist' => array(
                                ApiBase::PARAM_TYPE => 'boolean'
                        ),
@@ -194,11 +202,15 @@ class ApiSetNotificationTimestamp extends ApiBase {
                                ApiBase::PARAM_TYPE => 'integer'
                        ),
                );
+               if ( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags );
+               }
+               return $result;
+
        }
 
        public function getParamDescription() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getParamDescription() + array(
+               return $this->getPageSet()->getParamDescription() + array(
                        'entirewatchlist' => 'Work on all watched pages',
                        'timestamp' => 'Timestamp to which to set the notification timestamp',
                        'torevid' => 'Revision to set the notification timestamp to (one page only)',
@@ -253,12 +265,14 @@ class ApiSetNotificationTimestamp extends ApiBase {
        }
 
        public function getPossibleErrors() {
-               $psModule = new ApiPageSet( $this );
+               $ps = $this->getPageSet();
                return array_merge(
                        parent::getPossibleErrors(),
-                       $psModule->getPossibleErrors(),
-                       $this->getRequireMaxOneParameterErrorMessages( array( 'timestamp', 'torevid', 'newerthanrevid' ) ),
-                       $this->getRequireOnlyOneParameterErrorMessages( array_merge( array( 'entirewatchlist' ), array_keys( $psModule->getAllowedParams() ) ) ),
+                       $ps->getPossibleErrors(),
+                       $this->getRequireMaxOneParameterErrorMessages(
+                               array( 'timestamp', 'torevid', 'newerthanrevid' ) ),
+                       $this->getRequireOnlyOneParameterErrorMessages(
+                               array_merge( array( 'entirewatchlist' ), array_keys( $ps->getFinalParams() ) ) ),
                        array(
                                array( 'code' => 'notloggedin', 'info' => 'Anonymous users cannot use watchlist change notifications' ),
                                array( 'code' => 'multpages', 'info' => 'torevid may only be used with a single page' ),
index 2be2b24..518bfce 100644 (file)
  */
 class ApiTokens extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                wfProfileIn( __METHOD__ );
                $params = $this->extractRequestParams();
index 5802a98..bc7f6e7 100644 (file)
  */
 class ApiUnblock extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Unblocks the specified user or provides the reason the unblock failed.
         */
index b1eeff3..f53f065 100644 (file)
  */
 class ApiUndelete extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $params = $this->extractRequestParams();
 
index 4afc8e7..a0da765 100644 (file)
@@ -36,10 +36,6 @@ class ApiUpload extends ApiBase {
 
        protected $mParams;
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                // Check whether upload is enabled
                if ( !UploadBase::isEnabled() ) {
@@ -53,6 +49,7 @@ class ApiUpload extends ApiBase {
                $request = $this->getMain()->getRequest();
                // Check if async mode is actually supported
                $this->mParams['async'] = ( $this->mParams['async'] && !wfIsWindows() );
+               $this->mParams['async'] = false; // XXX: disabled per bug 44080
                // Add the uploaded file to the params array
                $this->mParams['file'] = $request->getFileName( 'file' );
                $this->mParams['chunk'] = $request->getFileName( 'chunk' );
@@ -121,7 +118,7 @@ class ApiUpload extends ApiBase {
         * Get an uplaod result based on upload context
         * @return array
         */
-       private function getContextResult(){
+       private function getContextResult() {
                $warnings = $this->getApiWarnings();
                if ( $warnings && !$this->mParams['ignorewarnings'] ) {
                        // Get warnings formated in result array format
@@ -143,7 +140,7 @@ class ApiUpload extends ApiBase {
         * @param $warnings array Array of Api upload warnings
         * @return array
         */
-       private function getStashResult( $warnings ){
+       private function getStashResult( $warnings ) {
                $result = array ();
                // Some uploads can request they be stashed, so as not to publish them immediately.
                // In this case, a failure to stash ought to be fatal
@@ -165,7 +162,7 @@ class ApiUpload extends ApiBase {
         * @param $warnings array Array of Api upload warnings
         * @return array
         */
-       private function getWarningsResult( $warnings ){
+       private function getWarningsResult( $warnings ) {
                $result = array();
                $result['result'] = 'Warning';
                $result['warnings'] = $warnings;
@@ -197,7 +194,7 @@ class ApiUpload extends ApiBase {
                $request = $this->getMain()->getRequest();
                $chunkPath = $request->getFileTempname( 'chunk' );
                $chunkSize = $request->getUpload( 'chunk' )->getSize();
-               if ($this->mParams['offset'] == 0) {
+               if ( $this->mParams['offset'] == 0 ) {
                        $result['filekey'] = $this->performStash();
                } else {
                        $status = $this->mUpload->addChunk(
@@ -249,7 +246,7 @@ class ApiUpload extends ApiBase {
                                        }
 
                                        // We have a new filekey for the fully concatenated file.
-                                       $result['filekey'] =  $this->mUpload->getLocalFile()->getFileKey();
+                                       $result['filekey'] = $this->mUpload->getLocalFile()->getFileKey();
 
                                        // Remove chunk from stash. (Checks against user ownership of chunks.)
                                        $this->mUpload->stash->removeFile( $this->mParams['filekey'] );
@@ -281,7 +278,7 @@ class ApiUpload extends ApiBase {
                        $fileKey = $stashFile->getFileKey();
                } catch ( MWException $e ) {
                        $message = 'Stashing temporary file failed: ' . get_class( $e ) . ' ' . $e->getMessage();
-                       wfDebug( __METHOD__ . ' ' . $message . "\n");
+                       wfDebug( __METHOD__ . ' ' . $message . "\n" );
                        throw new MWException( $message );
                }
                return $fileKey;
@@ -365,7 +362,7 @@ class ApiUpload extends ApiBase {
                if ( $this->mParams['chunk'] ) {
                        // Chunk upload
                        $this->mUpload = new UploadFromChunks();
-                       if( isset( $this->mParams['filekey'] ) ){
+                       if( isset( $this->mParams['filekey'] ) ) {
                                // handle new chunk
                                $this->mUpload->continueChunks(
                                        $this->mParams['filename'],
@@ -522,7 +519,7 @@ class ApiUpload extends ApiBase {
                                break;
                        default:
                                $this->dieUsage( 'An unknown error occurred', 'unknown-error',
-                                               0, array( 'code' =>  $verification['status'] ) );
+                                               0, array( 'code' => $verification['status'] ) );
                                break;
                }
        }
@@ -661,7 +658,7 @@ class ApiUpload extends ApiBase {
        protected function checkAsyncDownloadEnabled() {
                global $wgAllowAsyncCopyUploads;
                if ( !$wgAllowAsyncCopyUploads ) {
-                       $this->dieUsage( 'Asynchronous copy uploads disabled', 'asynccopyuploaddisabled');
+                       $this->dieUsage( 'Asynchronous copy uploads disabled', 'asynccopyuploaddisabled' );
                }
        }
 
@@ -794,7 +791,7 @@ class ApiUpload extends ApiBase {
                        ' * Have the MediaWiki server fetch a file from a URL, using the "url" parameter',
                        ' * Complete an earlier upload that failed due to warnings, using the "filekey" parameter',
                        'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
-                       'sending the "file".  Also you must get and send an edit token before doing any upload stuff'
+                       'sending the "file". Also you must get and send an edit token before doing any upload stuff'
                );
        }
 
index 0c6ebb1..b9b1eed 100644 (file)
  */
 class ApiUserrights extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        private $mUser = null;
 
        public function execute() {
index 16da176..2454e33 100644 (file)
  */
 class ApiWatch extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                if ( !$user->isLoggedIn() ) {
index 0710caa..a4aa79e 100644 (file)
@@ -268,8 +268,8 @@ class BacklinkCache {
                                        "{$prefix}_namespace" => $this->title->getNamespace(),
                                        "{$prefix}_title"     => $this->title->getDBkey(),
                                        $this->getDb()->makeList( array(
-                                               "{$prefix}_interwiki = ''",
-                                               "{$prefix}_interwiki is null",
+                                               "{$prefix}_interwiki" => '',
+                                               "{$prefix}_interwiki IS NULL",
                                        ), LIST_OR ),
                                        "page_id={$prefix}_from"
                                );
index 5cdc867..c67b655 100644 (file)
@@ -404,7 +404,7 @@ class GlobalDependency extends CacheDependency {
         * @return bool
         */
        function isExpired() {
-               if( !isset($GLOBALS[$this->name]) ) {
+               if( !isset( $GLOBALS[$this->name] ) ) {
                        return true;
                }
                return $GLOBALS[$this->name] != $this->value;
index 1a08d9f..ccdd98a 100644 (file)
@@ -163,7 +163,7 @@ abstract class FileCacheBase {
 
                $this->checkCacheDirs(); // build parent dir
                if ( !file_put_contents( $this->cachePath(), $text, LOCK_EX ) ) {
-                       wfDebug( __METHOD__ . "() failed saving ". $this->cachePath() . "\n");
+                       wfDebug( __METHOD__ . "() failed saving ". $this->cachePath() . "\n" );
                        $this->mCached = null;
                        return false;
                }
index fca071a..055fd68 100644 (file)
@@ -128,7 +128,7 @@ class HTMLFileCache extends FileCacheBase {
        public function loadFromFileCache( IContextSource $context ) {
                global $wgMimeType, $wgLanguageCode;
 
-               wfDebug( __METHOD__ . "()\n");
+               wfDebug( __METHOD__ . "()\n" );
                $filename = $this->cachePath();
 
                $context->getOutput()->sendCacheControl();
@@ -168,10 +168,10 @@ class HTMLFileCache extends FileCacheBase {
                $now = wfTimestampNow();
                if ( $this->useGzip() ) {
                        $text = str_replace(
-                               '</html>', '<!-- Cached/compressed '.$now." -->\n</html>", $text );
+                               '</html>', '<!-- Cached/compressed ' . $now . " -->\n</html>", $text );
                } else {
                        $text = str_replace(
-                               '</html>', '<!-- Cached '.$now." -->\n</html>", $text );
+                               '</html>', '<!-- Cached ' . $now . " -->\n</html>", $text );
                }
 
                // Store text to FS...
index 7cc1b9c..dc3151e 100644 (file)
@@ -604,7 +604,7 @@ class LocalisationCache {
                                } elseif ( in_array( $key, self::$mergeableAliasListKeys ) ) {
                                        $value = array_merge_recursive( $value, $fallbackValue );
                                } elseif ( in_array( $key, self::$optionalMergeKeys ) ) {
-                                       if ( !empty( $value['inherit'] ) )  {
+                                       if ( !empty( $value['inherit'] ) ) {
                                                $value = array_merge( $fallbackValue, $value );
                                        }
 
index e2cf1b4..89e5325 100644 (file)
@@ -499,7 +499,7 @@ class MessageCache {
 
                // Also delete cached sidebar... just in case it is affected
                $codes = array( $code );
-               if ( $code === 'en'  ) {
+               if ( $code === 'en' ) {
                        // Delete all sidebars, like for example on action=purge on the
                        // sidebar messages
                        $codes = array_keys( Language::fetchLanguageNames() );
@@ -545,7 +545,7 @@ class MessageCache {
                        $serialized = serialize( $cache );
                        $hash = md5( $serialized );
                        $this->mMemc->set( wfMemcKey( 'messages', $code, 'hash' ), $hash, $this->mExpiry );
-                       if ($wgLocalMessageCacheSerialized) {
+                       if ( $wgLocalMessageCacheSerialized ) {
                                $this->saveToLocal( $serialized, $hash, $code );
                        } else {
                                $this->saveToScript( $cache, $hash, $code );
index bcc8446..784e30e 100644 (file)
@@ -67,7 +67,7 @@ class SquidUpdate {
                $blurlArr = $title->getSquidURLs();
                if ( $res->numRows() <= $wgMaxSquidPurgeTitles ) {
                        foreach ( $res as $BL ) {
-                               $tobj = Title::makeTitle( $BL->page_namespace, $BL->page_title ) ;
+                               $tobj = Title::makeTitle( $BL->page_namespace, $BL->page_title );
                                $blurlArr[] = $tobj->getInternalURL();
                        }
                }
diff --git a/includes/clientpool/RedisConnectionPool.php b/includes/clientpool/RedisConnectionPool.php
new file mode 100644 (file)
index 0000000..eace85a
--- /dev/null
@@ -0,0 +1,299 @@
+<?php
+/**
+ * PhpRedis client connection pooling manager.
+ *
+ * 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
+ * @defgroup Redis Redis
+ * @author Aaron Schulz
+ */
+
+/**
+ * Helper class to manage redis connections using PhpRedis.
+ *
+ * This can be used to get handle wrappers that free the handle when the wrapper
+ * leaves scope. The maximum number of free handles (connections) is configurable.
+ * This provides an easy way to cache connection handles that may also have state,
+ * such as a handle does between multi() and exec(), and without hoarding connections.
+ * The wrappers use PHP magic methods so that calling functions on them calls the
+ * function of the actual Redis object handle.
+ *
+ * @ingroup Redis
+ * @since 1.21
+ */
+class RedisConnectionPool {
+       // Settings for all connections in this pool
+       protected $connectTimeout; // string; connection timeout
+       protected $persistent; // bool; whether connections persist
+       protected $password; // string; plaintext auth password
+       protected $poolSize; // integer; maximum number of idle connections
+       protected $serializer; // integer; the serializer to use (Redis::SERIALIZER_*)
+
+       protected $idlePoolSize = 0; // integer; current idle pool size
+
+       /** @var Array (server name => ((connection info array),...) */
+       protected $connections = array();
+       /** @var Array (server name => UNIX timestamp) */
+       protected $downServers = array();
+
+       /** @var Array */
+       protected static $instances = array(); // (pool ID => RedisConnectionPool)
+
+       const SERVER_DOWN_TTL = 30; // integer; seconds to cache servers as "down"
+
+       /**
+        * $options include:
+        *   - connectTimeout : The timeout for new connections, in seconds.
+        *                      Optional, default is 1 second.
+        *   - persistent     : Set this to true to allow connections to persist across
+        *                      multiple web requests. False by default.
+        *   - poolSize       : Maximim number of idle connections. Default is 5.
+        *   - password       : The authentication password, will be sent to Redis in clear text.
+        *                      Optional, if it is unspecified, no AUTH command will be sent.
+        *   - serializer     : Set to "php" or "igbinary". Default is "php".
+        * @param array $options
+        */
+       protected function __construct( array $options ) {
+               if ( !extension_loaded( 'redis' ) ) {
+                       throw new MWException( __CLASS__. ' requires the phpredis extension: ' .
+                               'https://github.com/nicolasff/phpredis' );
+               }
+               $this->connectTimeout = isset( $options['connectTimeout'] )
+                       ? $options['connectTimeout']
+                       : 1;
+               $this->persistent = isset( $options['persistent'] )
+                       ? $options['persistent']
+                       : false;
+               $this->password = isset( $options['password'] )
+                       ? $options['password']
+                       : '';
+               $this->poolSize = isset( $options['poolSize'] )
+                       ? $options['poolSize']
+                       : 5;
+               if ( !isset( $options['serializer'] ) || $options['serializer'] === 'php' ) {
+                       $this->serializer = Redis::SERIALIZER_PHP;
+               } elseif ( $options['serializer'] === 'igbinary' ) {
+                       $this->serializer = Redis::SERIALIZER_IGBINARY;
+               } else {
+                       throw new MWException( "Invalid serializer specified." );
+               }
+       }
+
+       /**
+        * @param $options Array
+        * @return RedisConnectionPool
+        */
+       public static function singleton( array $options ) {
+               ksort( $options ); // normalize
+               $id = sha1( serialize( $options ) );
+               if ( !isset( self::$instances[$id] ) ) {
+                       self::$instances[$id] = new self( $options );
+                       wfDebug( "Creating a new " . __CLASS__ . " instance with id $id." );
+               }
+               return self::$instances[$id];
+       }
+
+       /**
+        * Get a connection to a redis server. Based on code in RedisBagOStuff.php.
+        *
+        * @param $server string A hostname/port combination or the absolute path of a UNIX socket.
+        *                       If a hostname is specified but no port, port 6379 will be used.
+        * @return RedisConnRef|bool Returns false on failure
+        * @throws MWException
+        */
+       public function getConnection( $server ) {
+               // Check the listing "dead" servers which have had a connection errors.
+               // Servers are marked dead for a limited period of time, to
+               // avoid excessive overhead from repeated connection timeouts.
+               if ( isset( $this->downServers[$server] ) ) {
+                       $now = time();
+                       if ( $now > $this->downServers[$server] ) {
+                               // Dead time expired
+                               unset( $this->downServers[$server] );
+                       } else {
+                               // Server is dead
+                               wfDebug( "server $server is marked down for another " .
+                                       ( $this->downServers[$server] - $now ) . " seconds, can't get connection" );
+                               return false;
+                       }
+               }
+
+               // Check if a connection is already free for use
+               if ( isset( $this->connections[$server] ) ) {
+                       foreach ( $this->connections[$server] as &$connection ) {
+                               if ( $connection['free'] ) {
+                                       $connection['free'] = false;
+                                       --$this->idlePoolSize;
+                                       return new RedisConnRef( $this, $server, $connection['conn'] );
+                               }
+                       }
+               }
+
+               if ( substr( $server, 0, 1 ) === '/' ) {
+                       // UNIX domain socket
+                       // These are required by the redis extension to start with a slash, but
+                       // we still need to set the port to a special value to make it work.
+                       $host = $server;
+                       $port = 0;
+               } else {
+                       // TCP connection
+                       $hostPort = IP::splitHostAndPort( $server );
+                       if ( !$hostPort ) {
+                               throw new MWException( __CLASS__.": invalid configured server \"$server\"" );
+                       }
+                       list( $host, $port ) = $hostPort;
+                       if ( $port === false ) {
+                               $port = 6379;
+                       }
+               }
+
+               $conn = new Redis();
+               try {
+                       if ( $this->persistent ) {
+                               $result = $conn->pconnect( $host, $port, $this->connectTimeout );
+                       } else {
+                               $result = $conn->connect( $host, $port, $this->connectTimeout );
+                       }
+                       if ( !$result ) {
+                               wfDebugLog( 'redis', "Could not connect to server $server" );
+                               // Mark server down for some time to avoid further timeouts
+                               $this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
+                               return false;
+                       }
+                       if ( $this->password !== null ) {
+                               if ( !$conn->auth( $this->password ) ) {
+                                       wfDebugLog( 'redis', "Authentication error connecting to $server" );
+                               }
+                       }
+               } catch ( RedisException $e ) {
+                       $this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
+                       wfDebugLog( 'redis', "Redis exception: " . $e->getMessage() . "\n" );
+                       return false;
+               }
+
+               if ( $conn ) {
+                       $conn->setOption( Redis::OPT_SERIALIZER, $this->serializer );
+                       $this->connections[$server][] = array( 'conn' => $conn, 'free' => false );
+                       return new RedisConnRef( $this, $server, $conn );
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Mark a connection to a server as free to return to the pool
+        *
+        * @param $server string
+        * @param $conn Redis
+        * @return boolean
+        */
+       public function freeConnection( $server, Redis $conn ) {
+               $found = false;
+
+               foreach ( $this->connections[$server] as &$connection ) {
+                       if ( $connection['conn'] === $conn && !$connection['free'] ) {
+                               $connection['free'] = true;
+                               ++$this->idlePoolSize;
+                               break;
+                       }
+               }
+
+               $this->closeExcessIdleConections();
+
+               return $found;
+       }
+
+       /**
+        * Close any extra idle connections if there are more than the limit
+        *
+        * @return void
+        */
+       protected function closeExcessIdleConections() {
+               if ( $this->idlePoolSize <= $this->poolSize ) {
+                       return; // nothing to do
+               }
+
+               foreach ( $this->connections as $server => &$serverConnections ) {
+                       foreach ( $serverConnections as $key => &$connection ) {
+                               if ( $connection['free'] ) {
+                                       unset( $serverConnections[$key] );
+                                       if ( --$this->idlePoolSize <= $this->poolSize ) {
+                                               return; // done
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * The redis extension throws an exception in response to various read, write
+        * and protocol errors. Sometimes it also closes the connection, sometimes
+        * not. The safest response for us is to explicitly destroy the connection
+        * object and let it be reopened during the next request.
+        *
+        * @param $server string
+        * @param $conn RedisConnRef
+        * @param $e RedisException
+        * @return void
+        */
+       public function handleException( $server, RedisConnRef $conn, RedisException $e ) {
+               wfDebugLog( 'redis',
+                       "Redis exception on server $server: " . $e->getMessage() . "\n" );
+               foreach ( $this->connections[$server] as $key => $connection ) {
+                       if ( $connection['conn'] === $conn ) {
+                               $this->idlePoolSize -= $connection['free'] ? 1 : 0;
+                               unset( $this->connections[$server][$key] );
+                               break;
+                       }
+               }
+       }
+}
+
+/**
+ * Helper class to handle automatically marking connectons as reusable (via RAII pattern)
+ *
+ * @ingroup Redis
+ * @since 1.21
+ */
+class RedisConnRef {
+       /** @var RedisConnectionPool */
+       protected $pool;
+
+       protected $server; // string
+
+       /** @var Redis */
+       protected $conn;
+
+       /**
+        * @param $pool RedisConnectionPool
+        * @param $server string
+        * @param $conn Redis
+        */
+       public function __construct( RedisConnectionPool $pool, $server, Redis $conn ) {
+               $this->pool = $pool;
+               $this->server = $server;
+               $this->conn = $conn;
+       }
+
+       public function __call( $name, $arguments ) {
+               return call_user_func_array( array( $this->conn, $name ), $arguments );
+       }
+
+       function __destruct() {
+               $this->pool->freeConnection( $this->server, $this->conn );
+       }
+}
index cab65a5..e14fb56 100644 (file)
@@ -75,7 +75,7 @@ abstract class AbstractContent implements Content {
                if ( $modelId !== $this->model_id ) {
                        throw new MWException(
                                "Bad content model: " .
-                               "expected {$this->model_id}  " .
+                               "expected {$this->model_id} " .
                                "but got $modelId."
                        );
                }
@@ -214,7 +214,7 @@ abstract class AbstractContent implements Content {
         * resulting ParserOutput object.
         *
         * Subclasses may override this to determine the secondary data updates more
-        * efficiently, preferrably without the need to generate a parser output object.
+        * efficiently, preferably without the need to generate a parser output object.
         *
         * @see Content::getSecondaryDataUpdates()
         *
@@ -236,7 +236,7 @@ abstract class AbstractContent implements Content {
                Content $old = null,
                $recursive = true, ParserOutput $parserOutput = null
        ) {
-               if ( !$parserOutput ) {
+               if ( $parserOutput === null ) {
                        $parserOutput = $this->getParserOutput( $title, null, null, false );
                }
 
@@ -338,7 +338,7 @@ abstract class AbstractContent implements Content {
         *
         * @since 1.21
         */
-       public function replaceSection( $section, Content $with, $sectionTitle = ''  ) {
+       public function replaceSection( $section, Content $with, $sectionTitle = '' ) {
                return null;
        }
 
index 75ac5f2..31345af 100644 (file)
@@ -391,7 +391,7 @@ interface Content {
         * @param $sectionTitle String: new section's subject, only if $section is 'new'
         * @return string Complete article text, or null if error
         */
-       public function replaceSection( $section, Content $with, $sectionTitle = ''  );
+       public function replaceSection( $section, Content $with, $sectionTitle = '' );
 
        /**
         * Returns a Content object with pre-save transformations applied (or this
index ccc9b2c..5e0447f 100644 (file)
@@ -413,7 +413,7 @@ abstract class ContentHandler {
         * @param $format null|String The desired serialization format
         * @return string Serialized form of the content
         */
-       public abstract function serializeContent( Content $content, $format = null );
+       abstract public function serializeContent( Content $content, $format = null );
 
        /**
         * Unserializes a Content object of the type supported by this ContentHandler.
@@ -424,7 +424,7 @@ abstract class ContentHandler {
         * @param $format null|String the format used for serialization
         * @return Content the Content object created by deserializing $blob
         */
-       public abstract function unserializeContent( $blob, $format = null );
+       abstract public function unserializeContent( $blob, $format = null );
 
        /**
         * Creates an empty Content object of the type supported by this
@@ -434,7 +434,7 @@ abstract class ContentHandler {
         *
         * @return Content
         */
-       public abstract function makeEmptyContent();
+       abstract public function makeEmptyContent();
 
        /**
         * Creates a new Content object that acts as a redirect to the given page,
@@ -1074,7 +1074,7 @@ abstract class ContentHandler {
 
                        wfRestoreWarnings();
 
-                       wfWarn( "Using obsolete hook $event via ContentHandler::runLegacyHooks()! Handlers: " . implode(', ', $handlerInfo), 2 );
+                       wfWarn( "Using obsolete hook $event via ContentHandler::runLegacyHooks()! Handlers: " . implode( ', ', $handlerInfo ), 2 );
                }
 
                // convert Content objects to text
@@ -1114,4 +1114,3 @@ abstract class ContentHandler {
                return $ok;
        }
 }
-
index 8d778f5..89aac20 100644 (file)
@@ -241,7 +241,7 @@ class WikitextContent extends TextContent {
                        case 'any':
                                return true;
                        case 'comma':
-                               return strpos( $text,  ',' ) !== false;
+                               return strpos( $text, ',' ) !== false;
                        case 'link':
                                if ( $hasLinks === null ) { # not known, find out
                                        if ( !$title ) {
index 96d27b0..09cb409 100644 (file)
@@ -278,10 +278,14 @@ class RequestContext implements IContextSource {
         */
        public function getLanguage() {
                if ( isset( $this->recursion ) ) {
-                       throw new MWException( 'Recursion detected' );
-               }
-
-               if ( $this->lang === null ) {
+                       trigger_error( "Recursion detected in " . __METHOD__, E_USER_WARNING );
+                       $e = new Exception;
+                       wfDebugLog( 'recursion-guard', "Recursion detected:\n" . $e->getTraceAsString() );
+
+                       global $wgLanguageCode;
+                       $code = ( $wgLanguageCode ) ? $wgLanguageCode : 'en';
+                       $this->lang = Language::factory( $code );
+               } elseif ( $this->lang === null ) {
                        $this->recursion = true;
 
                        global $wgLanguageCode, $wgContLang;
index 4ff7913..56717b6 100644 (file)
@@ -100,12 +100,12 @@ class CloneDatabase {
 
                        if( $this->dropCurrentTables && !in_array( $this->db->getType(), array( 'postgres', 'oracle' ) ) ) {
                                $this->db->dropTable( $tbl, __METHOD__ );
-                               wfDebug( __METHOD__." dropping {$newTableName}\n", true);
+                               wfDebug( __METHOD__ . " dropping {$newTableName}\n", true );
                                //Dropping the oldTable because the prefix was changed
                        }
 
                        # Create new table
-                       wfDebug( __METHOD__." duplicating $oldTableName to $newTableName\n", true );
+                       wfDebug( __METHOD__ . " duplicating $oldTableName to $newTableName\n", true );
                        $this->db->duplicateTableStructure( $oldTableName, $newTableName, $this->useTemporaryTables );
                }
        }
index cf93508..05a0ca0 100644 (file)
@@ -62,9 +62,10 @@ interface DatabaseType {
         * Fetch the next row from the given result object, in object form.
         * Fields can be retrieved with $row->fieldname, with fields acting like
         * member variables.
+        * If no more rows are available, false is returned.
         *
         * @param $res ResultWrapper|object as returned from DatabaseBase::query(), etc.
-        * @return Row object
+        * @return object|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
        function fetchObject( $res );
@@ -72,9 +73,10 @@ interface DatabaseType {
        /**
         * Fetch the next row from the given result object, in associative array
         * form.  Fields are retrieved with $row['fieldname'].
+        * If no more rows are available, false is returned.
         *
         * @param $res ResultWrapper result object as returned from DatabaseBase::query(), etc.
-        * @return Row object
+        * @return array|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
        function fetchRow( $res );
@@ -112,8 +114,8 @@ interface DatabaseType {
         * The value inserted should be fetched from nextSequenceValue()
         *
         * Example:
-        * $id = $dbw->nextSequenceValue('page_page_id_seq');
-        * $dbw->insert('page',array('page_id' => $id));
+        * $id = $dbw->nextSequenceValue( 'page_page_id_seq' );
+        * $dbw->insert( 'page', array( 'page_id' => $id ) );
         * $id = $dbw->insertId();
         *
         * @return int
@@ -393,7 +395,7 @@ abstract class DatabaseBase implements DatabaseType {
                return wfSetVar( $this->mTablePrefix, $prefix );
        }
 
-       /**
+       /**
         * Set the filehandle to copy write statements to.
         *
         * @param $fh filehandle
@@ -584,7 +586,7 @@ abstract class DatabaseBase implements DatabaseType {
                global $wgDebugDBTransactions;
                $this->mFlags |= $flag;
                if ( ( $flag & DBO_TRX) & $wgDebugDBTransactions ) {
-                       wfDebug("Implicit transactions are now  disabled.\n");
+                       wfDebug( "Implicit transactions are now  disabled.\n" );
                }
        }
 
@@ -597,7 +599,7 @@ abstract class DatabaseBase implements DatabaseType {
                global $wgDebugDBTransactions;
                $this->mFlags &= ~$flag;
                if ( ( $flag & DBO_TRX ) && $wgDebugDBTransactions ) {
-                       wfDebug("Implicit transactions are now disabled.\n");
+                       wfDebug( "Implicit transactions are now disabled.\n" );
                }
        }
 
@@ -671,12 +673,12 @@ abstract class DatabaseBase implements DatabaseType {
                        if ( $wgCommandLineMode ) {
                                $this->mFlags &= ~DBO_TRX;
                                if ( $wgDebugDBTransactions ) {
-                                       wfDebug("Implicit transaction open disabled.\n");
+                                       wfDebug( "Implicit transaction open disabled.\n" );
                                }
                        } else {
                                $this->mFlags |= DBO_TRX;
                                if ( $wgDebugDBTransactions ) {
-                                       wfDebug("Implicit transaction open enabled.\n");
+                                       wfDebug( "Implicit transaction open enabled.\n" );
                                }
                        }
                }
@@ -724,7 +726,7 @@ abstract class DatabaseBase implements DatabaseType {
         *    Valid options are: host, user, password, dbname, flags, tablePrefix
         * @return DatabaseBase subclass or null
         */
-       public final static function factory( $dbType, $p = array() ) {
+       final public static function factory( $dbType, $p = array() ) {
                $canonicalDBTypes = array(
                        'mysql', 'postgres', 'sqlite', 'oracle', 'mssql', 'ibm_db2'
                );
@@ -772,7 +774,7 @@ abstract class DatabaseBase implements DatabaseType {
         * @param $errno
         * @param $errstr
         */
-       protected function connectionErrorHandler( $errno,  $errstr ) {
+       protected function connectionErrorHandler( $errno, $errstr ) {
                $this->mPHPError = $errstr;
        }
 
@@ -811,7 +813,7 @@ abstract class DatabaseBase implements DatabaseType {
         * @since 1.20
         * @return bool: Whether connection was closed successfully
         */
-       protected abstract function closeConnection();
+       abstract protected function closeConnection();
 
        /**
         * @param $error String: fallback error message, used if none is given by DB
@@ -833,7 +835,7 @@ abstract class DatabaseBase implements DatabaseType {
         * @param  $sql String: SQL query.
         * @return ResultWrapper Result object to feed to fetchObject, fetchRow, ...; or false on failure
         */
-       protected abstract function doQuery( $sql );
+       abstract protected function doQuery( $sql );
 
        /**
         * Determine whether a query writes to the DB.
@@ -921,7 +923,7 @@ abstract class DatabaseBase implements DatabaseType {
                        if ( strpos( $sqlstart, "SHOW " ) !== 0 && strpos( $sqlstart, "SET " ) !== 0 ) {
                                global $wgDebugDBTransactions;
                                if ( $wgDebugDBTransactions ) {
-                                       wfDebug("Implicit transaction start.\n");
+                                       wfDebug( "Implicit transaction start.\n" );
                                }
                                $this->begin( __METHOD__ . " ($fname)" );
                                $this->mTrxAutomatic = true;
@@ -1096,7 +1098,7 @@ abstract class DatabaseBase implements DatabaseType {
                        case '\\&': return '&';
                }
 
-               list( /* $n */ , $arg ) = each( $this->preparedArgs );
+               list( /* $n */, $arg ) = each( $this->preparedArgs );
 
                switch( $matches[1] ) {
                        case '?': return $this->addQuotes( $arg );
@@ -1180,26 +1182,9 @@ abstract class DatabaseBase implements DatabaseType {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $gb = is_array( $options['GROUP BY'] )
-                               ? implode( ',', $options['GROUP BY'] )
-                               : $options['GROUP BY'];
-                       $preLimitTail .= " GROUP BY {$gb}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
 
-               if ( isset( $options['HAVING'] ) ) {
-                       $having = is_array( $options['HAVING'] )
-                               ? $this->makeList( $options['HAVING'], LIST_AND )
-                               : $options['HAVING'];
-                       $preLimitTail .= " HAVING {$having}";
-               }
-
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $ob = is_array( $options['ORDER BY'] )
-                               ? implode( ',', $options['ORDER BY'] )
-                               : $options['ORDER BY'];
-                       $preLimitTail .= " ORDER BY {$ob}";
-               }
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                // if (isset($options['LIMIT'])) {
                //      $tailOpts .= $this->limitResult('', $options['LIMIT'],
@@ -1261,6 +1246,49 @@ abstract class DatabaseBase implements DatabaseType {
                return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail );
        }
 
+       /**
+        * Returns an optional GROUP BY with an optional HAVING
+        *
+        * @param $options Array: associative array of options
+        * @return string
+        * @see DatabaseBase::select()
+        * @since 1.21
+        */
+       public function makeGroupByWithHaving( $options ) {
+               $sql = '';
+               if ( isset( $options['GROUP BY'] ) ) {
+                       $gb = is_array( $options['GROUP BY'] )
+                               ? implode( ',', $options['GROUP BY'] )
+                               : $options['GROUP BY'];
+                       $sql .= ' GROUP BY ' . $gb;
+               }
+               if ( isset( $options['HAVING'] ) ) {
+                       $having = is_array( $options['HAVING'] )
+                               ? $this->makeList( $options['HAVING'], LIST_AND )
+                               : $options['HAVING'];
+                       $sql .= ' HAVING ' . $having;
+               }
+               return $sql;
+       }
+
+       /**
+        * Returns an optional ORDER BY
+        *
+        * @param $options Array: associative array of options
+        * @return string
+        * @see DatabaseBase::select()
+        * @since 1.21
+        */
+       public function makeOrderBy( $options ) {
+               if ( isset( $options['ORDER BY'] ) ) {
+                       $ob = is_array( $options['ORDER BY'] )
+                               ? implode( ',', $options['ORDER BY'] )
+                               : $options['ORDER BY'];
+                       return ' ORDER BY ' . $ob;
+               }
+               return '';
+       }
+
        /**
         * Execute a SELECT query constructed using the various parameters provided.
         * See below for full details of the parameters.
@@ -1393,7 +1421,7 @@ abstract class DatabaseBase implements DatabaseType {
         * join, the second is an SQL fragment giving the join condition for that
         * table. For example:
         *
-        *    array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
+        *    array( 'page' => array( 'LEFT JOIN', 'page_latest=rev_id' ) )
         *
         * @return ResultWrapper. If the query returned no rows, a ResultWrapper
         *   with no rows in it will be returned. If there was a query error, a
@@ -2030,47 +2058,39 @@ abstract class DatabaseBase implements DatabaseType {
                # Split database and table into proper variables.
                # We reverse the explode so that database.table and table both output
                # the correct table.
-               $dbDetails = array_reverse( explode( '.', $name, 2 ) );
-               if ( isset( $dbDetails[1] ) ) {
-                       list( $table, $database ) = $dbDetails;
+               $dbDetails = explode( '.', $name, 2 );
+               if ( count( $dbDetails ) == 2 ) {
+                       list( $database, $table ) = $dbDetails;
+                       # We don't want any prefix added in this case
+                       $prefix = '';
                } else {
                        list( $table ) = $dbDetails;
-               }
-               $prefix = $this->mTablePrefix; # Default prefix
-
-               # A database name has been specified in input. We don't want any
-               # prefixes added.
-               if ( isset( $database ) ) {
-                       $prefix = '';
+                       if ( $wgSharedDB !== null # We have a shared database
+                               && !$this->isQuotedIdentifier( $table ) # Paranoia check to prevent shared tables listing '`table`'
+                               && in_array( $table, $wgSharedTables ) # A shared table is selected
+                       ) {
+                               $database = $wgSharedDB;
+                               $prefix   = $wgSharedPrefix === null ? $this->mTablePrefix : $wgSharedPrefix;
+                       } else {
+                               $database = null;
+                               $prefix = $this->mTablePrefix; # Default prefix
+                       }
                }
 
-               # Note that we use the long format because php will complain in in_array if
-               # the input is not an array, and will complain in is_array if it is not set.
-               if ( !isset( $database ) # Don't use shared database if pre selected.
-                && isset( $wgSharedDB ) # We have a shared database
-                && !$this->isQuotedIdentifier( $table ) # Paranoia check to prevent shared tables listing '`table`'
-                && isset( $wgSharedTables )
-                && is_array( $wgSharedTables )
-                && in_array( $table, $wgSharedTables ) ) { # A shared table is selected
-                       $database = $wgSharedDB;
-                       $prefix   = isset( $wgSharedPrefix ) ? $wgSharedPrefix : $prefix;
+               # Quote $table and apply the prefix if not quoted.
+               $tableName = "{$prefix}{$table}";
+               if ( $format == 'quoted' && !$this->isQuotedIdentifier( $tableName ) ) {
+                       $tableName = $this->addIdentifierQuotes( $tableName );
                }
 
-               # Quote the $database and $table and apply the prefix if not quoted.
-               if ( isset( $database ) ) {
+               # Quote $database and merge it with the table name if needed
+               if ( $database !== null ) {
                        if ( $format == 'quoted' && !$this->isQuotedIdentifier( $database ) ) {
                                $database = $this->addIdentifierQuotes( $database );
                        }
+                       $tableName = $database . '.' . $tableName;
                }
 
-               $table = "{$prefix}{$table}";
-               if ( $format == 'quoted' && !$this->isQuotedIdentifier( $table ) ) {
-                       $table = $this->addIdentifierQuotes( "{$table}" );
-               }
-
-               # Merge our database and table into our final table name.
-               $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" );
-
                return $tableName;
        }
 
@@ -2079,7 +2099,7 @@ abstract class DatabaseBase implements DatabaseType {
         * This is handy when you need to construct SQL for joins
         *
         * Example:
-        * extract($dbr->tableNames('user','watchlist'));
+        * extract( $dbr->tableNames( 'user', 'watchlist' ) );
         * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
         *         WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
         *
@@ -2101,7 +2121,7 @@ abstract class DatabaseBase implements DatabaseType {
         * This is handy when you need to construct SQL for joins
         *
         * Example:
-        * list( $user, $watchlist ) = $dbr->tableNamesN('user','watchlist');
+        * list( $user, $watchlist ) = $dbr->tableNamesN( 'user', 'watchlist' );
         * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
         *         WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
         *
@@ -2653,7 +2673,7 @@ abstract class DatabaseBase implements DatabaseType {
                list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
 
                if ( is_array( $srcTable ) ) {
-                       $srcTable =  implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
+                       $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
                } else {
                        $srcTable = $this->tableName( $srcTable );
                }
@@ -2995,18 +3015,18 @@ abstract class DatabaseBase implements DatabaseType {
 
                if ( $this->mTrxLevel ) { // implicit commit
                        if ( !$this->mTrxAutomatic ) {
-                               // We want to warn about inadvertently nested begin/commit pairs, but not about auto-committing
-                               // implicit transactions that were started by query() because DBO_TRX was set.
-
-                               wfWarn( "$fname: Transaction already in progress (from {$this->mTrxFname}), " .
-                                       " performing implicit commit!" );
+                               // We want to warn about inadvertently nested begin/commit pairs, but not about
+                               // auto-committing implicit transactions that were started by query() via DBO_TRX
+                               $msg = "$fname: Transaction already in progress (from {$this->mTrxFname}), " .
+                                       " performing implicit commit!";
+                               wfWarn( $msg );
+                               wfLogDBError( $msg );
                        } else {
                                // if the transaction was automatic and has done write operations,
                                // log it if $wgDebugDBTransactions is enabled.
-
                                if ( $this->mTrxDoneWrites && $wgDebugDBTransactions ) {
-                                       wfDebug( "$fname: Automatic transaction with writes in progress (from {$this->mTrxFname}), " .
-                                               " performing implicit commit!\n" );
+                                       wfDebug( "$fname: Automatic transaction with writes in progress" .
+                                               " (from {$this->mTrxFname}), performing implicit commit!\n" );
                                }
                        }
 
@@ -3448,7 +3468,7 @@ abstract class DatabaseBase implements DatabaseType {
                        // replace `{$var}`
                        $ins = str_replace( '`{$' . $var . '}`', $this->addIdentifierQuotes( $value ), $ins );
                        // replace /*$var*/
-                       $ins = str_replace( '/*$' . $var . '*/', $this->strencode( $value ) , $ins );
+                       $ins = str_replace( '/*$' . $var . '*/', $this->strencode( $value ), $ins );
                }
                return $ins;
        }
index a53a674..18b2733 100644 (file)
@@ -176,7 +176,7 @@ class DBConnectionError extends DBError {
                return "$text<hr />$extra";
        }
 
-       public function reportHTML(){
+       public function reportHTML() {
                global $wgUseFileCache;
 
                # Check whether we can serve a file-cached copy of the page with the error underneath
@@ -289,10 +289,10 @@ class DBQueryError extends DBError {
         * @param $fname string
         */
        function __construct( DatabaseBase &$db, $error, $errno, $sql, $fname ) {
-               $message = "A database error has occurred.  Did you forget to run maintenance/update.php after upgrading?  See: https://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
-                 "Query: $sql\n" .
-                 "Function: $fname\n" .
-                 "Error: $errno $error\n";
+               $message = "A database error has occurred. Did you forget to run maintenance/update.php after upgrading?  See: https://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
+                       "Query: $sql\n" .
+                       "Function: $fname\n" .
+                       "Error: $errno $error\n";
                parent::__construct( $db, $message );
 
                $this->error = $error;
index 880d702..30bc665 100644 (file)
@@ -143,13 +143,12 @@ class IBM_DB2Result{
         * @param $sql String
         * @param $columns Array
         */
-       public function __construct( $db, $result, $num_rows, $sql, $columns ){
+       public function __construct( $db, $result, $num_rows, $sql, $columns ) {
                $this->db = $db;
 
-               if( $result instanceof ResultWrapper ){
+               if( $result instanceof ResultWrapper ) {
                        $this->result = $result->result;
-               }
-               else{
+               } else {
                        $this->result = $result;
                }
 
@@ -224,7 +223,7 @@ class IBM_DB2Result{
         * @return mixed Array on success, false on failure
         * @throws DBUnexpectedError
         */
-       public function fetchRow(){
+       public function fetchRow() {
                if ( $this->result
                                && $this->num_rows > 0
                                && $this->current_pos >= 0
@@ -239,7 +238,7 @@ class IBM_DB2Result{
                                }
                        }
 
-                       if ( $this->loadedLines > $this->current_pos ){
+                       if ( $this->loadedLines > $this->current_pos ) {
                                return $this->resultSet[$this->current_pos++];
                        }
 
@@ -251,7 +250,7 @@ class IBM_DB2Result{
         * Free a DB2 result object
         * @throws DBUnexpectedError
         */
-       public function freeResult(){
+       public function freeResult() {
                unset( $this->resultSet );
                if ( !@db2_free_result( $this->result ) ) {
                        throw new DBUnexpectedError( $this, "Unable to free DB2 result\n" );
@@ -420,7 +419,7 @@ class DatabaseIbm_db2 extends DatabaseBase {
         * Returns the database connection object
         * @return Object
         */
-       public function getDb(){
+       public function getDb() {
                return $this->mConn;
        }
 
@@ -686,9 +685,10 @@ class DatabaseIbm_db2 extends DatabaseBase {
         * Fetch the next row from the given result object, in object form.
         * Fields can be retrieved with $row->fieldname, with fields acting like
         * member variables.
+        * If no more rows are available, false is returned.
         *
         * @param $res array|ResultWrapper SQL result object as returned from Database::query(), etc.
-        * @return DB2 row object
+        * @return object|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
        public function fetchObject( $res ) {
@@ -708,9 +708,10 @@ class DatabaseIbm_db2 extends DatabaseBase {
        /**
         * Fetch the next row from the given result object, in associative array
         * form. Fields are retrieved with $row['fieldname'].
+        * If no more rows are available, false is returned.
         *
         * @param $res array|ResultWrapper SQL result object as returned from Database::query(), etc.
-        * @return ResultWrapper row object
+        * @return array|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
        public function fetchRow( $res ) {
@@ -788,8 +789,8 @@ class DatabaseIbm_db2 extends DatabaseBase {
                // Wide characters are evil -- some of them look like '
                $s = utf8_encode( $s );
                // Fix its stupidity
-               $from = array(  "\\\\", "\\'",  '\\n',  '\\t',  '\\"',  '\\r' );
-               $to = array(            "\\",           "''",           "\n",           "\t",           '"',            "\r" );
+               $from = array( "\\\\", "\\'", '\\n', '\\t', '\\"', '\\r' );
+               $to = array( "\\", "''", "\n", "\t", '"', "\r" );
                $s = str_replace( $from, $to, $s ); // DB2 expects '', not \' escaping
                return $s;
        }
@@ -1116,10 +1117,10 @@ class DatabaseIbm_db2 extends DatabaseBase {
 
                // find out the primary keys
                $keyres = $this->doQuery( "SELECT NAME FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = '"
-                 . strtoupper( $table )
-                 . "' AND TBCREATOR = '"
-                 . strtoupper( $schema )
-                 . "' AND KEYSEQ > 0" );
+                       . strtoupper( $table )
+                       . "' AND TBCREATOR = '"
+                       . strtoupper( $schema )
+                       . "' AND KEYSEQ > 0" );
 
                $keys = array();
                for (
@@ -1380,15 +1381,9 @@ class DatabaseIbm_db2 extends DatabaseBase {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $preLimitTail .= " GROUP BY {$options['GROUP BY']}";
-               }
-               if ( isset( $options['HAVING'] ) ) {
-                       $preLimitTail .= " HAVING {$options['HAVING']}";
-               }
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $preLimitTail .= " ORDER BY {$options['ORDER BY']}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
+
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                if ( isset( $noKeyOptions['DISTINCT'] )
                        || isset( $noKeyOptions['DISTINCTROW'] ) )
index 317ff09..1c920cb 100644 (file)
@@ -28,9 +28,9 @@
  * @ingroup Database
  */
 class DatabaseMssql extends DatabaseBase {
-       var $mInsertId = NULL;
-       var $mLastResult = NULL;
-       var $mAffectedRows = NULL;
+       var $mInsertId = null;
+       var $mLastResult = null;
+       var $mAffectedRows = null;
 
        var $mPort;
 
@@ -102,7 +102,7 @@ class DatabaseMssql extends DatabaseBase {
                $ntAuthPassTest = strtolower( $password );
 
                // Decide which auth scenerio to use
-               if( $ntAuthPassTest == 'ntauth' && $ntAuthUserTest == 'ntauth' ){
+               if( $ntAuthPassTest == 'ntauth' && $ntAuthUserTest == 'ntauth' ) {
                        // Don't add credentials to $connectionInfo
                } else {
                        $connectionInfo['UID'] = $user;
@@ -144,7 +144,7 @@ class DatabaseMssql extends DatabaseBase {
                // $this->limitResult();
                if ( preg_match( '/\bLIMIT\s*/i', $sql ) ) {
                        // massage LIMIT -> TopN
-                       $sql = $this->LimitToTopN( $sql ) ;
+                       $sql = $this->LimitToTopN( $sql );
                }
 
                // MSSQL doesn't have EXTRACT(epoch FROM XXX)
@@ -156,7 +156,7 @@ class DatabaseMssql extends DatabaseBase {
                // perform query
                $stmt = sqlsrv_query( $this->mConn, $sql );
                if ( $stmt == false ) {
-                       $message = "A database error has occurred.  Did you forget to run maintenance/update.php after upgrading?  See: http://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
+                       $message = "A database error has occurred. Did you forget to run maintenance/update.php after upgrading?  See: http://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
                                "Query: " . htmlentities( $sql ) . "\n" .
                                "Function: " . __METHOD__ . "\n";
                        // process each error (our driver will give us an array of errors unlike other providers)
@@ -319,7 +319,7 @@ class DatabaseMssql extends DatabaseBase {
                if ( isset( $options['EXPLAIN'] ) ) {
                        unset( $options['EXPLAIN'] );
                }
-               return parent::selectSQLText(  $table, $vars, $conds, $fname, $options, $join_conds );
+               return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );
        }
 
        /**
@@ -353,7 +353,7 @@ class DatabaseMssql extends DatabaseBase {
                $sql = "sp_helpindex '" . $table . "'";
                $res = $this->query( $sql, $fname );
                if ( !$res ) {
-                       return NULL;
+                       return null;
                }
 
                $result = array();
@@ -414,7 +414,7 @@ class DatabaseMssql extends DatabaseBase {
                $identity = null;
                $tableRaw = preg_replace( '#\[([^\]]*)\]#', '$1', $table ); // strip matching square brackets from table name
                $res = $this->doQuery( "SELECT NAME AS idColumn FROM SYS.IDENTITY_COLUMNS WHERE OBJECT_NAME(OBJECT_ID)='{$tableRaw}'" );
-               if( $res && $res->numrows() ){
+               if( $res && $res->numrows() ) {
                        // There is an identity for this table.
                        $identity = array_pop( $res->fetch( SQLSRV_FETCH_ASSOC ) );
                }
@@ -431,9 +431,9 @@ class DatabaseMssql extends DatabaseBase {
                                // iterate through
                                foreach ($a as $k => $v ) {
                                        if ( $k == $identity ) {
-                                               if( !is_null($v) ){
+                                               if( !is_null($v) ) {
                                                        // there is a value being passed to us, we need to turn on and off inserted identity
-                                                       $sqlPre = "SET IDENTITY_INSERT $table ON;" ;
+                                                       $sqlPre = "SET IDENTITY_INSERT $table ON;";
                                                        $sqlPost = ";SET IDENTITY_INSERT $table OFF;";
 
                                                } else {
@@ -484,7 +484,7 @@ class DatabaseMssql extends DatabaseBase {
                                } elseif ( is_array( $value ) || is_object( $value ) ) {
                                        if ( is_object( $value ) && strtolower( get_class( $value ) ) == 'blob' ) {
                                                $sql .= $this->addQuotes( $value );
-                                       }  else {
+                                       } else {
                                                $sql .= $this->addQuotes( serialize( $value ) );
                                        }
                                } else {
@@ -498,7 +498,7 @@ class DatabaseMssql extends DatabaseBase {
 
                        if ( $ret === false ) {
                                throw new DBQueryError( $this, $this->getErrors(), $this->lastErrno(), $sql, $fname );
-                       } elseif ( $ret != NULL ) {
+                       } elseif ( $ret != null ) {
                                // remember number of rows affected
                                $this->mAffectedRows = sqlsrv_rows_affected( $ret );
                                if ( !is_null($identity) ) {
@@ -536,12 +536,12 @@ class DatabaseMssql extends DatabaseBase {
 
                if ( $ret === false ) {
                        throw new DBQueryError( $this, $this->getErrors(), $this->lastErrno(), /*$sql*/ '', $fname );
-               } elseif ( $ret != NULL ) {
+               } elseif ( $ret != null ) {
                        // remember number of rows affected
                        $this->mAffectedRows = sqlsrv_rows_affected( $ret );
                        return $ret;
                }
-               return NULL;
+               return null;
        }
 
        /**
@@ -608,9 +608,9 @@ class DatabaseMssql extends DatabaseBase {
                } else {
                        $sql = '
                                SELECT * FROM (
-                                 SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 FROM (
-                                       SELECT 1 AS line2, sub1.* FROM (' . $sql . ') AS sub1
-                                 ) as sub2
+                                       SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 FROM (
+                                               SELECT 1 AS line2, sub1.* FROM (' . $sql . ') AS sub1
+                                       ) as sub2
                                ) AS sub3
                                WHERE line3 BETWEEN ' . ( $offset + 1 ) . ' AND ' . ( $offset + $limit );
                        return $sql;
@@ -770,17 +770,17 @@ class DatabaseMssql extends DatabaseBase {
                $newUser = $this->escapeIdentifier( $newUser );
                $loginPassword = $this->addQuotes( $loginPassword );
 
-               $this->doQuery("CREATE DATABASE $dbName;");
-               $this->doQuery("USE $dbName;");
-               $this->doQuery("CREATE SCHEMA $dbName;");
-               $this->doQuery("
+               $this->doQuery( "CREATE DATABASE $dbName;" );
+               $this->doQuery( "USE $dbName;" );
+               $this->doQuery( "CREATE SCHEMA $dbName;" );
+               $this->doQuery( "
                                                CREATE
                                                        LOGIN $newUser
                                                WITH
                                                        PASSWORD=$loginPassword
                                                ;
-                                       ");
-               $this->doQuery("
+                                       " );
+               $this->doQuery( "
                                                CREATE
                                                        USER $newUser
                                                FOR
@@ -788,8 +788,8 @@ class DatabaseMssql extends DatabaseBase {
                                                WITH
                                                        DEFAULT_SCHEMA=$dbName
                                                ;
-                                       ");
-               $this->doQuery("
+                                       " );
+               $this->doQuery( "
                                                GRANT
                                                        BACKUP DATABASE,
                                                        BACKUP LOG,
@@ -804,15 +804,15 @@ class DatabaseMssql extends DatabaseBase {
                                                        DATABASE::$dbName
                                                TO $newUser
                                                ;
-                                       ");
-               $this->doQuery("
+                                       " );
+               $this->doQuery( "
                                                GRANT
                                                        CONTROL
                                                ON
                                                        SCHEMA::$dbName
                                                TO $newUser
                                                ;
-                                       ");
+                                       " );
 
 
        }
@@ -908,29 +908,23 @@ class DatabaseMssql extends DatabaseBase {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $tailOpts .= " GROUP BY {$options['GROUP BY']}";
-               }
-               if ( isset( $options['HAVING'] ) ) {
-                       $tailOpts .= " HAVING {$options['GROUP BY']}";
-               }
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $tailOpts .= " ORDER BY {$options['ORDER BY']}";
-               }
+               $tailOpts .= $this->makeGroupByWithHaving( $options );
+
+               $tailOpts .= $this->makeOrderBy( $options );
 
                if ( isset( $noKeyOptions['DISTINCT'] ) && isset( $noKeyOptions['DISTINCTROW'] ) ) {
                        $startOpts .= 'DISTINCT';
                }
 
                // we want this to be compatible with the output of parent::makeSelectOptions()
-               return array( $startOpts, '' , $tailOpts, '' );
+               return array( $startOpts, '', $tailOpts, '' );
        }
 
        /**
         * Get the type of the DBMS, as it appears in $wgDBtype.
         * @return string
         */
-       function getType(){
+       function getType() {
                return 'mssql';
        }
 
@@ -1138,6 +1132,5 @@ class MssqlResult {
 
        public function free() {
                unset( $this->mRows );
-               return;
        }
 }
index 04c22f1..fab0e96 100644 (file)
@@ -193,7 +193,7 @@ class DatabaseMysql extends DatabaseBase {
 
        /**
         * @param $res ResultWrapper
-        * @return object|stdClass
+        * @return object|bool
         * @throws DBUnexpectedError
         */
        function fetchObject( $res ) {
@@ -217,7 +217,7 @@ class DatabaseMysql extends DatabaseBase {
 
        /**
         * @param $res ResultWrapper
-        * @return array
+        * @return array|bool
         * @throws DBUnexpectedError
         */
        function fetchRow( $res ) {
@@ -361,7 +361,7 @@ class DatabaseMysql extends DatabaseBase {
         * @param $options string|array
         * @return int
         */
-       public function estimateRowCount( $table, $vars='*', $conds='', $fname = 'DatabaseMysql::estimateRowCount', $options = array() ) {
+       public function estimateRowCount( $table, $vars = '*', $conds = '', $fname = 'DatabaseMysql::estimateRowCount', $options = array() ) {
                $options['EXPLAIN'] = true;
                $res = $this->select( $table, $vars, $conds, $fname, $options );
                if ( $res === false ) {
@@ -393,7 +393,7 @@ class DatabaseMysql extends DatabaseBase {
                for( $i = 0; $i < $n; $i++ ) {
                        $meta = mysql_fetch_field( $res->result, $i );
                        if( $field == $meta->name ) {
-                               return new MySQLField($meta);
+                               return new MySQLField( $meta );
                        }
                }
                return false;
@@ -449,7 +449,7 @@ class DatabaseMysql extends DatabaseBase {
        function strencode( $s ) {
                $sQuoted = mysql_real_escape_string( $s, $this->mConn );
 
-               if($sQuoted === false) {
+               if( $sQuoted === false ) {
                        $this->ping();
                        $sQuoted = mysql_real_escape_string( $s, $this->mConn );
                }
@@ -685,7 +685,7 @@ class DatabaseMysql extends DatabaseBase {
 
        public function streamStatementEnd( &$sql, &$newLine ) {
                if ( strtoupper( substr( $newLine, 0, 9 ) ) == 'DELIMITER' ) {
-                       preg_match( '/^DELIMITER\s+(\S+)/' , $newLine, $m );
+                       preg_match( '/^DELIMITER\s+(\S+)/', $newLine, $m );
                        $this->delimiter = $m[1];
                        $newLine = '';
                }
@@ -721,7 +721,7 @@ class DatabaseMysql extends DatabaseBase {
                if( $row->lockstatus == 1 ) {
                        return true;
                } else {
-                       wfDebug( __METHOD__." failed to acquire lock\n" );
+                       wfDebug( __METHOD__ . " failed to acquire lock\n" );
                        return false;
                }
        }
@@ -744,6 +744,7 @@ class DatabaseMysql extends DatabaseBase {
         * @param $write array
         * @param $method string
         * @param $lowPriority bool
+        * @return bool
         */
        public function lockTables( $read, $write, $method, $lowPriority = true ) {
                $items = array();
@@ -759,13 +760,16 @@ class DatabaseMysql extends DatabaseBase {
                }
                $sql = "LOCK TABLES " . implode( ',', $items );
                $this->query( $sql, $method );
+               return true;
        }
 
        /**
         * @param $method string
+        * @return bool
         */
        public function unlockTables( $method ) {
                $this->query( "UNLOCK TABLES", $method );
+               return true;
        }
 
        /**
@@ -899,7 +903,7 @@ class DatabaseMysql extends DatabaseBase {
                $endArray = array();
 
                foreach( $result as $table ) {
-                       $vars = get_object_vars($table);
+                       $vars = get_object_vars( $table );
                        $table = array_pop( $vars );
 
                        if( !$prefix || strpos( $table, $prefix ) === 0 ) {
index 7e3c0ca..626d841 100644 (file)
@@ -23,7 +23,7 @@
 
 /**
  * The oci8 extension is fairly weak and doesn't support oci_num_rows, among
- * other things.  We use a wrapper class to handle that and other
+ * other things. We use a wrapper class to handle that and other
  * Oracle-specific bits, like converting column names back to lowercase.
  * @ingroup Database
  */
@@ -69,7 +69,7 @@ class ORAResult {
                        $this->nrows = count( $this->rows );
                }
 
-               if ($this->nrows > 0) {
+               if ( $this->nrows > 0 ) {
                        foreach ( $this->rows[0] as $k => $v ) {
                                $this->columns[$k] = strtolower( oci_field_name( $stmt, $k + 1 ) );
                        }
@@ -80,7 +80,7 @@ class ORAResult {
        }
 
        public function free() {
-               unset($this->db);
+               unset( $this->db );
        }
 
        public function seek( $row ) {
@@ -92,7 +92,7 @@ class ORAResult {
        }
 
        public function numFields() {
-               return count($this->columns);
+               return count( $this->columns );
        }
 
        public function fetchObject() {
@@ -633,7 +633,7 @@ class DatabaseOracle extends DatabaseBase {
                }
                list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
                if ( is_array( $srcTable ) ) {
-                       $srcTable =  implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
+                       $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
                } else {
                        $srcTable = $this->tableName( $srcTable );
                }
@@ -756,7 +756,7 @@ class DatabaseOracle extends DatabaseBase {
 
        function unionQueries( $sqls, $all ) {
                $glue = ' UNION ALL ';
-               return 'SELECT * ' . ( $all ? '':'/* UNION_UNIQUE */ ' ) . 'FROM (' . implode( $glue, $sqls ) . ')' ;
+               return 'SELECT * ' . ( $all ? '':'/* UNION_UNIQUE */ ' ) . 'FROM (' . implode( $glue, $sqls ) . ')';
        }
 
        function wasDeadlock() {
@@ -778,8 +778,8 @@ class DatabaseOracle extends DatabaseBase {
 
        function listTables( $prefix = null, $fname = 'DatabaseOracle::listTables' ) {
                $listWhere = '';
-               if (!empty($prefix)) {
-                       $listWhere = ' AND table_name LIKE \''.strtoupper($prefix).'%\'';
+               if ( !empty( $prefix ) ) {
+                       $listWhere = ' AND table_name LIKE \'' . strtoupper( $prefix ) . '%\'';
                }
 
                $owner = strtoupper( $this->mDBname );
@@ -787,12 +787,12 @@ class DatabaseOracle extends DatabaseBase {
 
                // dirty code ... i know
                $endArray = array();
-               $endArray[] = strtoupper($prefix.'MWUSER');
-               $endArray[] = strtoupper($prefix.'PAGE');
-               $endArray[] = strtoupper($prefix.'IMAGE');
+               $endArray[] = strtoupper( $prefix . 'MWUSER' );
+               $endArray[] = strtoupper( $prefix . 'PAGE' );
+               $endArray[] = strtoupper( $prefix . 'IMAGE' );
                $fixedOrderTabs = $endArray;
-               while (($row = $result->fetchRow()) !== false) {
-                       if (!in_array($row['table_name'], $fixedOrderTabs))
+               while ( ($row = $result->fetchRow()) !== false ) {
+                       if ( !in_array( $row['table_name'], $fixedOrderTabs ) )
                                $endArray[] = $row['table_name'];
                }
 
@@ -800,7 +800,7 @@ class DatabaseOracle extends DatabaseBase {
        }
 
        public function dropTable( $tableName, $fName = 'DatabaseOracle::dropTable' ) {
-               $tableName = $this->tableName($tableName);
+               $tableName = $this->tableName( $tableName );
                if( !$this->tableExists( $tableName ) ) {
                        return false;
                }
@@ -846,7 +846,7 @@ class DatabaseOracle extends DatabaseBase {
        function getServerVersion() {
                //better version number, fallback on driver
                $rset = $this->doQuery( 'SELECT version FROM product_component_version WHERE UPPER(product) LIKE \'ORACLE DATABASE%\'' );
-               if ( !( $row =  $rset->fetchRow() ) ) {
+               if ( !( $row = $rset->fetchRow() ) ) {
                        return oci_server_version( $this->mConn );
                }
                return $row['version'];
@@ -907,7 +907,7 @@ class DatabaseOracle extends DatabaseBase {
                        $table = array_map( array( &$this, 'tableNameInternal' ), $table );
                        $tableWhere = 'IN (';
                        foreach( $table as &$singleTable ) {
-                               $singleTable = $this->removeIdentifierQuotes($singleTable);
+                               $singleTable = $this->removeIdentifierQuotes( $singleTable );
                                if ( isset( $this->mFieldInfoCache["$singleTable.$field"] ) ) {
                                        return $this->mFieldInfoCache["$singleTable.$field"];
                                }
@@ -915,14 +915,14 @@ class DatabaseOracle extends DatabaseBase {
                        }
                        $tableWhere = rtrim( $tableWhere, ',' ) . ')';
                } else {
-                       $table = $this->removeIdentifierQuotes(  $this->tableNameInternal( $table ) );
+                       $table = $this->removeIdentifierQuotes( $this->tableNameInternal( $table ) );
                        if ( isset( $this->mFieldInfoCache["$table.$field"] ) ) {
                                return $this->mFieldInfoCache["$table.$field"];
                        }
                        $tableWhere = '= \''.$table.'\'';
                }
 
-               $fieldInfoStmt = oci_parse( $this->mConn, 'SELECT * FROM wiki_field_info_full WHERE table_name '.$tableWhere.' and column_name = \''.$field.'\'' );
+               $fieldInfoStmt = oci_parse( $this->mConn, 'SELECT * FROM wiki_field_info_full WHERE table_name ' . $tableWhere . ' and column_name = \'' . $field . '\'' );
                if ( oci_execute( $fieldInfoStmt, $this->execFlags() ) === false ) {
                        $e = oci_error( $fieldInfoStmt );
                        $this->reportQueryError( $e['message'], $e['code'], 'fieldInfo QUERY', __METHOD__ );
@@ -957,7 +957,7 @@ class DatabaseOracle extends DatabaseBase {
                if ( is_array( $table ) ) {
                        throw new DBUnexpectedError( $this, 'DatabaseOracle::fieldInfo called with table array!' );
                }
-               return $this->fieldInfoMulti ($table, $field);
+               return $this->fieldInfoMulti( $table, $field );
        }
 
        protected function doBegin( $fname = 'DatabaseOracle::begin' ) {
@@ -1066,7 +1066,7 @@ class DatabaseOracle extends DatabaseBase {
                if ( $db == null || $db == $this->mUser ) {
                        return true;
                }
-               $sql = 'ALTER SESSION SET CURRENT_SCHEMA=' . strtoupper($db);
+               $sql = 'ALTER SESSION SET CURRENT_SCHEMA=' . strtoupper( $db );
                $stmt = oci_parse( $this->mConn, $sql );
                wfSuppressWarnings();
                $success = oci_execute( $stmt );
@@ -1101,11 +1101,11 @@ class DatabaseOracle extends DatabaseBase {
        }
 
        public function removeIdentifierQuotes( $s ) {
-               return strpos($s, '/*Q*/') === FALSE ? $s : substr($s, 5);
+               return strpos( $s, '/*Q*/' ) === false ? $s : substr( $s, 5 );
        }
 
        public function isQuotedIdentifier( $s ) {
-               return strpos($s, '/*Q*/') !== FALSE;
+               return strpos( $s, '/*Q*/' ) !== false;
        }
 
        private function wrapFieldForWhere( $table, &$col, &$val ) {
@@ -1139,7 +1139,7 @@ class DatabaseOracle extends DatabaseBase {
        }
 
        function selectRow( $table, $vars, $conds, $fname = 'DatabaseOracle::selectRow', $options = array(), $join_conds = array() ) {
-               if ( is_array($conds) ) {
+               if ( is_array( $conds ) ) {
                        $conds = $this->wrapConditionsForWhere( $table, $conds );
                }
                return parent::selectRow( $table, $vars, $conds, $fname, $options, $join_conds );
@@ -1166,26 +1166,9 @@ class DatabaseOracle extends DatabaseBase {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $gb = is_array( $options['GROUP BY'] )
-                               ? implode( ',', $options['GROUP BY'] )
-                               : $options['GROUP BY'];
-                       $preLimitTail .= " GROUP BY {$gb}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
 
-               if ( isset( $options['HAVING'] ) ) {
-                       $having = is_array( $options['HAVING'] )
-                               ? $this->makeList( $options['HAVING'], LIST_AND )
-                               : $options['HAVING'];
-                       $preLimitTail .= " HAVING {$having}";
-               }
-
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $ob = is_array( $options['ORDER BY'] )
-                               ? implode( ',', $options['ORDER BY'] )
-                               : $options['ORDER BY'];
-                       $preLimitTail .= " ORDER BY {$ob}";
-               }
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                if ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
                        $postLimitTail .= ' FOR UPDATE';
@@ -1203,15 +1186,15 @@ class DatabaseOracle extends DatabaseBase {
 
                return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail );
        }
-       
+
        public function delete( $table, $conds, $fname = 'DatabaseOracle::delete' ) {
-               if ( is_array($conds) ) {
+               if ( is_array( $conds ) ) {
                        $conds = $this->wrapConditionsForWhere( $table, $conds );
                }
                // a hack for deleting pages, users and images (which have non-nullable FKs)
                // all deletions on these tables have transactions so final failure rollbacks these updates
                $table = $this->tableName( $table );
-               if ( $table == $this->tableName( 'user' )  ) {
+               if ( $table == $this->tableName( 'user' ) ) {
                                $this->update( 'archive', array( 'ar_user' => 0 ), array( 'ar_user' => $conds['user_id'] ), $fname );
                                $this->update( 'ipblocks', array( 'ipb_user' => 0 ), array( 'ipb_user' => $conds['user_id'] ), $fname );
                                $this->update( 'image', array( 'img_user' => 0 ), array( 'img_user' => $conds['user_id'] ), $fname );
@@ -1221,7 +1204,7 @@ class DatabaseOracle extends DatabaseBase {
                                $this->update( 'uploadstash', array( 'us_user' => 0 ), array( 'us_user' => $conds['user_id'] ), $fname );
                                $this->update( 'recentchanges', array( 'rc_user' => 0 ), array( 'rc_user' => $conds['user_id'] ), $fname );
                                $this->update( 'logging', array( 'log_user' => 0 ), array( 'log_user' => $conds['user_id'] ), $fname );
-               } elseif ( $table == $this->tableName( 'image' )  ) {
+               } elseif ( $table == $this->tableName( 'image' ) ) {
                                $this->update( 'oldimage', array( 'oi_name' => 0 ), array( 'oi_name' => $conds['img_name'] ), $fname );
                }
                return parent::delete( $table, $conds, $fname );
index 419488e..2cbcc4b 100644 (file)
@@ -176,8 +176,8 @@ class PostgresTransactionState {
                                $old = reset( $this->mCurrentState );
                                $new = reset( $this->mNewState );
                                foreach ( self::$WATCHED as $watched ) {
-                                       if ($old !== $new) {
-                                               $this->log_changed($old, $new, $watched);
+                                       if ( $old !== $new ) {
+                                               $this->log_changed( $old, $new, $watched );
                                        }
                                        $old = next( $this->mCurrentState );
                                        $new = next( $this->mNewState );
@@ -197,11 +197,11 @@ class PostgresTransactionState {
        }
 
        protected function log_changed( $old, $new, $watched ) {
-               wfDebug(sprintf($watched["desc"],
+               wfDebug( sprintf( $watched["desc"],
                        $this->mConn,
                        $this->describe_changed( $old, $watched["states"] ),
-                       $this->describe_changed( $new, $watched["states"] ))
-               );
+                       $this->describe_changed( $new, $watched["states"] )
+               ) );
        }
 }
 
@@ -218,7 +218,7 @@ class SavepointPostgres {
        protected $id;
        protected $didbegin;
 
-       public function __construct ($dbw, $id) {
+       public function __construct ( $dbw, $id ) {
                $this->dbw = $dbw;
                $this->id = $id;
                $this->didbegin = false;
@@ -232,12 +232,14 @@ class SavepointPostgres {
        public function __destruct() {
                if ( $this->didbegin ) {
                        $this->dbw->rollback();
+                       $this->didbegin = false;
                }
        }
 
        public function commit() {
                if ( $this->didbegin ) {
                        $this->dbw->commit();
+                       $this->didbegin = false;
                }
        }
 
@@ -245,29 +247,29 @@ class SavepointPostgres {
                global $wgDebugDBTransactions;
                if ( $this->dbw->doQuery( $keyword . " " . $this->id ) !== false ) {
                        if ( $wgDebugDBTransactions ) {
-                               wfDebug( sprintf ($msg_ok, $this->id ) );
+                               wfDebug( sprintf ( $msg_ok, $this->id ) );
                        }
                } else {
-                       wfDebug( sprintf ($msg_failed, $this->id ) );
+                       wfDebug( sprintf ( $msg_failed, $this->id ) );
                }
        }
 
        public function savepoint() {
-               $this->query("SAVEPOINT",
+               $this->query( "SAVEPOINT",
                        "Transaction state: savepoint \"%s\" established.\n",
                        "Transaction state: establishment of savepoint \"%s\" FAILED.\n"
                );
        }
 
        public function release() {
-               $this->query("RELEASE",
+               $this->query( "RELEASE",
                        "Transaction state: savepoint \"%s\" released.\n",
                        "Transaction state: release of savepoint \"%s\" FAILED.\n"
                );
        }
 
        public function rollback() {
-               $this->query("ROLLBACK TO",
+               $this->query( "ROLLBACK TO",
                        "Transaction state: savepoint \"%s\" rolled back.\n",
                        "Transaction state: rollback of savepoint \"%s\" FAILED.\n"
                );
@@ -391,6 +393,9 @@ class DatabasePostgres extends DatabaseBase {
                $this->query( "SET datestyle = 'ISO, YMD'", __METHOD__ );
                $this->query( "SET timezone = 'GMT'", __METHOD__ );
                $this->query( "SET standard_conforming_strings = on", __METHOD__ );
+               if ( $this->getServerVersion() >= 9.0 ) {
+                       $this->query( "SET bytea_output = 'escape'", __METHOD__ ); // PHP bug 53127
+               }
 
                global $wgDBmwschema;
                $this->determineCoreSchema( $wgDBmwschema );
@@ -604,7 +609,7 @@ class DatabasePostgres extends DatabaseBase {
         * Takes same arguments as Database::select()
         * @return int
         */
-       function estimateRowCount( $table, $vars = '*', $conds='', $fname = 'DatabasePostgres::estimateRowCount', $options = array() ) {
+       function estimateRowCount( $table, $vars = '*', $conds = '', $fname = 'DatabasePostgres::estimateRowCount', $options = array() ) {
                $options['EXPLAIN'] = true;
                $res = $this->select( $table, $vars, $conds, $fname, $options );
                $rows = -1;
@@ -682,7 +687,7 @@ class DatabasePostgres extends DatabaseBase {
                                        AND     i.indclass[s.g] = opcls.oid
                                        AND     pg_am.oid = opcls.opcmethod
 __INDEXATTR__;
-               $res = $this->query($sql, __METHOD__);
+               $res = $this->query( $sql, __METHOD__ );
                $a = array();
                if ( $res ) {
                        foreach ( $res as $row ) {
@@ -690,7 +695,7 @@ __INDEXATTR__;
                                        $row->attname,
                                        $row->opcname,
                                        $row->amname,
-                                       $row->option);
+                                       $row->option );
                        }
                } else {
                        return null;
@@ -733,7 +738,7 @@ __INDEXATTR__;
                }
 
                $table = $this->tableName( $table );
-               if (isset( $this->numeric_version ) ) {
+               if ( !isset( $this->numeric_version ) ) {
                        $this->getServerVersion();
                }
 
@@ -985,7 +990,7 @@ __INDEXATTR__;
                $endArray = array();
 
                foreach( $result as $table ) {
-                       $vars = get_object_vars($table);
+                       $vars = get_object_vars( $table );
                        $table = array_pop( $vars );
                        if( !$prefix || strpos( $table, $prefix ) === 0 ) {
                                $endArray[] = $table;
@@ -1066,7 +1071,7 @@ __INDEXATTR__;
         * @return string return default schema for the current session
         */
        function getCurrentSchema() {
-               $res = $this->query( "SELECT current_schema()", __METHOD__);
+               $res = $this->query( "SELECT current_schema()", __METHOD__ );
                $row = $this->fetchRow( $res );
                return $row[0];
        }
@@ -1082,11 +1087,11 @@ __INDEXATTR__;
         * @return array list of actual schemas for the current sesson
         */
        function getSchemas() {
-               $res = $this->query( "SELECT current_schemas(false)", __METHOD__);
+               $res = $this->query( "SELECT current_schemas(false)", __METHOD__ );
                $row = $this->fetchRow( $res );
                $schemas = array();
                /* PHP pgsql support does not support array type, "{a,b}" string is returned */
-               return $this->pg_array_parse($row[0], $schemas);
+               return $this->pg_array_parse( $row[0], $schemas );
        }
 
        /**
@@ -1099,10 +1104,10 @@ __INDEXATTR__;
         * @return array how to search for table names schemas for the current user
         */
        function getSearchPath() {
-               $res = $this->query( "SHOW search_path", __METHOD__);
+               $res = $this->query( "SHOW search_path", __METHOD__ );
                $row = $this->fetchRow( $res );
                /* PostgreSQL returns SHOW values as strings */
-               return explode(",", $row[0]);
+               return explode( ",", $row[0] );
        }
 
        /**
@@ -1113,7 +1118,7 @@ __INDEXATTR__;
         * @param $search_path array list of schemas to be searched by default
         */
        function setSearchPath( $search_path ) {
-               $this->query( "SET search_path = " . implode(", ", $search_path) );
+               $this->query( "SET search_path = " . implode( ", ", $search_path ) );
        }
 
        /**
@@ -1134,7 +1139,7 @@ __INDEXATTR__;
                if ( $this->schemaExists( $desired_schema ) ) {
                        if ( in_array( $desired_schema, $this->getSchemas() ) ) {
                                $this->mCoreSchema = $desired_schema;
-                               wfDebug("Schema \"" . $desired_schema . "\" already in the search path\n");
+                               wfDebug( "Schema \"" . $desired_schema . "\" already in the search path\n" );
                        } else {
                                /**
                                 * Prepend our schema (e.g. 'mediawiki') in front
@@ -1146,11 +1151,11 @@ __INDEXATTR__;
                                        $this->addIdentifierQuotes( $desired_schema ));
                                $this->setSearchPath( $search_path );
                                $this->mCoreSchema = $desired_schema;
-                               wfDebug("Schema \"" . $desired_schema . "\" added to the search path\n");
+                               wfDebug( "Schema \"" . $desired_schema . "\" added to the search path\n" );
                        }
                } else {
                        $this->mCoreSchema = $this->getCurrentSchema();
-                       wfDebug("Schema \"" . $desired_schema . "\" not found, using current \"". $this->mCoreSchema ."\"\n");
+                       wfDebug( "Schema \"" . $desired_schema . "\" not found, using current \"" . $this->mCoreSchema . "\"\n" );
                }
                /* Commit SET otherwise it will be rollbacked on error or IGNORE SELECT */
                $this->commit( __METHOD__ );
@@ -1256,8 +1261,8 @@ SQL;
        }
 
        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",
+               $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() ),
                        $this->addQuotes( $table ),
                        $this->addQuotes( $constraint )
@@ -1384,23 +1389,9 @@ SQL;
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $gb = is_array( $options['GROUP BY'] )
-                               ? implode( ',', $options['GROUP BY'] )
-                               : $options['GROUP BY'];
-                       $preLimitTail .= " GROUP BY {$gb}";
-               }
-
-               if ( isset( $options['HAVING'] ) ) {
-                       $preLimitTail .= " HAVING {$options['HAVING']}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
 
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $ob = is_array( $options['ORDER BY'] )
-                               ? implode( ',', $options['ORDER BY'] )
-                               : $options['ORDER BY'];
-                       $preLimitTail .= " ORDER BY {$ob}";
-               }
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                //if ( isset( $options['LIMIT'] ) ) {
                //      $tailOpts .= $this->limitResult( '', $options['LIMIT'],
@@ -1448,4 +1439,65 @@ 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 $lockName String: name of lock to poll
+        * @param $method String: name of method calling us
+        * @return Boolean
+        * @since 1.20
+        */
+       public function lockIsFree( $lockName, $method ) {
+               $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 );
+               $row = $this->fetchObject( $result );
+               return ( $row->lockstatus === 't' );
+       }
+
+       /**
+        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+        * @param $lockName string
+        * @param $method string
+        * @param $timeout int
+        * @return bool
+        */
+       public function lock( $lockName, $method, $timeout = 5 ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               for ( $attempts=1; $attempts <= $timeout; ++$attempts ) {
+                       $result = $this->query(
+                               "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
+                       $row = $this->fetchObject( $result );
+                       if ( $row->lockstatus === 't' ) {
+                               return true;
+                       } else {
+                               sleep( 1 );
+                       }
+               }
+               wfDebug( __METHOD__." failed to acquire lock\n" );
+               return false;
+       }
+
+       /**
+        * 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 $lockName string
+        * @param $method string
+        * @return bool
+        */
+       public function unlock( $lockName, $method ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               $result = $this->query( "SELECT pg_advisory_unlock($key) as lockstatus", $method );
+               $row = $this->fetchObject( $result );
+               return ( $row->lockstatus === 't' );
+       }
+
+       /**
+        * @param string $lockName
+        * @return string Integer
+        */
+       private function bigintFromLockName( $lockName ) {
+               return wfBaseConvert( substr( sha1( $lockName ), 0, 15 ), 16, 10 );
+       }
 } // end DatabasePostgres class
index d30d984..74bd9b7 100644 (file)
@@ -127,6 +127,8 @@ class DatabaseSqlite extends DatabaseBase {
                # set error codes only, don't raise exceptions
                if ( $this->mOpened ) {
                        $this->mConn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
+                       # Enforce LIKE to be case sensitive, just like MySQL
+                       $this->query( 'PRAGMA case_sensitive_like = 1' );
                        return true;
                }
        }
@@ -161,7 +163,7 @@ class DatabaseSqlite extends DatabaseBase {
                        $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name = '$table'", __METHOD__ );
                        if ( $res ) {
                                $row = $res->fetchRow();
-                               self::$fulltextEnabled = stristr($row['sql'], 'fts' ) !== false;
+                               self::$fulltextEnabled = stristr( $row['sql'], 'fts' ) !== false;
                        }
                }
                return self::$fulltextEnabled;
@@ -250,7 +252,7 @@ class DatabaseSqlite extends DatabaseBase {
 
        /**
         * @param $res ResultWrapper
-        * @return
+        * @return object|bool
         */
        function fetchObject( $res ) {
                if ( $res instanceof ResultWrapper ) {
@@ -276,7 +278,7 @@ class DatabaseSqlite extends DatabaseBase {
 
        /**
         * @param $res ResultWrapper
-        * @return bool|mixed
+        * @return array|bool
         */
        function fetchRow( $res ) {
                if ( $res instanceof ResultWrapper ) {
@@ -848,7 +850,7 @@ class DatabaseSqlite extends DatabaseBase {
                $endArray = array();
 
                foreach( $result as $table ) {
-                       $vars = get_object_vars($table);
+                       $vars = get_object_vars( $table );
                        $table = array_pop( $vars );
 
                        if( !$prefix || strpos( $table, $prefix ) === 0 ) {
index c846788..5e11076 100644 (file)
@@ -138,7 +138,7 @@ class ResultWrapper implements Iterator {
 
        /**
         * Fetch the next row from the given result object, in associative array
-        * form.  Fields are retrieved with $row['fieldname'].
+        * form. Fields are retrieved with $row['fieldname'].
         *
         * @return Array
         * @throws DBUnexpectedError Thrown if the database returns an error
@@ -306,4 +306,3 @@ class LikeMatch {
  */
 interface DBMasterPos {
 }
-
index 1ea4b12..6a7a5bb 100644 (file)
@@ -272,4 +272,4 @@ interface IORMRow {
         */
        public function getTable();
 
-}
\ No newline at end of file
+}
index e82c54b..cc7f133 100644 (file)
@@ -240,7 +240,7 @@ class LBFactory_Simple extends LBFactory {
        function newExternalLB( $cluster, $wiki = false ) {
                global $wgExternalServers;
                if ( !isset( $wgExternalServers[$cluster] ) ) {
-                       throw new MWException( __METHOD__.": Unknown cluster \"$cluster\"" );
+                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
                }
                return new LoadBalancer( array(
                        'servers' => $wgExternalServers[$cluster]
@@ -345,7 +345,7 @@ class ChronologyProtector {
                if ( $lb->getServerCount() > 1 && !empty( $this->startupPos[$masterName] ) ) {
                        $info = $lb->parentInfo();
                        $pos = $this->startupPos[$masterName];
-                       wfDebug( __METHOD__.": LB " . $info['id'] . " waiting for master pos $pos\n" );
+                       wfDebug( __METHOD__ . ": LB " . $info['id'] . " waiting for master pos $pos\n" );
                        $lb->waitFor( $this->startupPos[$masterName] );
                }
        }
@@ -370,11 +370,11 @@ class ChronologyProtector {
                $db = $lb->getAnyOpenConnection( 0 );
                $info = $lb->parentInfo();
                if ( !$db || !$db->doneWrites() ) {
-                       wfDebug( __METHOD__.": LB {$info['id']}, no writes done\n" );
+                       wfDebug( __METHOD__ . ": LB {$info['id']}, no writes done\n" );
                        return;
                }
                $pos = $db->getMasterPos();
-               wfDebug( __METHOD__.": LB {$info['id']} has master pos $pos\n" );
+               wfDebug( __METHOD__ . ": LB {$info['id']} has master pos $pos\n" );
                $this->shutdownPos[$masterName] = $pos;
        }
 
@@ -384,7 +384,7 @@ class ChronologyProtector {
         */
        function shutdown() {
                if ( session_id() != '' && count( $this->shutdownPos ) ) {
-                       wfDebug( __METHOD__.": saving master pos for " .
+                       wfDebug( __METHOD__ . ": saving master pos for " .
                                count( $this->shutdownPos ) . " master(s)\n" );
                        $_SESSION[__CLASS__] = $this->shutdownPos;
                }
index 9b468a7..88b7500 100644 (file)
@@ -83,7 +83,7 @@ class LBFactory_Multi extends LBFactory {
 
                foreach ( $required as $key ) {
                        if ( !isset( $conf[$key] ) ) {
-                               throw new MWException( __CLASS__.": $key is required in configuration" );
+                               throw new MWException( __CLASS__ . ": $key is required in configuration" );
                        }
                        $this->$key = $conf[$key];
                }
@@ -161,7 +161,7 @@ class LBFactory_Multi extends LBFactory {
         */
        function newExternalLB( $cluster, $wiki = false ) {
                if ( !isset( $this->externalLoads[$cluster] ) ) {
-                       throw new MWException( __METHOD__.": Unknown cluster \"$cluster\"" );
+                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
                }
                $template = $this->serverTemplate;
                if ( isset( $this->externalTemplateOverrides ) ) {
index 2858cd9..13fa466 100644 (file)
@@ -45,7 +45,7 @@ class LoadBalancer {
         */
        function __construct( $params ) {
                if ( !isset( $params['servers'] ) ) {
-                       throw new MWException( __CLASS__.': missing servers parameter' );
+                       throw new MWException( __CLASS__ . ': missing servers parameter' );
                }
                $this->mServers = $params['servers'];
 
@@ -205,11 +205,11 @@ class LoadBalancer {
                global $wgReadOnly, $wgDBClusterTimeout, $wgDBAvgStatusPoll, $wgDBtype;
 
                # @todo FIXME: For now, only go through all this for mysql databases
-               if ($wgDBtype != 'mysql') {
+               if ( $wgDBtype != 'mysql' ) {
                        return $this->getWriterIndex();
                }
 
-               if ( count( $this->mServers ) == 1 )  {
+               if ( count( $this->mServers ) == 1 ) {
                        # Skip the load balancing if there's only one server
                        return 0;
                } elseif ( $group === false and $this->mReadIndex >= 0 ) {
@@ -230,7 +230,7 @@ class LoadBalancer {
                                $nonErrorLoads = $this->mGroupLoads[$group];
                        } else {
                                # No loads for this group, return false and the caller can use some other group
-                               wfDebug( __METHOD__.": no loads for group $group\n" );
+                               wfDebug( __METHOD__ . ": no loads for group $group\n" );
                                wfProfileOut( __METHOD__ );
                                return false;
                        }
@@ -258,7 +258,7 @@ class LoadBalancer {
                                        $i = $this->pickRandom( $currentLoads );
                                } else {
                                        $i = $this->getRandomNonLagged( $currentLoads, $wiki );
-                                       if ( $i === false && count( $currentLoads ) != 0 )  {
+                                       if ( $i === false && count( $currentLoads ) != 0 ) {
                                                # All slaves lagged. Switch to read-only mode
                                                wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode\n" );
                                                $wgReadOnly = 'The database has been automatically locked ' .
@@ -272,16 +272,16 @@ class LoadBalancer {
                                        # pickRandom() returned false
                                        # This is permanent and means the configuration or the load monitor
                                        # wants us to return false.
-                                       wfDebugLog( 'connect', __METHOD__.": pickRandom() returned false\n" );
+                                       wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false\n" );
                                        wfProfileOut( __METHOD__ );
                                        return false;
                                }
 
-                               wfDebugLog( 'connect', __METHOD__.": Using reader #$i: {$this->mServers[$i]['host']}...\n" );
+                               wfDebugLog( 'connect', __METHOD__ . ": Using reader #$i: {$this->mServers[$i]['host']}...\n" );
                                $conn = $this->openConnection( $i, $wiki );
 
                                if ( !$conn ) {
-                                       wfDebugLog( 'connect', __METHOD__.": Failed connecting to $i/$wiki\n" );
+                                       wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki\n" );
                                        unset( $nonErrorLoads[$i] );
                                        unset( $currentLoads[$i] );
                                        continue;
@@ -320,7 +320,7 @@ class LoadBalancer {
 
                        # Some servers must have been overloaded
                        if ( $overloadedServers == 0 ) {
-                               throw new MWException( __METHOD__.": unexpectedly found no overloaded servers" );
+                               throw new MWException( __METHOD__ . ": unexpectedly found no overloaded servers" );
                        }
                        # Back off for a while
                        # Scale the sleep time by the number of connected threads, to produce a
@@ -358,7 +358,7 @@ class LoadBalancer {
         */
        function sleep( $t ) {
                wfProfileIn( __METHOD__ );
-               wfDebug( __METHOD__.": waiting $t us\n" );
+               wfDebug( __METHOD__ . ": waiting $t us\n" );
                usleep( $t );
                wfProfileOut( __METHOD__ );
                return $t;
@@ -392,7 +392,7 @@ class LoadBalancer {
                wfProfileIn( __METHOD__ );
                $this->mWaitForPos = $pos;
                for ( $i = 1; $i < count( $this->mServers ); $i++ ) {
-                       $this->doWait( $i , true );
+                       $this->doWait( $i, true );
                }
                wfProfileOut( __METHOD__ );
        }
@@ -435,15 +435,15 @@ class LoadBalancer {
                        }
                }
 
-               wfDebug( __METHOD__.": Waiting for slave #$index to catch up...\n" );
+               wfDebug( __METHOD__ . ": Waiting for slave #$index to catch up...\n" );
                $result = $conn->masterPosWait( $this->mWaitForPos, $this->mWaitTimeout );
 
                if ( $result == -1 || is_null( $result ) ) {
                        # Timed out waiting for slave, use master instead
-                       wfDebug( __METHOD__.": Timed out waiting for slave #$index pos {$this->mWaitForPos}\n" );
+                       wfDebug( __METHOD__ . ": Timed out waiting for slave #$index pos {$this->mWaitForPos}\n" );
                        return false;
                } else {
-                       wfDebug( __METHOD__.": Done\n" );
+                       wfDebug( __METHOD__ . ": Done\n" );
                        return true;
                }
        }
@@ -479,7 +479,7 @@ class LoadBalancer {
                        $groupIndex = $this->getReaderIndex( $groups, $wiki );
                        if ( $groupIndex !== false ) {
                                $serverName = $this->getServerName( $groupIndex );
-                               wfDebug( __METHOD__.": using server $serverName for group $groups\n" );
+                               wfDebug( __METHOD__ . ": using server $serverName for group $groups\n" );
                                $i = $groupIndex;
                        }
                } else {
@@ -487,7 +487,7 @@ class LoadBalancer {
                                $groupIndex = $this->getReaderIndex( $group, $wiki );
                                if ( $groupIndex !== false ) {
                                        $serverName = $this->getServerName( $groupIndex );
-                                       wfDebug( __METHOD__.": using server $serverName for group $group\n" );
+                                       wfDebug( __METHOD__ . ": using server $serverName for group $group\n" );
                                        $i = $groupIndex;
                                        break;
                                }
@@ -525,8 +525,8 @@ class LoadBalancer {
         * @throws MWException
         */
        public function reuseConnection( $conn ) {
-               $serverIndex = $conn->getLBInfo('serverIndex');
-               $refCount = $conn->getLBInfo('foreignPoolRefCount');
+               $serverIndex = $conn->getLBInfo( 'serverIndex' );
+               $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
                $dbName = $conn->getDBname();
                $prefix = $conn->tablePrefix();
                if ( strval( $prefix ) !== '' ) {
@@ -535,7 +535,7 @@ class LoadBalancer {
                        $wiki = $dbName;
                }
                if ( $serverIndex === null || $refCount === null ) {
-                       wfDebug( __METHOD__.": this connection was not opened as a foreign connection\n" );
+                       wfDebug( __METHOD__ . ": this connection was not opened as a foreign connection\n" );
                        /**
                         * This can happen in code like:
                         *   foreach ( $dbs as $db ) {
@@ -549,15 +549,15 @@ class LoadBalancer {
                        return;
                }
                if ( $this->mConns['foreignUsed'][$serverIndex][$wiki] !== $conn ) {
-                       throw new MWException( __METHOD__.": connection not found, has the connection been freed already?" );
+                       throw new MWException( __METHOD__ . ": connection not found, has the connection been freed already?" );
                }
                $conn->setLBInfo( 'foreignPoolRefCount', --$refCount );
                if ( $refCount <= 0 ) {
                        $this->mConns['foreignFree'][$serverIndex][$wiki] = $conn;
                        unset( $this->mConns['foreignUsed'][$serverIndex][$wiki] );
-                       wfDebug( __METHOD__.": freed connection $serverIndex/$wiki\n" );
+                       wfDebug( __METHOD__ . ": freed connection $serverIndex/$wiki\n" );
                } else {
-                       wfDebug( __METHOD__.": reference count for $serverIndex/$wiki reduced to $refCount\n" );
+                       wfDebug( __METHOD__ . ": reference count for $serverIndex/$wiki reduced to $refCount\n" );
                }
        }
 
@@ -620,18 +620,18 @@ class LoadBalancer {
         * @return DatabaseBase
         */
        function openForeignConnection( $i, $wiki ) {
-               wfProfileIn(__METHOD__);
+               wfProfileIn( __METHOD__ );
                list( $dbName, $prefix ) = wfSplitWikiID( $wiki );
                if ( isset( $this->mConns['foreignUsed'][$i][$wiki] ) ) {
                        // Reuse an already-used connection
                        $conn = $this->mConns['foreignUsed'][$i][$wiki];
-                       wfDebug( __METHOD__.": reusing connection $i/$wiki\n" );
+                       wfDebug( __METHOD__ . ": reusing connection $i/$wiki\n" );
                } elseif ( isset( $this->mConns['foreignFree'][$i][$wiki] ) ) {
                        // Reuse a free connection for the same wiki
                        $conn = $this->mConns['foreignFree'][$i][$wiki];
                        unset( $this->mConns['foreignFree'][$i][$wiki] );
                        $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                       wfDebug( __METHOD__.": reusing free connection $i/$wiki\n" );
+                       wfDebug( __METHOD__ . ": reusing free connection $i/$wiki\n" );
                } elseif ( !empty( $this->mConns['foreignFree'][$i] ) ) {
                        // Reuse a connection from another wiki
                        $conn = reset( $this->mConns['foreignFree'][$i] );
@@ -646,7 +646,7 @@ class LoadBalancer {
                                $conn->tablePrefix( $prefix );
                                unset( $this->mConns['foreignFree'][$i][$oldWiki] );
                                $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                               wfDebug( __METHOD__.": reusing free connection from $oldWiki for $wiki\n" );
+                               wfDebug( __METHOD__ . ": reusing free connection from $oldWiki for $wiki\n" );
                        }
                } else {
                        // Open a new connection
@@ -655,13 +655,13 @@ class LoadBalancer {
                        $server['foreignPoolRefCount'] = 0;
                        $conn = $this->reallyOpenConnection( $server, $dbName );
                        if ( !$conn->isOpen() ) {
-                               wfDebug( __METHOD__.": error opening connection for $i/$wiki\n" );
+                               wfDebug( __METHOD__ . ": error opening connection for $i/$wiki\n" );
                                $this->mErrorConnection = $conn;
                                $conn = false;
                        } else {
                                $conn->tablePrefix( $prefix );
                                $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                               wfDebug( __METHOD__.": opened new connection for $i/$wiki\n" );
+                               wfDebug( __METHOD__ . ": opened new connection for $i/$wiki\n" );
                        }
                }
 
@@ -670,7 +670,7 @@ class LoadBalancer {
                        $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
                        $conn->setLBInfo( 'foreignPoolRefCount', $refCount + 1 );
                }
-               wfProfileOut(__METHOD__);
+               wfProfileOut( __METHOD__ );
                return $conn;
        }
 
@@ -732,6 +732,7 @@ class LoadBalancer {
 
        /**
         * @param $conn
+        * @return bool
         * @throws DBConnectionError
         */
        function reportConnectionError( &$conn ) {
index 146ac61..cb3376f 100644 (file)
@@ -159,7 +159,7 @@ class LoadMonitor_MySQL implements LoadMonitor {
 
                $times = array();
                foreach ( $serverIndexes as $i ) {
-                       if ($i == 0) { # Master
+                       if ( $i == 0 ) { # Master
                                $times[$i] = 0;
                        } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) {
                                $times[$i] = $conn->getLag();
@@ -173,7 +173,7 @@ class LoadMonitor_MySQL implements LoadMonitor {
                $wgMemc->set( $memcKey, $times, $expiry );
 
                # But don't give the timestamp to the caller
-               unset($times['timestamp']);
+               unset( $times['timestamp'] );
                $lagTimes = $times;
 
                wfProfileOut( __METHOD__ );
@@ -189,7 +189,7 @@ class LoadMonitor_MySQL implements LoadMonitor {
                if ( !$threshold ) {
                        return 0;
                }
-               $status = $conn->getMysqlStatus("Thread%");
+               $status = $conn->getMysqlStatus( "Thread%" );
                if ( $status['Threads_running'] > $threshold ) {
                        $server = $conn->getProperty( 'mServer' );
                        wfLogDBError( "LB backoff from $server - Threads_running = {$status['Threads_running']}\n" );
@@ -199,4 +199,3 @@ class LoadMonitor_MySQL implements LoadMonitor {
                }
        }
 }
-
index 7542797..077eab0 100644 (file)
@@ -28,4 +28,4 @@
  */
 interface ORMIterator extends Iterator {
 
-}
\ No newline at end of file
+}
index 8abfdb6..06f88c1 100644 (file)
@@ -901,4 +901,4 @@ class ORMTable extends DBAccessBase implements IORMTable {
                return array_key_exists( $name, $this->getFields() );
        }
 
-}
\ No newline at end of file
+}
index 6a6f930..6ef5fcb 100644 (file)
@@ -43,14 +43,14 @@ class _DiffOp {
         * @return int
         */
        function norig() {
-               return $this->orig ? sizeof( $this->orig ) : 0;
+               return $this->orig ? count( $this->orig ) : 0;
        }
 
        /**
         * @return int
         */
        function nclosing() {
-               return $this->closing ? sizeof( $this->closing ) : 0;
+               return $this->closing ? count( $this->closing ) : 0;
        }
 }
 
@@ -167,7 +167,7 @@ class _DiffOp_Change extends _DiffOp {
  */
 class _DiffEngine {
 
-       const MAX_XREF_LENGTH =  10000;
+       const MAX_XREF_LENGTH = 10000;
 
        protected $xchanged, $ychanged;
 
@@ -194,8 +194,8 @@ class _DiffEngine {
                $this->_shift_boundaries( $to_lines, $this->ychanged, $this->xchanged );
 
                // Compute the edit operations.
-               $n_from = sizeof( $from_lines );
-               $n_to = sizeof( $to_lines );
+               $n_from = count( $from_lines );
+               $n_to = count( $to_lines );
 
                $edits = array();
                $xi = $yi = 0;
@@ -221,7 +221,7 @@ class _DiffEngine {
                        }
 
                        $add = array();
-                       while ( $yi < $n_to && $this->ychanged[$yi] )  {
+                       while ( $yi < $n_to && $this->ychanged[$yi] ) {
                                $add[] = $to_lines[$yi++];
                        }
 
@@ -254,8 +254,8 @@ class _DiffEngine {
                        unset( $wikidiff3 );
                } else {
                        // old diff
-                       $n_from = sizeof( $from_lines );
-                       $n_to = sizeof( $to_lines );
+                       $n_from = count( $from_lines );
+                       $n_to = count( $to_lines );
                        $this->xchanged = $this->ychanged = array();
                        $this->xv = $this->yv = array();
                        $this->xind = $this->yind = array();
@@ -303,7 +303,7 @@ class _DiffEngine {
                        }
 
                        // Find the LCS.
-                       $this->_compareseq( 0, sizeof( $this->xv ), 0, sizeof( $this->yv ) );
+                       $this->_compareseq( 0, count( $this->xv ), 0, count( $this->yv ) );
                }
                wfProfileOut( __METHOD__ );
        }
@@ -491,8 +491,7 @@ class _DiffEngine {
                        // $nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
                        // $nchunks = max(2,min(8,(int)$nchunks));
                        $nchunks = min( 7, $xlim - $xoff, $ylim - $yoff ) + 1;
-                       list ( $lcs, $seps )
-                       = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
+                       list ( $lcs, $seps ) = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
                }
 
                if ( $lcs == 0 ) {
@@ -533,9 +532,9 @@ class _DiffEngine {
                $i = 0;
                $j = 0;
 
-               assert( 'sizeof($lines) == sizeof($changed)' );
-               $len = sizeof( $lines );
-               $other_len = sizeof( $other_changed );
+               assert( 'count($lines) == count($changed)' );
+               $len = count( $lines );
+               $other_len = count( $other_changed );
 
                while ( 1 ) {
                        /*
@@ -713,7 +712,7 @@ class Diff {
                $lcs = 0;
                foreach ( $this->edits as $edit ) {
                        if ( $edit->type == 'copy' ) {
-                               $lcs += sizeof( $edit->orig );
+                               $lcs += count( $edit->orig );
                        }
                }
                return $lcs;
@@ -732,7 +731,7 @@ class Diff {
 
                foreach ( $this->edits as $edit ) {
                        if ( $edit->orig ) {
-                               array_splice( $lines, sizeof( $lines ), 0, $edit->orig );
+                               array_splice( $lines, count( $lines ), 0, $edit->orig );
                        }
                }
                return $lines;
@@ -751,7 +750,7 @@ class Diff {
 
                foreach ( $this->edits as $edit ) {
                        if ( $edit->closing ) {
-                               array_splice( $lines, sizeof( $lines ), 0, $edit->closing );
+                               array_splice( $lines, count( $lines ), 0, $edit->closing );
                        }
                }
                return $lines;
@@ -829,23 +828,23 @@ class MappedDiff extends Diff {
                $mapped_from_lines, $mapped_to_lines ) {
                wfProfileIn( __METHOD__ );
 
-               assert( 'sizeof( $from_lines ) == sizeof( $mapped_from_lines )' );
-               assert( 'sizeof( $to_lines ) == sizeof( $mapped_to_lines )' );
+               assert( 'count( $from_lines ) == count( $mapped_from_lines )' );
+               assert( 'count( $to_lines ) == count( $mapped_to_lines )' );
 
                parent::__construct( $mapped_from_lines, $mapped_to_lines );
 
                $xi = $yi = 0;
-               for ( $i = 0; $i < sizeof( $this->edits ); $i++ ) {
+               for ( $i = 0; $i < count( $this->edits ); $i++ ) {
                        $orig = &$this->edits[$i]->orig;
                        if ( is_array( $orig ) ) {
-                               $orig = array_slice( $from_lines, $xi, sizeof( $orig ) );
-                               $xi += sizeof( $orig );
+                               $orig = array_slice( $from_lines, $xi, count( $orig ) );
+                               $xi += count( $orig );
                        }
 
                        $closing = &$this->edits[$i]->closing;
                        if ( is_array( $closing ) ) {
-                               $closing = array_slice( $to_lines, $yi, sizeof( $closing ) );
-                               $yi += sizeof( $closing );
+                               $closing = array_slice( $to_lines, $yi, count( $closing ) );
+                               $yi += count( $closing );
                        }
                }
                wfProfileOut( __METHOD__ );
@@ -900,7 +899,7 @@ class DiffFormatter {
                foreach ( $diff->edits as $edit ) {
                        if ( $edit->type == 'copy' ) {
                                if ( is_array( $block ) ) {
-                                       if ( sizeof( $edit->orig ) <= $nlead + $ntrail ) {
+                                       if ( count( $edit->orig ) <= $nlead + $ntrail ) {
                                                $block[] = $edit;
                                        } else {
                                                if ( $ntrail ) {
@@ -916,9 +915,9 @@ class DiffFormatter {
                                $context = $edit->orig;
                        } else {
                                if ( !is_array( $block ) ) {
-                                       $context = array_slice( $context, sizeof( $context ) - $nlead );
-                                       $x0 = $xi - sizeof( $context );
-                                       $y0 = $yi - sizeof( $context );
+                                       $context = array_slice( $context, count( $context ) - $nlead );
+                                       $x0 = $xi - count( $context );
+                                       $y0 = $yi - count( $context );
                                        $block = array();
                                        if ( $context ) {
                                                $block[] = new _DiffOp_Copy( $context );
@@ -928,10 +927,10 @@ class DiffFormatter {
                        }
 
                        if ( $edit->orig ) {
-                               $xi += sizeof( $edit->orig );
+                               $xi += count( $edit->orig );
                        }
                        if ( $edit->closing ) {
-                               $yi += sizeof( $edit->closing );
+                               $yi += count( $edit->closing );
                        }
                }
 
@@ -1365,7 +1364,7 @@ class TableDiffFormatter extends DiffFormatter {
         */
        function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
                $r = '<tr><td colspan="2" class="diff-lineno"><!--LINE ' . $xbeg . "--></td>\n" .
-                 '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
+                       '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
                return $r;
        }
 
index 97553e6..c8f1d7f 100644 (file)
@@ -152,7 +152,7 @@ class DifferenceEngine extends ContextSource {
        function deletedLink( $id ) {
                if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $row = $dbr->selectRow('archive', '*',
+                       $row = $dbr->selectRow( 'archive', '*',
                                array( 'ar_rev_id' => $id ),
                                __METHOD__ );
                        if ( $row ) {
@@ -735,6 +735,7 @@ class DifferenceEngine extends ContextSource {
         * @param $old Content: old content
         * @param $new Content: new content
         *
+        * @return bool|string
         * @since 1.21
         * @throws MWException if $old or $new are not instances of TextContent.
         */
@@ -760,6 +761,7 @@ class DifferenceEngine extends ContextSource {
         *
         * @param $otext String: old text, must be already segmented
         * @param $ntext String: new text, must be already segmented
+        * @return bool|string
         * @deprecated since 1.21, use generateContentDiffBody() instead!
         */
        function generateDiffBody( $otext, $ntext ) {
index 6672744..4ce9f19 100644 (file)
@@ -64,7 +64,7 @@ class WikiDiff3 {
 
        public function diff( /*array*/ $from, /*array*/ $to ) {
                // remember initial lengths
-               $m = sizeof( $from );
+               $m = count( $from );
                $n = count( $to );
 
                $this->heuristicUsed = false;
index 1b7c29d..5dd49d7 100644 (file)
@@ -1,6 +1,10 @@
 <?php
 /**
- * Data storage in external repositories.
+ * @defgroup ExternalStorage ExternalStorage
+ */
+
+/**
+ * Interface for data storage in external repositories.
  *
  * 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
  */
 
 /**
- * @defgroup ExternalStorage ExternalStorage
- */
-
-/**
- * Constructor class for data kept in external repositories
+ * Constructor class for key/value blob data kept in external repositories.
+ *
+ * Objects in external stores are defined by a special URL. The URL is of
+ * the form "<store protocal>://<location>/<object name>". The protocal is used
+ * to determine what ExternalStoreMedium class is used. The location identifies
+ * particular storage instances or database clusters for store class to use.
+ *
+ * When an object is inserted into a store, the calling code uses a partial URL of
+ * the form "<store protocal>://<location>" and receives the full object URL on success.
+ * This is useful since object names can be sequential IDs, UUIDs, or hashes.
+ * Callers are not responsible for unique name generation.
  *
  * External repositories might be populated by maintenance/async
  * scripts, thus partial moving of data may be possible, as well
- * as possibility to have any storage format (i.e. for archives)
+ * as the possibility to have any storage format (i.e. for archives).
  *
  * @ingroup ExternalStorage
  */
 class ExternalStore {
-       var $mParams;
-
        /**
-        * @param $params array
+        * Get an external store object of the given type, with the given parameters
+        *
+        * @param $proto string Type of external storage, should be a value in $wgExternalStores
+        * @param $params array Associative array of ExternalStoreMedium parameters
+        * @return ExternalStoreMedium|bool The store class or false on error
         */
-       function __construct( $params = array() ) {
-               $this->mParams = $params;
+       public static function getStoreObject( $proto, array $params = array() ) {
+               global $wgExternalStores;
+
+               if ( !$wgExternalStores || !in_array( $proto, $wgExternalStores ) ) {
+                       return false; // protocol not enabled
+               }
+
+               $class = 'ExternalStore' . ucfirst( $proto );
+               // Any custom modules should be added to $wgAutoLoadClasses for on-demand loading
+               return MWInit::classExists( $class ) ? new $class( $params ) : false;
        }
 
        /**
         * Fetch data from given URL
         *
-        * @param $url String: The URL of the text to get
-        * @param $params Array: associative array of parameters for the ExternalStore object.
+        * @param $url string The URL of the text to get
+        * @param $params array Associative array of ExternalStoreMedium parameters
         * @return string|bool The text stored or false on error
+        * @throws MWException
         */
-       static function fetchFromURL( $url, $params = array() ) {
-               global $wgExternalStores;
-
-               if( !$wgExternalStores ) {
-                       return false;
-               }
-
+       public static function fetchFromURL( $url, array $params = array() ) {
                $parts = explode( '://', $url, 2 );
-
                if ( count( $parts ) != 2 ) {
-                       return false;
+                       return false; // invalid URL
                }
 
                list( $proto, $path ) = $parts;
-
-               if ( $path == '' ) { // Bad URL
+               if ( $path == '' ) { // bad URL
                        return false;
                }
 
@@ -78,48 +91,32 @@ class ExternalStore {
        }
 
        /**
-        * Get an external store object of the given type, with the given parameters
+        * Store a data item to an external store, identified by a partial URL
+        * The protocol part is used to identify the class, the rest is passed to the
+        * class itself as a parameter.
         *
-        * @param $proto String: type of external storage, should be a value in $wgExternalStores
-        * @param $params Array: associative array of parameters for the ExternalStore object.
-        * @return ExternalStore|bool ExternalStore class or false on error
+        * @param $url String A partial external store URL ("<store type>://<location>")
+        * @param $data string
+        * @param $params array Associative array of ExternalStoreMedium parameters
+        * @return string|bool The URL of the stored data item, or false on error
+        * @throws MWException
         */
-       static function getStoreObject( $proto, $params = array() ) {
-               global $wgExternalStores;
-               if( !$wgExternalStores ) {
-                       return false;
-               }
-
-               /* Protocol not enabled */
-               if( !in_array( $proto, $wgExternalStores ) ) {
-                       return false;
+       public static function insert( $url, $data, array $params = array() ) {
+               $parts = explode( '://', $url, 2 );
+               if ( count( $parts ) != 2 ) {
+                       return false; // invalid URL
                }
 
-               $class = 'ExternalStore' . ucfirst( $proto );
-               /* Any custom modules should be added to $wgAutoLoadClasses for on-demand loading */
-               if( !MWInit::classExists( $class ) ) {
+               list( $proto, $path ) = $parts;
+               if ( $path == '' ) { // bad URL
                        return false;
                }
 
-               return new $class($params);
-       }
-
-       /**
-        * Store a data item to an external store, identified by a partial URL
-        * The protocol part is used to identify the class, the rest is passed to the
-        * class itself as a parameter.
-        * @param $url
-        * @param $data
-        * @param $params array
-        * @return string|bool The URL of the stored data item, or false on error
-        */
-       static function insert( $url, $data, $params = array() ) {
-               list( $proto, $params ) = explode( '://', $url, 2 );
                $store = self::getStoreObject( $proto, $params );
                if ( $store === false ) {
                        return false;
                } else {
-                       return $store->store( $params, $data );
+                       return $store->store( $path, $data );
                }
        }
 
@@ -128,53 +125,52 @@ class ExternalStore {
         * This function does not need a url param, it builds it by
         * itself. It also fails-over to the next possible clusters.
         *
-        * @param $data String
-        * @param $storageParams Array: associative array of parameters for the ExternalStore object.
-        * @throws MWException|DBConnectionError|DBQueryError
+        * @param $data string
+        * @param $params array Associative array of ExternalStoreMedium parameters
         * @return string|bool The URL of the stored data item, or false on error
+        * @throws MWException
         */
-       public static function insertToDefault( $data, $storageParams = array() ) {
+       public static function insertToDefault( $data, array $params = array() ) {
                global $wgDefaultExternalStore;
-               $tryStores = (array)$wgDefaultExternalStore;
+
                $error = false;
+               $tryStores = (array)$wgDefaultExternalStore;
                while ( count( $tryStores ) > 0 ) {
-                       $index = mt_rand(0, count( $tryStores ) - 1);
+                       $index = mt_rand( 0, count( $tryStores ) - 1 );
                        $storeUrl = $tryStores[$index];
-                       wfDebug( __METHOD__.": trying $storeUrl\n" );
-                       list( $proto, $params ) = explode( '://', $storeUrl, 2 );
-                       $store = self::getStoreObject( $proto, $storageParams );
+                       wfDebug( __METHOD__ . ": trying $storeUrl\n" );
+                       list( $proto, $path ) = explode( '://', $storeUrl, 2 );
+                       $store = self::getStoreObject( $proto, $params );
                        if ( $store === false ) {
                                throw new MWException( "Invalid external storage protocol - $storeUrl" );
                        }
                        try {
-                               $url = $store->store( $params, $data ); // Try to save the object
-                       } catch ( DBConnectionError $error ) {
-                               $url = false;
-                       } catch( DBQueryError $error ) {
+                               $url = $store->store( $path, $data ); // Try to save the object
+                       } catch ( MWException $error ) {
                                $url = false;
                        }
-                       if ( $url ) {
+                       if ( strlen( $url ) ) {
                                return $url; // Done!
                        } else {
                                unset( $tryStores[$index] ); // Don't try this one again!
                                $tryStores = array_values( $tryStores ); // Must have consecutive keys
-                               wfDebugLog( 'ExternalStorage', "Unable to store text to external storage $storeUrl" );
+                               wfDebugLog( 'ExternalStorage',
+                                       "Unable to store text to external storage $storeUrl" );
                        }
                }
                // All stores failed
                if ( $error ) {
-                       // Rethrow the last connection error
-                       throw $error;
+                       throw $error; // rethrow the last error
                } else {
                        throw new MWException( "Unable to store text to external storage" );
                }
        }
 
        /**
-        * @param $data
-        * @param $wiki
-        *
-        * @return string
+        * @param $data string
+        * @param $wiki string
+        * @return string|bool The URL of the stored data item, or false on error
+        * @throws MWException
         */
        public static function insertToForeignDefault( $data, $wiki ) {
                return self::insertToDefault( $data, array( 'wiki' => $wiki ) );
index 172e4f6..3857771 100644 (file)
  */
 
 /**
- * DB accessable external objects
+ * DB accessable external objects.
+ *
+ * In this system, each store "location" maps to a database "cluster".
+ * The clusters must be defined in the normal LBFactory configuration.
+ *
  * @ingroup ExternalStorage
  */
-class ExternalStoreDB {
+class ExternalStoreDB extends ExternalStoreMedium {
+       /**
+        * The URL returned is of the form of the form DB://cluster/id
+        * or DB://cluster/id/itemid for concatened storage.
+        *
+        * @see ExternalStoreMedium::fetchFromURL()
+        */
+       public function fetchFromURL( $url ) {
+               $path = explode( '/', $url );
+               $cluster = $path[2];
+               $id = $path[3];
+               if ( isset( $path[4] ) ) {
+                       $itemID = $path[4];
+               } else {
+                       $itemID = false;
+               }
+
+               $ret =& $this->fetchBlob( $cluster, $id, $itemID );
+
+               if ( $itemID !== false && $ret !== false ) {
+                       return $ret->getItem( $itemID );
+               }
+               return $ret;
+       }
 
        /**
-        * @param $params array
+        * @see ExternalStoreMedium::store()
         */
-       function __construct( $params = array() ) {
-               $this->mParams = $params;
+       public function store( $cluster, $data ) {
+               $dbw = $this->getMaster( $cluster );
+               $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
+               $dbw->insert( $this->getTable( $dbw ),
+                       array( 'blob_id' => $id, 'blob_text' => $data ),
+                       __METHOD__ );
+               $id = $dbw->insertId();
+               if ( !$id ) {
+                       throw new MWException( __METHOD__.': no insert ID' );
+               }
+               if ( $dbw->getFlag( DBO_TRX ) ) {
+                       $dbw->commit( __METHOD__ );
+               }
+               return "DB://$cluster/$id";
        }
 
        /**
@@ -40,7 +79,7 @@ class ExternalStoreDB {
         * @return LoadBalancer object
         */
        function &getLoadBalancer( $cluster ) {
-               $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
+               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
 
                return wfGetLBFactory()->getExternalLB( $cluster, $wiki );
        }
@@ -54,12 +93,12 @@ class ExternalStoreDB {
        function &getSlave( $cluster ) {
                global $wgDefaultExternalStore;
 
-               $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
+               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
                $lb =& $this->getLoadBalancer( $cluster );
 
                if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) {
                        wfDebug( "read only external store" );
-                       $lb->allowLagged(true);
+                       $lb->allowLagged( true );
                } else {
                        wfDebug( "writable external store" );
                }
@@ -74,7 +113,7 @@ class ExternalStoreDB {
         * @return DatabaseBase object
         */
        function &getMaster( $cluster ) {
-               $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
+               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
                $lb =& $this->getLoadBalancer( $cluster );
                return $lb->getConnection( DB_MASTER, array(), $wiki );
        }
@@ -93,29 +132,6 @@ class ExternalStoreDB {
                return $table;
        }
 
-       /**
-        * Fetch data from given URL
-        * @param $url String: an url of the form DB://cluster/id or DB://cluster/id/itemid for concatened storage.
-        * @return mixed
-        */
-       function fetchFromURL( $url ) {
-               $path = explode( '/', $url );
-               $cluster = $path[2];
-               $id = $path[3];
-               if ( isset( $path[4] ) ) {
-                       $itemID = $path[4];
-               } else {
-                       $itemID = false;
-               }
-
-               $ret =& $this->fetchBlob( $cluster, $id, $itemID );
-
-               if ( $itemID !== false && $ret !== false ) {
-                       return $ret->getItem( $itemID );
-               }
-               return $ret;
-       }
-
        /**
         * Fetch a blob item out of the database; a cache of the last-loaded
         * blob will be kept so that multiple loads out of a multi-item blob
@@ -162,28 +178,4 @@ class ExternalStoreDB {
                $externalBlobCache = array( $cacheID => &$ret );
                return $ret;
        }
-
-       /**
-        * Insert a data item into a given cluster
-        *
-        * @param $cluster String: the cluster name
-        * @param $data String: the data item
-        * @throws MWException
-        * @return string URL
-        */
-       function store( $cluster, $data ) {
-               $dbw = $this->getMaster( $cluster );
-               $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
-               $dbw->insert( $this->getTable( $dbw ),
-                       array( 'blob_id' => $id, 'blob_text' => $data ),
-                       __METHOD__ );
-               $id = $dbw->insertId();
-               if ( !$id ) {
-                       throw new MWException( __METHOD__.': no insert ID' );
-               }
-               if ( $dbw->getFlag( DBO_TRX ) ) {
-                       $dbw->commit( __METHOD__ );
-               }
-               return "DB://$cluster/$id";
-       }
 }
index 311e32b..345c17b 100644 (file)
  *
  * @ingroup ExternalStorage
  */
-class ExternalStoreHttp {
-
+class ExternalStoreHttp extends ExternalStoreMedium {
        /**
-        * Fetch data from given URL
-        *
-        * @param $url String: the URL
-        * @return String: the content at $url
+        * @see ExternalStoreMedium::fetchFromURL()
         */
-       function fetchFromURL( $url ) {
-               $ret = Http::get( $url );
-               return $ret;
+       public function fetchFromURL( $url ) {
+               return Http::get( $url );
        }
 
-       /* XXX: may require other methods, for store, delete,
-        * whatever, for initial ext storage
+       /**
+        * @see ExternalStoreMedium::store()
         */
+       public function store( $cluster, $data ) {
+               throw new MWException( "ExternalStoreHttp is read-only and does not support store()." );
+       }
 }
diff --git a/includes/externalstore/ExternalStoreMedium.php b/includes/externalstore/ExternalStoreMedium.php
new file mode 100644 (file)
index 0000000..34e43e2
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+/**
+ * External storage in some particular medium.
+ *
+ * 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 ExternalStorage
+ * @author Aaron Schulz
+ */
+
+/**
+ * Accessable external objects in a particular storage medium
+ *
+ * @ingroup ExternalStorage
+ * @since 1.21
+ */
+abstract class ExternalStoreMedium {
+       /** @var Array */
+       protected $params = array();
+
+       /**
+        * @param $params array Options
+        */
+       public function __construct( array $params = array() ) {
+               $this->params = $params;
+       }
+
+       /**
+        * Fetch data from given external store URL
+        *
+        * @param $url string An external store URL
+        * @return string|bool The text stored or false on error
+        * @throws MWException
+        */
+       abstract public function fetchFromURL( $url );
+
+       /**
+        * Insert a data item into a given location
+        *
+        * @param $location string: the location name
+        * @param $data string: the data item
+        * @return string|bool The URL of the stored data item, or false on error
+        * @throws MWException
+        */
+       abstract public function store( $location, $data );
+}
diff --git a/includes/externalstore/ExternalStoreMwstore.php b/includes/externalstore/ExternalStoreMwstore.php
new file mode 100644 (file)
index 0000000..0911cca
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+/**
+ * External storage in a file backend.
+ *
+ * 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
+ */
+
+/**
+ * File backend accessable external objects.
+ *
+ * In this system, each store "location" maps to the name of a file backend.
+ * The file backends must be defined in $wgFileBackends and must be global
+ * and fully qualified with a global "wikiId" prefix in the configuration.
+ *
+ * @ingroup ExternalStorage
+ * @since 1.21
+ */
+class ExternalStoreMwstore extends ExternalStoreMedium {
+       /**
+        * The URL returned is of the form of the form mwstore://backend/container/wiki/id
+        *
+        * @see ExternalStoreMedium::fetchFromURL()
+        */
+       public function fetchFromURL( $url ) {
+               $be = FileBackendGroup::singleton()->backendFromPath( $url );
+               if ( $be instanceof FileBackend ) {
+                       // We don't need "latest" since objects are immutable and
+                       // backends should at least have "read-after-create" consistency.
+                       return $be->getFileContents( array( 'src' => $url ) );
+               }
+               return false;
+       }
+
+       /**
+        * @see ExternalStoreMedium::store()
+        */
+       public function store( $backend, $data ) {
+               $be = FileBackendGroup::singleton()->get( $backend );
+               if ( $be instanceof FileBackend ) {
+                       // Get three random base 36 characters to act as shard directories
+                       $rand = wfBaseConvert( mt_rand( 0, 46655 ), 10, 36, 3 );
+                       // Make sure ID is roughly lexicographically increasing for performance
+                       $id = str_pad( UIDGenerator::newTimestampedUID128( 32 ), 26, '0', STR_PAD_LEFT );
+                       // Segregate items by wiki ID for the sake of bookkeeping
+                       $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : wfWikiID();
+
+                       $url = $be->getContainerStoragePath( 'data' ) . '/' .
+                               rawurlencode( $wiki ) . "/{$rand[0]}/{$rand[1]}/{$rand[2]}/{$id}";
+
+                       $be->prepare( array( 'dir' => dirname( $url ), 'noAccess' => 1, 'noListing' => 1 ) );
+                       if ( $be->create( array( 'dst' => $url, 'content' => $data ) )->isOK() ) {
+                               return $url;
+                       }
+               }
+               return false;
+       }
+}
index 5141ec5..acbc4a9 100644 (file)
@@ -104,7 +104,7 @@ class FSFile {
         */
        public function getProps( $ext = true ) {
                wfProfileIn( __METHOD__ );
-               wfDebug( __METHOD__.": Getting file info for $this->path\n" );
+               wfDebug( __METHOD__ . ": Getting file info for $this->path\n" );
 
                $info = self::placeholderProps();
                $info['fileExists'] = $this->exists();
@@ -140,9 +140,9 @@ class FSFile {
                        }
                        $info['sha1'] = $this->getSha1Base36();
 
-                       wfDebug(__METHOD__.": $this->path loaded, {$info['size']} bytes, {$info['mime']}.\n");
+                       wfDebug( __METHOD__ . ": $this->path loaded, {$info['size']} bytes, {$info['mime']}.\n" );
                } else {
-                       wfDebug(__METHOD__.": $this->path NOT FOUND!\n");
+                       wfDebug( __METHOD__ . ": $this->path NOT FOUND!\n" );
                }
 
                wfProfileOut( __METHOD__ );
index a4e6ef6..a1d46c1 100644 (file)
@@ -861,12 +861,15 @@ abstract class FSFileBackendList implements Iterator {
         * @param $params array
         */
        public function __construct( $dir, array $params ) {
-               $dir = realpath( $dir ); // normalize
-               $this->suffixStart = strlen( $dir ) + 1; // size of "path/to/dir/"
+               $path = realpath( $dir ); // normalize
+               if( $path === false ) {
+                       $path = $dir;
+               }
+               $this->suffixStart = strlen( $path ) + 1; // size of "path/to/dir/"
                $this->params = $params;
 
                try {
-                       $this->iter = $this->initIterator( $dir );
+                       $this->iter = $this->initIterator( $path );
                } catch ( UnexpectedValueException $e ) {
                        $this->iter = null; // bad permissions? deleted?
                }
@@ -958,8 +961,12 @@ abstract class FSFileBackendList implements Iterator {
         * @param $path string
         * @return string
         */
-       protected function getRelPath( $path ) {
-               return strtr( substr( realpath( $path ), $this->suffixStart ), '\\', '/' );
+       protected function getRelPath( $dir ) {
+               $path = realpath( $dir );
+               if( $path === false ) {
+                       $path = $dir;
+               }
+               return strtr( substr( $path, $this->suffixStart ), '\\', '/' );
        }
 }
 
index 65caf10..3ebfdb1 100644 (file)
  * Outside callers can assume that all backends will have these functions.
  *
  * All "storage paths" are of the format "mwstore://<backend>/<container>/<path>".
- * The "<path>" portion is a relative path that uses UNIX file system (FS)
- * notation, though any particular backend may not actually be using a local
- * filesystem. Therefore, the relative paths are only virtual.
+ * The "backend" portion is unique name for MediaWiki to refer to a backend, while
+ * the "container" portion is a top-level directory of the backend. The "path" portion
+ * is a relative path that uses UNIX file system (FS) notation, though any particular
+ * backend may not actually be using a local filesystem. Therefore, the relative paths
+ * are only virtual.
  *
  * Backend contents are stored under wiki-specific container names by default.
- * For legacy reasons, this has no effect for the FS backend class, and per-wiki
- * segregation must be done by setting the container paths appropriately.
+ * Global (qualified) backends are achieved by configuring the "wiki ID" to a constant.
+ * For legacy reasons, the FSFileBackend class allows manually setting the paths of
+ * containers to ones that do not respect the "wiki ID".
  *
+ * In key/value stores, the container is the only hierarchy (the rest is emulated).
  * FS-based backends are somewhat more restrictive due to the existence of real
  * directory files; a regular file cannot have the same name as a directory. Other
  * backends with virtual directories may not have this limitation. Callers should
@@ -75,9 +79,13 @@ abstract class FileBackend {
         * $config includes:
         *   - name        : The unique name of this backend.
         *                   This should consist of alphanumberic, '-', and '_' characters.
-        *                   This name should not be changed after use.
-        *   - wikiId      : Prefix to container names that is unique to this wiki.
+        *                   This name should not be changed after use (e.g. with journaling).
+        *                   Note that the name is *not* used in actual container names.
+        *   - wikiId      : Prefix to container names that is unique to this backend.
+        *                   If not provided, this defaults to the current wiki ID.
         *                   It should only consist of alphanumberic, '-', and '_' characters.
+        *                   This ID is what avoids collisions if multiple logical backends
+        *                   use the same storage system, so this should be set carefully.
         *   - lockManager : Registered name of a file lock manager to use.
         *   - fileJournal : File journal configuration; see FileJournal::factory().
         *                   Journals simply log changes to files stored in the backend.
@@ -100,7 +108,7 @@ abstract class FileBackend {
                        : wfWikiID(); // e.g. "my_wiki-en_"
                $this->lockManager = ( $config['lockManager'] instanceof LockManager )
                        ? $config['lockManager']
-                       : LockManagerGroup::singleton()->get( $config['lockManager'] );
+                       : LockManagerGroup::singleton( $this->wikiId )->get( $config['lockManager'] );
                $this->fileJournal = isset( $config['fileJournal'] )
                        ? ( ( $config['fileJournal'] instanceof FileJournal )
                                ? $config['fileJournal']
@@ -275,7 +283,7 @@ abstract class FileBackend {
         * $opts is an associative of boolean flags, including:
         *   - force               : Operation precondition errors no longer trigger an abort.
         *                           Any remaining operations are still attempted. Unexpected
-        *                           failures may still cause remaning operations to be aborted.
+        *                           failures may still cause remaining operations to be aborted.
         *   - nonLocking          : No locks are acquired for the operations.
         *                           This can increase performance for non-critical writes.
         *                           This has no effect unless the 'force' flag is set.
@@ -313,6 +321,7 @@ abstract class FileBackend {
                if ( empty( $opts['force'] ) ) { // sanity
                        unset( $opts['nonLocking'] );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doOperationsInternal( $ops, $opts );
        }
 
@@ -543,6 +552,7 @@ abstract class FileBackend {
                foreach ( $ops as &$op ) {
                        $op['overwrite'] = true; // avoids RTTs in key/value stores
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doQuickOperationsInternal( $ops );
        }
 
@@ -686,6 +696,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doPrepare( $params );
        }
 
@@ -713,6 +724,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doSecure( $params );
        }
 
@@ -741,6 +753,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doPublish( $params );
        }
 
@@ -765,6 +778,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doClean( $params );
        }
 
@@ -773,6 +787,21 @@ abstract class FileBackend {
         */
        abstract protected function doClean( array $params );
 
+       /**
+        * Enter file operation scope.
+        * This just makes PHP ignore user aborts/disconnects until the return
+        * value leaves scope. This returns null and does nothing in CLI mode.
+        *
+        * @return ScopedCallback|null
+        */
+       final protected function getScopedPHPBehaviorForOps() {
+               if ( php_sapi_name() != 'cli' ) { // http://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;
+       }
+
        /**
         * Check if a file exists at a storage path in the backend.
         * This returns false if only a directory exists at the path.
index 8bbc96d..0bf5279 100644 (file)
@@ -87,6 +87,9 @@ class FileBackendGroup {
                        $thumbDir = isset( $info['thumbDir'] )
                                ? $info['thumbDir']
                                : "{$directory}/thumb";
+                       $transcodedDir = isset( $info['transcodedDir'] )
+                               ? $info['transcodedDir']
+                               : "{$directory}/transcoded";
                        $fileMode = isset( $info['fileMode'] )
                                ? $info['fileMode']
                                : 0644;
@@ -98,6 +101,7 @@ class FileBackendGroup {
                                'containerPaths' => array(
                                        "{$repoName}-public"  => "{$directory}",
                                        "{$repoName}-thumb"   => $thumbDir,
+                                       "{$repoName}-transcoded"   => $transcodedDir,
                                        "{$repoName}-deleted" => $deletedDir,
                                        "{$repoName}-temp"    => "{$directory}/temp"
                                ),
@@ -122,7 +126,9 @@ class FileBackendGroup {
                                throw new MWException( "Cannot register a backend with no name." );
                        }
                        $name = $config['name'];
-                       if ( !isset( $config['class'] ) ) {
+                       if ( isset( $this->backends[$name] ) ) {
+                               throw new MWException( "Backend with name `{$name}` already registered." );
+                       } elseif ( !isset( $config['class'] ) ) {
                                throw new MWException( "Cannot register backend `{$name}` with no class." );
                        }
                        $class = $config['class'];
index a443a3a..a5f5073 100644 (file)
@@ -62,7 +62,7 @@ class FileBackendMultiWrite extends FileBackend {
         * Additional $config params include:
         *   - backends       : Array of backend config and multi-backend settings.
         *                      Each value is the config used in the constructor of a
-        *                          FileBackendStore class, but with these additional settings:
+        *                      FileBackendStore class, but with these additional settings:
         *                        - class         : The name of the backend class
         *                        - isMultiMaster : This must be set for one backend.
         *                        - template:     : If given a backend name, this will use
index 7952bcb..28f5b73 100644 (file)
@@ -167,7 +167,7 @@ abstract class FileOp {
         * @return Array
         */
        final public function applyDependencies( array $deps ) {
-               $deps['read']  += array_fill_keys( $this->storagePathsRead(), 1 );
+               $deps['read'] += array_fill_keys( $this->storagePathsRead(), 1 );
                $deps['write'] += array_fill_keys( $this->storagePathsChanged(), 1 );
                return $deps;
        }
index 02c0c9a..9c271ea 100644 (file)
@@ -148,7 +148,7 @@ class SwiftFileBackend extends FileBackendStore {
                $this->connContainerCache = new ProcessCacheLRU( 300 );
                // Cache auth token information to avoid RTTs
                if ( !empty( $config['cacheAuthInfo'] ) ) {
-                       if ( php_sapi_name() === 'cli' ) {
+                       if ( PHP_SAPI === 'cli' ) {
                                $this->srvCache = wfGetMainCache(); // preferrably memcached
                        } else {
                                try { // look for APC, XCache, WinCache, ect...
@@ -315,7 +315,9 @@ class SwiftFileBackend extends FileBackendStore {
                }
 
                // (b) Get a SHA-1 hash of the object
+               wfSuppressWarnings();
                $sha1Hash = sha1_file( $params['src'] );
+               wfRestoreWarnings();
                if ( $sha1Hash === false ) { // source doesn't exist?
                        $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
                        return $status;
@@ -988,7 +990,7 @@ class SwiftFileBackend extends FileBackendStore {
                                $objects = $container->list_objects( $limit, $after, $prefix );
                                foreach ( $objects as $object ) { // files
                                        $objectDir = $this->getParentDir( $object ); // directory of object
-                                       if ( $objectDir !== false ) { // file has a parent dir
+                                       if ( $objectDir !== false && $objectDir !== $dir ) {
                                                // Swift stores paths in UTF-8, using binary sorting.
                                                // See function "create_container_table" in common/db.py.
                                                // If a directory is not "greater" than the last one,
index a8fe258..90f4ccd 100644 (file)
  */
 
 /**
- * Version of LockManager based on using DB table locks.
+ * Version of LockManager based on using named/row DB locks.
+ *
  * This is meant for multi-wiki systems that may share files.
- * All locks are blocking, so it might be useful to set a small
- * lock-wait timeout via server config to curtail 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 DBs, each on their
@@ -37,7 +36,7 @@
  * @ingroup LockManager
  * @since 1.19
  */
-class DBLockManager extends QuorumLockManager {
+abstract class DBLockManager extends QuorumLockManager {
        /** @var Array Map of DB names to server config */
        protected $dbServers; // (DB name => server config array)
        /** @var BagOStuff */
@@ -67,6 +66,7 @@ class DBLockManager extends QuorumLockManager {
         *                   each having an odd-numbered list of DB names (peers) as values.
         *                   Any DB named 'localDBMaster' will automatically use the DB master
         *                   settings for this wiki (without the need for a dbServers entry).
+        *                   Only use 'localDBMaster' if the domain is a valid wiki ID.
         *   - lockExpiry  : Lock timeout (seconds) for dropped connections. [optional]
         *                   This tells the DB server how long to wait before assuming
         *                   connection failure and releasing all the locks for a session.
@@ -110,65 +110,6 @@ class DBLockManager extends QuorumLockManager {
                $this->session = wfRandomString( 31 );
        }
 
-       /**
-        * 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.
-        *
-        * @see QuorumLockManager::getLocksOnServer()
-        * @return Status
-        */
-       protected function getLocksOnServer( $lockSrv, array $paths, $type ) {
-               $status = Status::newGood();
-
-               if ( $type == self::LOCK_EX ) { // writer locks
-                       try {
-                               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
-                               # Build up values for INSERT clause
-                               $data = array();
-                               foreach ( $keys as $key ) {
-                                       $data[] = array( 'fle_key' => $key );
-                               }
-                               # Wait on any existing writers and block new ones if we get in
-                               $db = $this->getConnection( $lockSrv ); // checked in isServerUp()
-                               $db->insert( 'filelocks_exclusive', $data, __METHOD__ );
-                       } catch ( DBError $e ) {
-                               foreach ( $paths as $path ) {
-                                       $status->fatal( 'lockmanager-fail-acquirelock', $path );
-                               }
-                       }
-               }
-
-               return $status;
-       }
-
-       /**
-        * @see QuorumLockManager::freeLocksOnServer()
-        * @return Status
-        */
-       protected function freeLocksOnServer( $lockSrv, array $paths, $type ) {
-               return Status::newGood(); // not supported
-       }
-
-       /**
-        * @see QuorumLockManager::releaseAllLocks()
-        * @return Status
-        */
-       protected function releaseAllLocks() {
-               $status = Status::newGood();
-
-               foreach ( $this->conns as $lockDb => $db ) {
-                       if ( $db->trxLevel() ) { // in transaction
-                               try {
-                                       $db->rollback( __METHOD__ ); // finish transaction and kill any rows
-                               } catch ( DBError $e ) {
-                                       $status->fatal( 'lockmanager-fail-db-release', $lockDb );
-                               }
-                       }
-               }
-
-               return $status;
-       }
-
        /**
         * @see QuorumLockManager::isServerUp()
         * @return bool
@@ -197,8 +138,8 @@ class DBLockManager extends QuorumLockManager {
                if ( !isset( $this->conns[$lockDb] ) ) {
                        $db = null;
                        if ( $lockDb === 'localDBMaster' ) {
-                               $lb = wfGetLBFactory()->newMainLB();
-                               $db = $lb->getConnection( DB_MASTER );
+                               $lb = wfGetLBFactory()->getMainLB( $this->domain );
+                               $db = $lb->getConnection( DB_MASTER, array(), $this->domain );
                        } elseif ( isset( $this->dbServers[$lockDb] ) ) {
                                $config = $this->dbServers[$lockDb];
                                $db = DatabaseBase::factory( $config['type'], $config );
@@ -274,14 +215,8 @@ class DBLockManager extends QuorumLockManager {
         * Make sure remaining locks get cleared for sanity
         */
        function __destruct() {
+               $this->releaseAllLocks();
                foreach ( $this->conns as $db ) {
-                       if ( $db->trxLevel() ) { // in transaction
-                               try {
-                                       $db->rollback( __METHOD__ ); // finish transaction and kill any rows
-                               } catch ( DBError $e ) {
-                                       // oh well
-                               }
-                       }
                        $db->close();
                }
        }
@@ -321,7 +256,7 @@ class MySqlLockManager extends DBLockManager {
                $status = Status::newGood();
 
                $db = $this->getConnection( $lockSrv ); // checked in isServerUp()
-               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
+               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
                # Build up values for INSERT clause
                $data = array();
                foreach ( $keys as $key ) {
@@ -371,4 +306,117 @@ class MySqlLockManager extends DBLockManager {
 
                return $status;
        }
+
+       /**
+        * @see QuorumLockManager::freeLocksOnServer()
+        * @return Status
+        */
+       protected function freeLocksOnServer( $lockSrv, array $paths, $type ) {
+               return Status::newGood(); // not supported
+       }
+
+       /**
+        * @see QuorumLockManager::releaseAllLocks()
+        * @return Status
+        */
+       protected function releaseAllLocks() {
+               $status = Status::newGood();
+
+               foreach ( $this->conns as $lockDb => $db ) {
+                       if ( $db->trxLevel() ) { // in transaction
+                               try {
+                                       $db->rollback( __METHOD__ ); // finish transaction and kill any rows
+                               } catch ( DBError $e ) {
+                                       $status->fatal( 'lockmanager-fail-db-release', $lockDb );
+                               }
+                       }
+               }
+
+               return $status;
+       }
+}
+
+/**
+ * PostgreSQL version of DBLockManager that supports shared locks.
+ * All locks are non-blocking, which avoids deadlocks.
+ *
+ * @ingroup LockManager
+ */
+class PostgreSqlLockManager extends DBLockManager {
+       /** @var Array Mapping of lock types to the type actually used */
+       protected $lockTypeMap = array(
+               self::LOCK_SH => self::LOCK_SH,
+               self::LOCK_UW => self::LOCK_SH,
+               self::LOCK_EX => self::LOCK_EX
+       );
+
+       protected function getLocksOnServer( $lockSrv, array $paths, $type ) {
+               $status = Status::newGood();
+               if ( !count( $paths ) ) {
+                       return $status; // nothing to lock
+               }
+
+               $db = $this->getConnection( $lockSrv ); // checked in isServerUp()
+               $bigints = array_unique( array_map(
+                       function( $key ) { return wfBaseConvert( substr( $key, 0, 15 ), 16, 10 ); },
+                       array_map( array( $this, 'sha1Base16Absolute' ), $paths )
+               ) );
+
+               // Try to acquire all the locks...
+               $fields = array();
+               foreach ( $bigints as $bigint ) {
+                       $fields[] = ( $type == self::LOCK_SH )
+                               ? "pg_try_advisory_lock_shared({$db->addQuotes( $bigint )}) AS K$bigint"
+                               : "pg_try_advisory_lock({$db->addQuotes( $bigint )}) AS K$bigint";
+               }
+               $res = $db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
+               $row = (array)$res->fetchObject();
+
+               if ( in_array( 'f', $row ) ) {
+                       // Release any acquired locks if some could not be acquired...
+                       $fields = array();
+                       foreach ( $row as $kbigint => $ok ) {
+                               if ( $ok === 't' ) { // locked
+                                       $bigint = substr( $kbigint, 1 ); // strip off the "K"
+                                       $fields[] = ( $type == self::LOCK_SH )
+                                               ? "pg_advisory_unlock_shared({$db->addQuotes( $bigint )})"
+                                               : "pg_advisory_unlock({$db->addQuotes( $bigint )})";
+                               }
+                       }
+                       if ( count( $fields ) ) {
+                               $db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
+                       }
+                       foreach ( $paths as $path ) {
+                               $status->fatal( 'lockmanager-fail-acquirelock', $path );
+                       }
+               }
+
+               return $status;
+       }
+
+       /**
+        * @see QuorumLockManager::freeLocksOnServer()
+        * @return Status
+        */
+       protected function freeLocksOnServer( $lockSrv, array $paths, $type ) {
+               return Status::newGood(); // not supported
+       }
+
+       /**
+        * @see QuorumLockManager::releaseAllLocks()
+        * @return Status
+        */
+       protected function releaseAllLocks() {
+               $status = Status::newGood();
+
+               foreach ( $this->conns as $lockDb => $db ) {
+                       try {
+                               $db->query( "SELECT pg_advisory_unlock_all()", __METHOD__ );
+                       } catch ( DBError $e ) {
+                               $status->fatal( 'lockmanager-fail-db-release', $lockDb );
+                       }
+               }
+
+               return $status;
+       }
 }
index 9a6206f..f374fdd 100644 (file)
@@ -237,8 +237,7 @@ class FSLockManager extends LockManager {
         * @return string
         */
        protected function getLockPath( $path ) {
-               $hash = self::sha1Base36( $path );
-               return "{$this->lockDir}/{$hash}.lock";
+               return "{$this->lockDir}/{$this->sha1Base36Absolute( $path )}.lock";
        }
 
        /**
index 3de6183..96d37ab 100644 (file)
@@ -94,7 +94,7 @@ class LSLockManager extends QuorumLockManager {
 
                // Send out the command and get the response...
                $type = ( $type == self::LOCK_SH ) ? 'SH' : 'EX';
-               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
+               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
                $response = $this->sendCommand( $lockSrv, 'ACQUIRE', $type, $keys );
 
                if ( $response !== 'ACQUIRED' ) {
@@ -115,7 +115,7 @@ class LSLockManager extends QuorumLockManager {
 
                // Send out the command and get the response...
                $type = ( $type == self::LOCK_SH ) ? 'SH' : 'EX';
-               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
+               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
                $response = $this->sendCommand( $lockSrv, 'RELEASE', $type, $keys );
 
                if ( $response !== 'RELEASED' ) {
index 51454a4..d222bab 100644 (file)
@@ -53,6 +53,8 @@ abstract class LockManager {
        /** @var Array Map of (resource path => lock type => count) */
        protected $locksHeld = array();
 
+       protected $domain; // string; domain (usually wiki ID)
+
        /* Lock types; stronger locks have higher values */
        const LOCK_SH = 1; // shared lock (for reads)
        const LOCK_UW = 2; // shared lock (for reads used to write elsewhere)
@@ -61,9 +63,14 @@ abstract class LockManager {
        /**
         * Construct a new instance from configuration
         *
+        * $config paramaters include:
+        *   - domain : Domain (usually wiki ID) that all resources are relative to [optional]
+        *
         * @param $config Array
         */
-       public function __construct( array $config ) {}
+       public function __construct( array $config ) {
+               $this->domain = isset( $config['domain'] ) ? $config['domain'] : wfWikiID();
+       }
 
        /**
         * Lock the resources at the given abstract paths
@@ -94,13 +101,27 @@ abstract class LockManager {
        }
 
        /**
-        * Get the base 36 SHA-1 of a string, padded to 31 digits
+        * Get the base 36 SHA-1 of a string, padded to 31 digits.
+        * Before hashing, the path will be prefixed with the domain ID.
+        * This should be used interally for lock key or file names.
         *
         * @param $path string
         * @return string
         */
-       final protected static function sha1Base36( $path ) {
-               return wfBaseConvert( sha1( $path ), 16, 36, 31 );
+       final protected function sha1Base36Absolute( $path ) {
+               return wfBaseConvert( sha1( "{$this->domain}:{$path}" ), 16, 36, 31 );
+       }
+
+       /**
+        * Get the base 16 SHA-1 of a string, padded to 31 digits.
+        * Before hashing, the path will be prefixed with the domain ID.
+        * This should be used interally for lock key or file names.
+        *
+        * @param $path string
+        * @return string
+        */
+       final protected function sha1Base16Absolute( $path ) {
+               return sha1( "{$this->domain}:{$path}" );
        }
 
        /**
@@ -122,216 +143,6 @@ abstract class LockManager {
        abstract protected function doUnlock( array $paths, $type );
 }
 
-/**
- * Version of LockManager that uses a quorum from peer servers for locks.
- * The resource space can also be sharded into separate peer groups.
- *
- * @ingroup LockManager
- * @since 1.20
- */
-abstract class QuorumLockManager extends LockManager {
-       /** @var Array Map of bucket indexes to peer server lists */
-       protected $srvsByBucket = array(); // (bucket index => (lsrv1, lsrv2, ...))
-
-       /**
-        * @see LockManager::doLock()
-        * @param $paths array
-        * @param $type int
-        * @return Status
-        */
-       final protected function doLock( array $paths, $type ) {
-               $status = Status::newGood();
-
-               $pathsToLock = array(); // (bucket => paths)
-               // Get locks that need to be acquired (buckets => locks)...
-               foreach ( $paths as $path ) {
-                       if ( isset( $this->locksHeld[$path][$type] ) ) {
-                               ++$this->locksHeld[$path][$type];
-                       } elseif ( isset( $this->locksHeld[$path][self::LOCK_EX] ) ) {
-                               $this->locksHeld[$path][$type] = 1;
-                       } else {
-                               $bucket = $this->getBucketFromKey( $path );
-                               $pathsToLock[$bucket][] = $path;
-                       }
-               }
-
-               $lockedPaths = array(); // files locked in this attempt
-               // Attempt to acquire these locks...
-               foreach ( $pathsToLock as $bucket => $paths ) {
-                       // Try to acquire the locks for this bucket
-                       $status->merge( $this->doLockingRequestBucket( $bucket, $paths, $type ) );
-                       if ( !$status->isOK() ) {
-                               $status->merge( $this->doUnlock( $lockedPaths, $type ) );
-                               return $status;
-                       }
-                       // Record these locks as active
-                       foreach ( $paths as $path ) {
-                               $this->locksHeld[$path][$type] = 1; // locked
-                       }
-                       // Keep track of what locks were made in this attempt
-                       $lockedPaths = array_merge( $lockedPaths, $paths );
-               }
-
-               return $status;
-       }
-
-       /**
-        * @see LockManager::doUnlock()
-        * @param $paths array
-        * @param $type int
-        * @return Status
-        */
-       final protected function doUnlock( array $paths, $type ) {
-               $status = Status::newGood();
-
-               $pathsToUnlock = array();
-               foreach ( $paths as $path ) {
-                       if ( !isset( $this->locksHeld[$path][$type] ) ) {
-                               $status->warning( 'lockmanager-notlocked', $path );
-                       } else {
-                               --$this->locksHeld[$path][$type];
-                               // Reference count the locks held and release locks when zero
-                               if ( $this->locksHeld[$path][$type] <= 0 ) {
-                                       unset( $this->locksHeld[$path][$type] );
-                                       $bucket = $this->getBucketFromKey( $path );
-                                       $pathsToUnlock[$bucket][] = $path;
-                               }
-                               if ( !count( $this->locksHeld[$path] ) ) {
-                                       unset( $this->locksHeld[$path] ); // no SH or EX locks left for key
-                               }
-                       }
-               }
-
-               // Remove these specific locks if possible, or at least release
-               // all locks once this process is currently not holding any locks.
-               foreach ( $pathsToUnlock as $bucket => $paths ) {
-                       $status->merge( $this->doUnlockingRequestBucket( $bucket, $paths, $type ) );
-               }
-               if ( !count( $this->locksHeld ) ) {
-                       $status->merge( $this->releaseAllLocks() );
-               }
-
-               return $status;
-       }
-
-       /**
-        * Attempt to acquire locks with the peers for a bucket.
-        * This is all or nothing; if any key is locked then this totally fails.
-        *
-        * @param $bucket integer
-        * @param $paths Array List of resource keys to lock
-        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
-        * @return Status
-        */
-       final protected function doLockingRequestBucket( $bucket, array $paths, $type ) {
-               $status = Status::newGood();
-
-               $yesVotes = 0; // locks made on trustable servers
-               $votesLeft = count( $this->srvsByBucket[$bucket] ); // remaining peers
-               $quorum = floor( $votesLeft/2 + 1 ); // simple majority
-               // Get votes for each peer, in order, until we have enough...
-               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
-                       if ( !$this->isServerUp( $lockSrv ) ) {
-                               --$votesLeft;
-                               $status->warning( 'lockmanager-fail-svr-acquire', $lockSrv );
-                               continue; // server down?
-                       }
-                       // Attempt to acquire the lock on this peer
-                       $status->merge( $this->getLocksOnServer( $lockSrv, $paths, $type ) );
-                       if ( !$status->isOK() ) {
-                               return $status; // vetoed; resource locked
-                       }
-                       ++$yesVotes; // success for this peer
-                       if ( $yesVotes >= $quorum ) {
-                               return $status; // lock obtained
-                       }
-                       --$votesLeft;
-                       $votesNeeded = $quorum - $yesVotes;
-                       if ( $votesNeeded > $votesLeft ) {
-                               break; // short-circuit
-                       }
-               }
-               // At this point, we must not have met the quorum
-               $status->setResult( false );
-
-               return $status;
-       }
-
-       /**
-        * Attempt to release locks with the peers for a bucket
-        *
-        * @param $bucket integer
-        * @param $paths Array List of resource keys to lock
-        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
-        * @return Status
-        */
-       final protected function doUnlockingRequestBucket( $bucket, array $paths, $type ) {
-               $status = Status::newGood();
-
-               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
-                       if ( !$this->isServerUp( $lockSrv ) ) {
-                               $status->fatal( 'lockmanager-fail-svr-release', $lockSrv );
-                       // Attempt to release the lock on this peer
-                       } else {
-                               $status->merge( $this->freeLocksOnServer( $lockSrv, $paths, $type ) );
-                       }
-               }
-
-               return $status;
-       }
-
-       /**
-        * Get the bucket for resource path.
-        * This should avoid throwing any exceptions.
-        *
-        * @param $path string
-        * @return integer
-        */
-       protected function getBucketFromKey( $path ) {
-               $prefix = substr( sha1( $path ), 0, 2 ); // first 2 hex chars (8 bits)
-               return (int)base_convert( $prefix, 16, 10 ) % count( $this->srvsByBucket );
-       }
-
-       /**
-        * Check if a lock server is up
-        *
-        * @param $lockSrv string
-        * @return bool
-        */
-       abstract protected function isServerUp( $lockSrv );
-
-       /**
-        * Get a connection to a lock server and acquire locks on $paths
-        *
-        * @param $lockSrv string
-        * @param $paths array
-        * @param $type integer
-        * @return Status
-        */
-       abstract protected function getLocksOnServer( $lockSrv, array $paths, $type );
-
-       /**
-        * Get a connection to a lock server and release locks on $paths.
-        *
-        * Subclasses must effectively implement this or releaseAllLocks().
-        *
-        * @param $lockSrv string
-        * @param $paths array
-        * @param $type integer
-        * @return Status
-        */
-       abstract protected function freeLocksOnServer( $lockSrv, array $paths, $type );
-
-       /**
-        * Release all locks that this session is holding.
-        *
-        * Subclasses must effectively implement this or freeLocksOnServer().
-        *
-        * @return Status
-        */
-       abstract protected function releaseAllLocks();
-}
-
 /**
  * Simple version of LockManager that does nothing
  * @since 1.19
index 8c8c940..f0d5818 100644 (file)
  * @since 1.19
  */
 class LockManagerGroup {
-       /**
-        * @var LockManagerGroup
-        */
-       protected static $instance = null;
+       /** @var Array (domain => LockManager) */
+       protected static $instances = array();
+
+       protected $domain; // string; domain (usually wiki ID)
 
-       /** @var Array of (name => ('class' =>, 'config' =>, 'instance' =>)) */
+       /** @var Array of (name => ('class' => ..., 'config' => ..., 'instance' => ...)) */
        protected $managers = array();
 
-       protected function __construct() {}
+       /**
+        * @param $domain string Domain (usually wiki ID)
+        */
+       protected function __construct( $domain ) {
+               $this->domain = $domain;
+       }
 
        /**
+        * @param $domain string Domain (usually wiki ID)
         * @return LockManagerGroup
         */
-       public static function singleton() {
-               if ( self::$instance == null ) {
-                       self::$instance = new self();
-                       self::$instance->initFromGlobals();
+       public static function singleton( $domain = false ) {
+               $domain = ( $domain === false ) ? wfWikiID() : $domain;
+               if ( !isset( self::$instances[$domain] ) ) {
+                       self::$instances[$domain] = new self( $domain );
+                       self::$instances[$domain]->initFromGlobals();
                }
-               return self::$instance;
+               return self::$instances[$domain];
        }
 
        /**
-        * Destroy the singleton instance, so that a new one will be created next
-        * time singleton() is called.
+        * Destroy the singleton instances
+        *
+        * @return void
         */
-       public static function destroySingleton() {
-               self::$instance = null;
+       public static function destroySingletons() {
+               self::$instances = array();
        }
 
        /**
@@ -78,6 +86,7 @@ class LockManagerGroup {
         */
        protected function register( array $configs ) {
                foreach ( $configs as $config ) {
+                       $config['domain'] = $this->domain;
                        if ( !isset( $config['name'] ) ) {
                                throw new MWException( "Cannot register a lock manager with no name." );
                        }
@@ -115,6 +124,21 @@ class LockManagerGroup {
                return $this->managers[$name]['instance'];
        }
 
+       /**
+        * Get the config array for a lock manager object with a given name
+        *
+        * @param $name string
+        * @return Array
+        * @throws MWException
+        */
+       public function config( $name ) {
+               if ( !isset( $this->managers[$name] ) ) {
+                       throw new MWException( "No lock manager defined with the name `$name`." );
+               }
+               $class = $this->managers[$name]['class'];
+               return array( 'class' => $class ) + $this->managers[$name]['config'];
+       }
+
        /**
         * Get the default lock manager configured for the site.
         * Returns NullLockManager if no lock manager could be found.
index 610fc47..099f11d 100644 (file)
@@ -50,7 +50,6 @@ class MemcLockManager extends QuorumLockManager {
 
        protected $lockExpiry; // integer; maximum time locks can be held
        protected $session = ''; // string; random SHA-1 UUID
-       protected $wikiId = ''; // string
 
        /**
         * Construct a new instance from configuration.
@@ -61,7 +60,6 @@ class MemcLockManager extends QuorumLockManager {
         *                    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.
-        *   - wikiId       : Wiki ID string that all resources are relative to. [optional]
         *
         * @param Array $config
         * @throws MWException
@@ -88,8 +86,6 @@ class MemcLockManager extends QuorumLockManager {
                        }
                }
 
-               $this->wikiId = isset( $config['wikiId'] ) ? $config['wikiId'] : wfWikiID();
-
                $met = ini_get( 'max_execution_time' ); // this is 0 in CLI mode
                $this->lockExpiry = $met ? 2*(int)$met : 2*3600;
 
@@ -252,9 +248,7 @@ class MemcLockManager extends QuorumLockManager {
         * @return string
         */
        protected function recordKeyForPath( $path ) {
-               $hash = LockManager::sha1Base36( $path );
-               list( $db, $prefix ) = wfSplitWikiID( $this->wikiId );
-               return wfForeignMemcKey( $db, $prefix, __CLASS__, 'locks', $hash );
+               return implode( ':', array( __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ) );
        }
 
        /**
diff --git a/includes/filebackend/lockmanager/QuorumLockManager.php b/includes/filebackend/lockmanager/QuorumLockManager.php
new file mode 100644 (file)
index 0000000..76a3ad6
--- /dev/null
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Version of LockManager that uses a quorum from peer servers for locks.
+ *
+ * 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
+ */
+
+/**
+ * Version of LockManager that uses a quorum from peer servers for locks.
+ * The resource space can also be sharded into separate peer groups.
+ *
+ * @ingroup LockManager
+ * @since 1.20
+ */
+abstract class QuorumLockManager extends LockManager {
+       /** @var Array Map of bucket indexes to peer server lists */
+       protected $srvsByBucket = array(); // (bucket index => (lsrv1, lsrv2, ...))
+
+       /**
+        * @see LockManager::doLock()
+        * @param $paths array
+        * @param $type int
+        * @return Status
+        */
+       final protected function doLock( array $paths, $type ) {
+               $status = Status::newGood();
+
+               $pathsToLock = array(); // (bucket => paths)
+               // Get locks that need to be acquired (buckets => locks)...
+               foreach ( $paths as $path ) {
+                       if ( isset( $this->locksHeld[$path][$type] ) ) {
+                               ++$this->locksHeld[$path][$type];
+                       } elseif ( isset( $this->locksHeld[$path][self::LOCK_EX] ) ) {
+                               $this->locksHeld[$path][$type] = 1;
+                       } else {
+                               $bucket = $this->getBucketFromPath( $path );
+                               $pathsToLock[$bucket][] = $path;
+                       }
+               }
+
+               $lockedPaths = array(); // files locked in this attempt
+               // Attempt to acquire these locks...
+               foreach ( $pathsToLock as $bucket => $paths ) {
+                       // Try to acquire the locks for this bucket
+                       $status->merge( $this->doLockingRequestBucket( $bucket, $paths, $type ) );
+                       if ( !$status->isOK() ) {
+                               $status->merge( $this->doUnlock( $lockedPaths, $type ) );
+                               return $status;
+                       }
+                       // Record these locks as active
+                       foreach ( $paths as $path ) {
+                               $this->locksHeld[$path][$type] = 1; // locked
+                       }
+                       // Keep track of what locks were made in this attempt
+                       $lockedPaths = array_merge( $lockedPaths, $paths );
+               }
+
+               return $status;
+       }
+
+       /**
+        * @see LockManager::doUnlock()
+        * @param $paths array
+        * @param $type int
+        * @return Status
+        */
+       final protected function doUnlock( array $paths, $type ) {
+               $status = Status::newGood();
+
+               $pathsToUnlock = array();
+               foreach ( $paths as $path ) {
+                       if ( !isset( $this->locksHeld[$path][$type] ) ) {
+                               $status->warning( 'lockmanager-notlocked', $path );
+                       } else {
+                               --$this->locksHeld[$path][$type];
+                               // Reference count the locks held and release locks when zero
+                               if ( $this->locksHeld[$path][$type] <= 0 ) {
+                                       unset( $this->locksHeld[$path][$type] );
+                                       $bucket = $this->getBucketFromPath( $path );
+                                       $pathsToUnlock[$bucket][] = $path;
+                               }
+                               if ( !count( $this->locksHeld[$path] ) ) {
+                                       unset( $this->locksHeld[$path] ); // no SH or EX locks left for key
+                               }
+                       }
+               }
+
+               // Remove these specific locks if possible, or at least release
+               // all locks once this process is currently not holding any locks.
+               foreach ( $pathsToUnlock as $bucket => $paths ) {
+                       $status->merge( $this->doUnlockingRequestBucket( $bucket, $paths, $type ) );
+               }
+               if ( !count( $this->locksHeld ) ) {
+                       $status->merge( $this->releaseAllLocks() );
+               }
+
+               return $status;
+       }
+
+       /**
+        * Attempt to acquire locks with the peers for a bucket.
+        * This is all or nothing; if any key is locked then this totally fails.
+        *
+        * @param $bucket integer
+        * @param $paths Array List of resource keys to lock
+        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
+        * @return Status
+        */
+       final protected function doLockingRequestBucket( $bucket, array $paths, $type ) {
+               $status = Status::newGood();
+
+               $yesVotes = 0; // locks made on trustable servers
+               $votesLeft = count( $this->srvsByBucket[$bucket] ); // remaining peers
+               $quorum = floor( $votesLeft/2 + 1 ); // simple majority
+               // Get votes for each peer, in order, until we have enough...
+               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
+                       if ( !$this->isServerUp( $lockSrv ) ) {
+                               --$votesLeft;
+                               $status->warning( 'lockmanager-fail-svr-acquire', $lockSrv );
+                               continue; // server down?
+                       }
+                       // Attempt to acquire the lock on this peer
+                       $status->merge( $this->getLocksOnServer( $lockSrv, $paths, $type ) );
+                       if ( !$status->isOK() ) {
+                               return $status; // vetoed; resource locked
+                       }
+                       ++$yesVotes; // success for this peer
+                       if ( $yesVotes >= $quorum ) {
+                               return $status; // lock obtained
+                       }
+                       --$votesLeft;
+                       $votesNeeded = $quorum - $yesVotes;
+                       if ( $votesNeeded > $votesLeft ) {
+                               break; // short-circuit
+                       }
+               }
+               // At this point, we must not have met the quorum
+               $status->setResult( false );
+
+               return $status;
+       }
+
+       /**
+        * Attempt to release locks with the peers for a bucket
+        *
+        * @param $bucket integer
+        * @param $paths Array List of resource keys to lock
+        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
+        * @return Status
+        */
+       final protected function doUnlockingRequestBucket( $bucket, array $paths, $type ) {
+               $status = Status::newGood();
+
+               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
+                       if ( !$this->isServerUp( $lockSrv ) ) {
+                               $status->fatal( 'lockmanager-fail-svr-release', $lockSrv );
+                       // Attempt to release the lock on this peer
+                       } else {
+                               $status->merge( $this->freeLocksOnServer( $lockSrv, $paths, $type ) );
+                       }
+               }
+
+               return $status;
+       }
+
+       /**
+        * Get the bucket for resource path.
+        * This should avoid throwing any exceptions.
+        *
+        * @param $path string
+        * @return integer
+        */
+       protected function getBucketFromPath( $path ) {
+               $prefix = substr( sha1( $path ), 0, 2 ); // first 2 hex chars (8 bits)
+               return (int)base_convert( $prefix, 16, 10 ) % count( $this->srvsByBucket );
+       }
+
+       /**
+        * Check if a lock server is up
+        *
+        * @param $lockSrv string
+        * @return bool
+        */
+       abstract protected function isServerUp( $lockSrv );
+
+       /**
+        * Get a connection to a lock server and acquire locks on $paths
+        *
+        * @param $lockSrv string
+        * @param $paths array
+        * @param $type integer
+        * @return Status
+        */
+       abstract protected function getLocksOnServer( $lockSrv, array $paths, $type );
+
+       /**
+        * Get a connection to a lock server and release locks on $paths.
+        *
+        * Subclasses must effectively implement this or releaseAllLocks().
+        *
+        * @param $lockSrv string
+        * @param $paths array
+        * @param $type integer
+        * @return Status
+        */
+       abstract protected function freeLocksOnServer( $lockSrv, array $paths, $type );
+
+       /**
+        * Release all locks that this session is holding.
+        *
+        * Subclasses must effectively implement this or freeLocksOnServer().
+        *
+        * @return Status
+        */
+       abstract protected function releaseAllLocks();
+}
index 635cb95..e49f37d 100644 (file)
@@ -46,6 +46,9 @@ class FSRepo extends FileRepo {
                        $thumbDir = isset( $info['thumbDir'] )
                                ? $info['thumbDir']
                                : "{$directory}/thumb";
+                       $transcodedDir = isset( $info['transcodedDir'] )
+                               ? $info['transcodedDir']
+                               : "{$directory}/transcoded";
                        $fileMode = isset( $info['fileMode'] )
                                ? $info['fileMode']
                                : 0644;
@@ -59,6 +62,7 @@ class FSRepo extends FileRepo {
                                        "{$repoName}-public"  => "{$directory}",
                                        "{$repoName}-temp"    => "{$directory}/temp",
                                        "{$repoName}-thumb"   => $thumbDir,
+                                       "{$repoName}-transcoded"   => $transcodedDir,
                                        "{$repoName}-deleted" => $deletedDir
                                ),
                                'fileMode'       => $fileMode,
index 82f7b49..05e71d4 100644 (file)
@@ -120,7 +120,7 @@ class FileRepo {
                $this->isPrivate = !empty( $info['isPrivate'] );
                // Give defaults for the basic zones...
                $this->zones = isset( $info['zones'] ) ? $info['zones'] : array();
-               foreach ( array( 'public', 'thumb', 'temp', 'deleted' ) as $zone ) {
+               foreach ( array( 'public', 'thumb', 'transcoded', 'temp', 'deleted' ) as $zone ) {
                        if ( !isset( $this->zones[$zone]['container'] ) ) {
                                $this->zones[$zone]['container'] = "{$this->name}-{$zone}";
                        }
@@ -204,7 +204,7 @@ class FileRepo {
         * @return String or false
         */
        public function getZoneUrl( $zone, $ext = null ) {
-               if ( in_array( $zone, array( 'public', 'temp', 'thumb' ) ) ) { // standard public zones
+               if ( in_array( $zone, array( 'public', 'temp', 'thumb', 'transcoded' ) ) ) { // standard public zones
                        if ( $ext !== null && isset( $this->zones[$zone]['urlsByExt'][$ext] ) ) {
                                return $this->zones[$zone]['urlsByExt'][$ext]; // custom URL for extension/zone
                        } elseif ( isset( $this->zones[$zone]['url'] ) ) {
@@ -220,6 +220,8 @@ class FileRepo {
                                return false; // no public URL
                        case 'thumb':
                                return $this->thumbUrl;
+                       case 'transcoded':
+                               return "{$this->url}/transcoded";
                        default:
                                return false;
                }
@@ -240,7 +242,7 @@ class FileRepo {
         */
        public function getZoneHandlerUrl( $zone ) {
                if ( isset( $this->zones[$zone]['handlerUrl'] )
-                       && in_array( $zone, array( 'public', 'temp', 'thumb' ) ) )
+                       && in_array( $zone, array( 'public', 'temp', 'thumb', 'transcoded' ) ) )
                {
                        return $this->zones[$zone]['handlerUrl'];
                }
@@ -694,7 +696,7 @@ class FileRepo {
        public function getDescriptionStylesheetUrl() {
                if ( isset( $this->scriptDirUrl ) ) {
                        return $this->makeUrl( 'title=MediaWiki:Filepage.css&' .
-                               wfArrayToCGI( Skin::getDynamicStylesheetQuery() ) );
+                               wfArrayToCgi( Skin::getDynamicStylesheetQuery() ) );
                }
                return false;
        }
@@ -955,7 +957,7 @@ class FileRepo {
                $hashPath   = $this->getHashPath( $originalName );
                $dstRel     = "{$hashPath}{$date}!{$originalName}";
                $dstUrlRel  = $hashPath . $date . '!' . rawurlencode( $originalName );
-               $virtualUrl = $this->getVirtualUrl( 'temp' )  . '/' . $dstUrlRel;
+               $virtualUrl = $this->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel;
 
                $result = $this->quickImport( $srcPath, $virtualUrl );
                $result->value = $virtualUrl;
@@ -1105,7 +1107,7 @@ class FileRepo {
                        if ( !$this->initDirectory( $dstDir )->isOK() ) {
                                return $this->newFatal( 'directorycreateerror', $dstDir );
                        }
-                       if ( !$this->initDirectory($archiveDir )->isOK() ) {
+                       if ( !$this->initDirectory( $archiveDir )->isOK() ) {
                                return $this->newFatal( 'directorycreateerror', $archiveDir );
                        }
 
@@ -1670,10 +1672,17 @@ class FileRepo {
                                        'directory' => ( $this->zones['thumb']['directory'] == '' )
                                                ? 'temp'
                                                : $this->zones['thumb']['directory'] . '/temp'
+                               ),
+                               'transcoded'  => array(
+                                       'container' => $this->zones['transcoded']['container'],
+                                       'directory' => ( $this->zones['transcoded']['directory'] == '' )
+                                               ? 'temp'
+                                               : $this->zones['transcoded']['directory'] . '/temp'
                                )
                        ),
                        'url'        => $this->getZoneUrl( 'temp' ),
                        'thumbUrl'   => $this->getZoneUrl( 'thumb' ) . '/temp',
+                       'transcodedUrl'   => $this->getZoneUrl( 'transcoded' ) . '/temp',
                        'hashLevels' => $this->hashLevels // performance
                ) );
        }
index 7697e4e..98a21f7 100644 (file)
@@ -267,14 +267,14 @@ class ForeignAPIRepo extends FileRepo {
                $sizekey = "$width:$height:$params";
 
                /* Get the array of urls that we already know */
-               $knownThumbUrls = $wgMemc->get($key);
+               $knownThumbUrls = $wgMemc->get( $key );
                if( !$knownThumbUrls ) {
                        /* No knownThumbUrls for this file */
                        $knownThumbUrls = array();
                } else {
                        if( isset( $knownThumbUrls[$sizekey] ) ) {
                                wfDebug( __METHOD__ . ': Got thumburl from local cache: ' .
-                                       "{$knownThumbUrls[$sizekey]} \n");
+                                       "{$knownThumbUrls[$sizekey]} \n" );
                                return $knownThumbUrls[$sizekey];
                        }
                        /* This size is not yet known */
@@ -294,9 +294,9 @@ class ForeignAPIRepo extends FileRepo {
                        wfDebug( __METHOD__ . " The deduced filename $fileName is not safe\n" );
                        return false;
                }
-               $localPath =  $this->getZonePath( 'thumb' ) . "/" . $this->getHashPath( $name ) . $name;
+               $localPath = $this->getZonePath( 'thumb' ) . "/" . $this->getHashPath( $name ) . $name;
                $localFilename = $localPath . "/" . $fileName;
-               $localUrl =  $this->getZoneUrl( 'thumb' ) . "/" . $this->getHashPath( $name ) . rawurlencode( $name ) . "/" . rawurlencode( $fileName );
+               $localUrl = $this->getZoneUrl( 'thumb' ) . "/" . $this->getHashPath( $name ) . rawurlencode( $name ) . "/" . rawurlencode( $fileName );
 
                if( $backend->fileExists( array( 'src' => $localFilename ) )
                        && isset( $metadata['timestamp'] ) )
index 118e981..0fbaeef 100644 (file)
@@ -212,8 +212,8 @@ class LocalRepo extends FileRepo {
                $dbr = $this->getSlaveDB();
                $id = $dbr->selectField(
                        'page', // Table
-                       'page_id',  //Field
-                       array(  //Conditions
+                       'page_id', //Field
+                       array( //Conditions
                                'page_namespace' => $title->getNamespace(),
                                'page_title' => $title->getDBkey(),
                        ),
@@ -323,4 +323,3 @@ class LocalRepo extends FileRepo {
                }
        }
 }
-
index f9e5759..1f5ae91 100644 (file)
@@ -131,7 +131,7 @@ class RepoGroup {
                        $time = isset( $options['time'] ) ? $options['time'] : '';
                        $dbkey = $title->getDBkey();
                        if ( isset( $this->cache[$dbkey][$time] ) ) {
-                               wfDebug( __METHOD__.": got File:$dbkey from process cache\n" );
+                               wfDebug( __METHOD__ . ": got File:$dbkey from process cache\n" );
                                # Move it to the end of the list so that we can delete the LRU entry later
                                $this->pingCache( $dbkey );
                                # Return the entry
@@ -388,12 +388,12 @@ class RepoGroup {
         */
        function splitVirtualUrl( $url ) {
                if ( substr( $url, 0, 9 ) != 'mwrepo://' ) {
-                       throw new MWException( __METHOD__.': unknown protocol' );
+                       throw new MWException( __METHOD__ . ': unknown protocol' );
                }
 
                $bits = explode( '/', substr( $url, 9 ), 3 );
                if ( count( $bits ) != 3 ) {
-                       throw new MWException( __METHOD__.": invalid mwrepo URL: $url" );
+                       throw new MWException( __METHOD__ . ": invalid mwrepo URL: $url" );
                }
                return $bits;
        }
@@ -433,7 +433,7 @@ class RepoGroup {
                while ( count( $this->cache ) >= self::MAX_CACHE_SIZE ) {
                        reset( $this->cache );
                        $key = key( $this->cache );
-                       wfDebug( __METHOD__.": evicting $key\n" );
+                       wfDebug( __METHOD__ . ": evicting $key\n" );
                        unset( $this->cache[$key] );
                }
        }
index e1a8547..3f78619 100644 (file)
@@ -68,7 +68,7 @@ class ArchivedFile {
         * @param int $id
         * @param string $key
         */
-       function __construct( $title, $id=0, $key='' ) {
+       function __construct( $title, $id = 0, $key = '' ) {
                $this->id = -1;
                $this->title = false;
                $this->name = false;
@@ -95,11 +95,11 @@ class ArchivedFile {
                        $this->name = $title->getDBkey();
                }
 
-               if ($id) {
+               if ( $id ) {
                        $this->id = $id;
                }
 
-               if ($key) {
+               if ( $key ) {
                        $this->key = $key;
                }
 
@@ -130,37 +130,19 @@ class ArchivedFile {
                        $conds['fa_name'] = $this->title->getDBkey();
                }
 
-               if( !count($conds)) {
+               if( !count( $conds ) ) {
                        throw new MWException( "No specific information for retrieving archived file" );
                }
 
                if( !$this->title || $this->title->getNamespace() == NS_FILE ) {
                        $this->dataLoaded = true; // set it here, to have also true on miss
                        $dbr = wfGetDB( DB_SLAVE );
-                       $row = $dbr->selectRow( 'filearchive',
-                               array(
-                                       'fa_id',
-                                       'fa_name',
-                                       'fa_archive_name',
-                                       'fa_storage_key',
-                                       'fa_storage_group',
-                                       'fa_size',
-                                       'fa_bits',
-                                       'fa_width',
-                                       'fa_height',
-                                       'fa_metadata',
-                                       'fa_media_type',
-                                       'fa_major_mime',
-                                       'fa_minor_mime',
-                                       'fa_description',
-                                       'fa_user',
-                                       'fa_user_text',
-                                       'fa_timestamp',
-                                       'fa_deleted',
-                                       'fa_sha1' ),
+                       $row = $dbr->selectRow(
+                               'filearchive',
+                               self::selectFields(),
                                $conds,
                                __METHOD__,
-                               array( 'ORDER BY' => 'fa_timestamp DESC')
+                               array( 'ORDER BY' => 'fa_timestamp DESC' )
                        );
                        if ( !$row ) {
                                // this revision does not exist?
@@ -190,6 +172,34 @@ class ArchivedFile {
                return $file;
        }
 
+       /**
+        * Fields in the filearchive table
+        * @return array
+        */
+       static function selectFields() {
+               return array(
+                       'fa_id',
+                       'fa_name',
+                       'fa_archive_name',
+                       'fa_storage_key',
+                       'fa_storage_group',
+                       'fa_size',
+                       'fa_bits',
+                       'fa_width',
+                       'fa_height',
+                       'fa_metadata',
+                       'fa_media_type',
+                       'fa_major_mime',
+                       'fa_minor_mime',
+                       'fa_description',
+                       'fa_user',
+                       'fa_user_text',
+                       'fa_timestamp',
+                       'fa_deleted',
+                       'fa_sha1',
+               );
+       }
+
        /**
         * Load ArchivedFile object fields from a DB row.
         *
@@ -197,7 +207,7 @@ class ArchivedFile {
         * @since 1.21
         */
        public function loadFromRow( $row ) {
-               $this->id = intval($row->fa_id);
+               $this->id = intval( $row->fa_id );
                $this->name = $row->fa_name;
                $this->archive_name = $row->fa_archive_name;
                $this->group = $row->fa_storage_group;
index bfb9197..bf2749f 100644 (file)
@@ -40,7 +40,7 @@
  * never name a file class explictly outside of the repo class. Instead use the
  * repo's factory functions to generate file objects, for example:
  *
- * RepoGroup::singleton()->getLocalRepo()->newFile($title);
+ * RepoGroup::singleton()->getLocalRepo()->newFile( $title );
  *
  * The convenience functions wfLocalFile() and wfFindFile() should be sufficient
  * in most cases.
@@ -54,7 +54,7 @@ abstract class File {
        const DELETED_RESTRICTED = 8;
 
        /** Force rendering in the current process */
-       const RENDER_NOW   = 1;
+       const RENDER_NOW = 1;
        /**
         * Force rendering even if thumbnail already exist and using RENDER_NOW
         * I.e. you have to pass both flags: File::RENDER_NOW | File::RENDER_FORCE
@@ -348,7 +348,7 @@ abstract class File {
                        if ( $this->canRender() ) {
                                return $this->createThumb( $this->getWidth() );
                        } else {
-                               wfDebug( __METHOD__.': supposed to render ' . $this->getName() .
+                               wfDebug( __METHOD__ . ': supposed to render ' . $this->getName() .
                                        ' (' . $this->getMimeType() . "), but can't!\n" );
                                return $this->getURL(); #hm... return NULL?
                        }
@@ -663,13 +663,13 @@ abstract class File {
                if ( $this->allowInlineDisplay() ) {
                        return true;
                }
-               if ($this->isTrustedFile()) {
+               if ( $this->isTrustedFile() ) {
                        return true;
                }
 
                $type = $this->getMediaType();
                $mime = $this->getMimeType();
-               #wfDebug("LocalFile::isSafeFile: type= $type, mime= $mime\n");
+               #wfDebug( "LocalFile::isSafeFile: type= $type, mime= $mime\n" );
 
                if ( !$type || $type === MEDIATYPE_UNKNOWN ) {
                        return false; #unknown type, not trusted
@@ -842,7 +842,7 @@ abstract class File {
                global $wgIgnoreImageErrors;
 
                if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
-                       return $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
+                       return $this->getHandler()->getTransform( $this, $thumbPath, $thumbUrl, $params );
                } else {
                        return new MediaTransformError( 'thumbnail_error',
                                $params['width'], 0, wfMessage( 'thumbnail-dest-create' )->text() );
@@ -873,17 +873,18 @@ abstract class File {
                                $params['descriptionUrl'] = wfExpandUrl( $descriptionUrl, PROTO_CANONICAL );
                        }
 
+                       $handler = $this->getHandler();
                        $script = $this->getTransformScript();
                        if ( $script && !( $flags & self::RENDER_NOW ) ) {
                                // Use a script to transform on client request, if possible
-                               $thumb = $this->handler->getScriptedTransform( $this, $script, $params );
+                               $thumb = $handler->getScriptedTransform( $this, $script, $params );
                                if ( $thumb ) {
                                        break;
                                }
                        }
 
                        $normalisedParams = $params;
-                       $this->handler->normaliseParams( $this, $normalisedParams );
+                       $handler->normaliseParams( $this, $normalisedParams );
 
                        $thumbName = $this->thumbName( $normalisedParams );
                        $thumbUrl = $this->getThumbUrl( $thumbName );
@@ -896,20 +897,20 @@ abstract class File {
                                        // XXX: Pass in the storage path even though we are not rendering anything
                                        // and the path is supposed to be an FS path. This is due to getScalerType()
                                        // getting called on the path and clobbering $thumb->getUrl() if it's false.
-                                       $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
+                                       $thumb = $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
                                        break;
                                }
                                // Clean up broken thumbnails as needed
                                $this->migrateThumbFile( $thumbName );
                                // Check if an up-to-date thumbnail already exists...
-                               wfDebug( __METHOD__.": Doing stat for $thumbPath\n" );
+                               wfDebug( __METHOD__ . ": Doing stat for $thumbPath\n" );
                                if ( !( $flags & self::RENDER_FORCE ) && $this->repo->fileExists( $thumbPath ) ) {
                                        $timestamp = $this->repo->getFileTimestamp( $thumbPath );
                                        if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) {
                                                // XXX: Pass in the storage path even though we are not rendering anything
                                                // and the path is supposed to be an FS path. This is due to getScalerType()
                                                // getting called on the path and clobbering $thumb->getUrl() if it's false.
-                                               $thumb = $this->handler->getTransform(
+                                               $thumb = $handler->getTransform(
                                                        $this, $thumbPath, $thumbUrl, $params );
                                                $thumb->setStoragePath( $thumbPath );
                                                break;
@@ -937,7 +938,7 @@ abstract class File {
 
                        // Actually render the thumbnail...
                        wfProfileIn( __METHOD__ . '-doTransform' );
-                       $thumb = $this->handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $params );
+                       $thumb = $handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $params );
                        wfProfileOut( __METHOD__ . '-doTransform' );
                        $tmpFile->bind( $thumb ); // keep alive with $thumb
 
@@ -947,7 +948,7 @@ abstract class File {
                                $this->lastError = $thumb->toText();
                                // Ignore errors if requested
                                if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
-                                       $thumb = $this->handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $params );
+                                       $thumb = $handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $params );
                                }
                        } elseif ( $this->repo && $thumb->hasFile() && !$thumb->fileIsSource() ) {
                                // Copy the thumbnail from the file system into storage...
@@ -1246,6 +1247,18 @@ abstract class File {
                return $this->repo->getZonePath( 'thumb' ) . '/' . $this->getThumbRel( $suffix );
        }
 
+       /**
+        * Get the path of the transcoded directory, or a particular file if $suffix is specified
+        *
+        * @param $suffix bool|string if not false, the name of a media file
+        *
+        * @return string
+        */
+       function getTranscodedPath( $suffix = false ) {
+               $this->assertRepoDefined();
+               return $this->repo->getZonePath( 'transcoded' ) . '/' . $this->getThumbRel( $suffix );
+       }
+
        /**
         * Get the URL of the archive directory, or a particular file if $suffix is specified
         *
@@ -1287,22 +1300,45 @@ abstract class File {
        }
 
        /**
-        * Get the URL of the thumbnail directory, or a particular file if $suffix is specified
+        * Get the URL of the zone directory, or a particular file if $suffix is specified
         *
-        * @param $suffix bool|string if not false, the name of a thumbnail file
+        * @param $zone string name of requested zone
+        * @param $suffix bool|string if not false, the name of a file in zone
         *
         * @return string path
         */
-       function getThumbUrl( $suffix = false ) {
+       function getZoneUrl( $zone, $suffix = false ) {
                $this->assertRepoDefined();
                $ext = $this->getExtension();
-               $path = $this->repo->getZoneUrl( 'thumb', $ext ) . '/' . $this->getUrlRel();
+               $path = $this->repo->getZoneUrl( $zone, $ext ) . '/' . $this->getUrlRel();
                if ( $suffix !== false ) {
                        $path .= '/' . rawurlencode( $suffix );
                }
                return $path;
        }
 
+       /**
+        * Get the URL of the thumbnail directory, or a particular file if $suffix is specified
+        *
+        * @param $suffix bool|string if not false, the name of a thumbnail file
+        *
+        * @return string path
+        */
+       function getThumbUrl( $suffix = false ) {
+               return $this->getZoneUrl( 'thumb', $suffix );
+       }
+
+       /**
+        * Get the URL of the transcoded directory, or a particular file if $suffix is specified
+        *
+        * @param $suffix bool|string if not false, the name of a media file
+        *
+        * @return string path
+        */
+       function getTranscodedUrl( $suffix = false ) {
+               return $this->getZoneUrl( 'transcoded', $suffix );
+       }
+
        /**
         * Get the public zone virtual URL for a current version source file
         *
@@ -1365,7 +1401,7 @@ abstract class File {
         * @throws MWException
         */
        function readOnlyError() {
-               throw new MWException( get_class($this) . ': write operations are not supported' );
+               throw new MWException( get_class( $this ) . ': write operations are not supported' );
        }
 
        /**
@@ -1378,8 +1414,12 @@ abstract class File {
         * @param $copyStatus string
         * @param $source string
         * @param $watch bool
+        * @param $timestamp string|bool
+        * @param $user User object or null to use $wgUser
+        * @return bool
+        * @throws MWException
         */
-       function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '', $watch = false ) {
+       function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '', $watch = false, $timestamp = false, User $user = null ) {
                $this->readOnlyError();
        }
 
@@ -1499,9 +1539,9 @@ abstract class File {
         * @param $target Title New file name
         * @return FileRepoStatus object.
         */
-        function move( $target ) {
+       function move( $target ) {
                $this->readOnlyError();
-        }
+       }
 
        /**
         * Delete all versions of the file.
@@ -1626,15 +1666,15 @@ abstract class File {
                $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgLang->getCode() );
                if ( $renderUrl ) {
                        if ( $this->repo->descriptionCacheExpiry > 0 ) {
-                               wfDebug("Attempting to get the description from cache...");
+                               wfDebug( "Attempting to get the description from cache..." );
                                $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', $wgLang->getCode(),
                                                                        $this->getName() );
-                               $obj = $wgMemc->get($key);
-                               if ($obj) {
-                                       wfDebug("success!\n");
+                               $obj = $wgMemc->get( $key );
+                               if ( $obj ) {
+                                       wfDebug( "success!\n" );
                                        return $obj;
                                }
-                               wfDebug("miss\n");
+                               wfDebug( "miss\n" );
                        }
                        wfDebug( "Fetching shared description from $renderUrl\n" );
                        $res = Http::get( $renderUrl );
@@ -1720,7 +1760,7 @@ abstract class File {
         * @return array
         */
        static function getPropsFromPath( $path, $ext = true ) {
-               wfDebug( __METHOD__.": Getting file info for $path\n" );
+               wfDebug( __METHOD__ . ": Getting file info for $path\n" );
                wfDeprecated( __METHOD__, '1.19' );
 
                $fsFile = new FSFile( $path );
index 5648261..84e0df6 100644 (file)
@@ -189,7 +189,7 @@ class ForeignAPIFile extends File {
         * @param string $method
         * @return int|null|string
         */
-       public function getUser( $method='text' ) {
+       public function getUser( $method = 'text' ) {
                return isset( $this->mInfo['user'] ) ? strval( $this->mInfo['user'] ) : null;
        }
 
@@ -256,7 +256,7 @@ class ForeignAPIFile extends File {
         */
        function getThumbPath( $suffix = '' ) {
                if ( $this->repo->canCacheThumbs() ) {
-                       $path = $this->repo->getZonePath('thumb') . '/' . $this->getHashPath( $this->getName() );
+                       $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath( $this->getName() );
                        if ( $suffix ) {
                                $path = $path . $suffix . '/';
                        }
@@ -293,7 +293,7 @@ class ForeignAPIFile extends File {
                global $wgMemc, $wgContLang;
 
                $url = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgContLang->getCode() );
-               $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', md5($url) );
+               $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', md5( $url ) );
 
                $wgMemc->delete( $key );
        }
index a03df85..610f556 100644 (file)
@@ -58,6 +58,7 @@ class ForeignDBFile extends LocalFile {
         * @param $srcPath String
         * @param $flags int
         * @param $options Array
+        * @return \FileRepoStatus
         * @throws MWException
         */
        function publish( $srcPath, $flags = 0, array $options = array() ) {
@@ -72,16 +73,19 @@ class ForeignDBFile extends LocalFile {
         * @param $source string
         * @param $watch bool
         * @param $timestamp bool|string
+        * @param $user User object or null to use $wgUser
+        * @return bool
         * @throws MWException
         */
        function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '',
-               $watch = false, $timestamp = false ) {
+               $watch = false, $timestamp = false, User $user = null ) {
                $this->readOnlyError();
        }
 
        /**
         * @param $versions array
         * @param $unsuppress bool
+        * @return \FileRepoStatus
         * @throws MWException
         */
        function restore( $versions = array(), $unsuppress = false ) {
@@ -91,6 +95,7 @@ class ForeignDBFile extends LocalFile {
        /**
         * @param $reason string
         * @param $suppress bool
+        * @return \FileRepoStatus
         * @throws MWException
         */
        function delete( $reason, $suppress = false ) {
@@ -99,6 +104,7 @@ class ForeignDBFile extends LocalFile {
 
        /**
         * @param $target Title
+        * @return \FileRepoStatus
         * @throws MWException
         */
        function move( $target ) {
index 9babe5a..11eab1e 100644 (file)
@@ -24,7 +24,7 @@
 /**
  * Bump this number when serialized cache records may be incompatible.
  */
-define( 'MW_FILE_VERSION', 8 );
+define( 'MW_FILE_VERSION', 9 );
 
 /**
  * Class to represent a local file in the wiki's own database
@@ -36,7 +36,7 @@ define( 'MW_FILE_VERSION', 8 );
  * never name a file class explictly outside of the repo class. Instead use the
  * repo's factory functions to generate file objects, for example:
  *
- * RepoGroup::singleton()->getLocalRepo()->newFile($title);
+ * RepoGroup::singleton()->getLocalRepo()->newFile( $title );
  *
  * The convenience functions wfLocalFile() and wfFindFile() should be sufficient
  * in most cases.
@@ -67,9 +67,11 @@ class LocalFile extends File {
                $sha1,             # SHA-1 base 36 content hash
                $user, $user_text, # User, who uploaded the file
                $description,      # Description of current revision of the file
-               $dataLoaded,       # Whether or not all this has been loaded from the database (loadFromXxx)
+               $dataLoaded,       # Whether or not core data has been loaded from the database (loadFromXxx)
+               $extraDataLoaded,  # Whether or not lazy-loaded data has been loaded from the database
                $upgraded,         # Whether the row was upgraded on load
                $locked,           # True if the image row is locked
+               $lockedOwnTrx,     # True if the image row is locked with a lock initiated transaction
                $missing,          # True if file is not present in file system. Not to be cached in memcached
                $deleted;          # Bitfield akin to rev_deleted
 
@@ -82,6 +84,8 @@ class LocalFile extends File {
 
        protected $repoClass = 'LocalRepo';
 
+       const LOAD_ALL = 1; // integer; load all the lazy fields too (like metadata)
+
        /**
         * Create a LocalFile from a title
         * Do not call this except from inside a repo class.
@@ -175,6 +179,7 @@ class LocalFile extends File {
                $this->historyLine = 0;
                $this->historyRes = null;
                $this->dataLoaded = false;
+               $this->extraDataLoaded = false;
 
                $this->assertRepoDefined();
                $this->assertTitleDefined();
@@ -200,6 +205,7 @@ class LocalFile extends File {
 
                wfProfileIn( __METHOD__ );
                $this->dataLoaded = false;
+               $this->extraDataLoaded = false;
                $key = $this->getCacheKey();
 
                if ( !$key ) {
@@ -210,13 +216,17 @@ class LocalFile extends File {
                $cachedValues = $wgMemc->get( $key );
 
                // Check if the key existed and belongs to this version of MediaWiki
-               if ( isset( $cachedValues['version'] ) && ( $cachedValues['version'] == MW_FILE_VERSION ) ) {
+               if ( isset( $cachedValues['version'] ) && $cachedValues['version'] == MW_FILE_VERSION ) {
                        wfDebug( "Pulling file metadata from cache key $key\n" );
                        $this->fileExists = $cachedValues['fileExists'];
                        if ( $this->fileExists ) {
                                $this->setProps( $cachedValues );
                        }
                        $this->dataLoaded = true;
+                       $this->extraDataLoaded = true;
+                       foreach ( $this->getLazyCacheFields( '' ) as $field ) {
+                               $this->extraDataLoaded = $this->extraDataLoaded && isset( $cachedValues[$field] );
+                       }
                }
 
                if ( $this->dataLoaded ) {
@@ -252,7 +262,17 @@ class LocalFile extends File {
                        }
                }
 
-               $wgMemc->set( $key, $cache, 60 * 60 * 24 * 7 ); // A week
+               // Strip off excessive entries from the subset of fields that can become large.
+               // If the cache value gets to large it will not fit in memcached and nothing will
+               // get cached at all, causing master queries for any file access.
+               foreach ( $this->getLazyCacheFields( '' ) as $field ) {
+                       if ( isset( $cache[$field] ) && strlen( $cache[$field] ) > 100*1024 ) {
+                               unset( $cache[$field] ); // don't let the value get too big
+                       }
+               }
+
+               // Cache presence for 1 week and negatives for 1 day
+               $wgMemc->set( $key, $cache, $this->fileExists ? 86400 * 7 : 86400 );
        }
 
        /**
@@ -287,6 +307,28 @@ class LocalFile extends File {
                return $results[$prefix];
        }
 
+       /**
+        * @return array
+        */
+       function getLazyCacheFields( $prefix = 'img_' ) {
+               static $fields = array( 'metadata' );
+               static $results = array();
+
+               if ( $prefix == '' ) {
+                       return $fields;
+               }
+
+               if ( !isset( $results[$prefix] ) ) {
+                       $prefixedFields = array();
+                       foreach ( $fields as $field ) {
+                               $prefixedFields[] = $prefix . $field;
+                       }
+                       $results[$prefix] = $prefixedFields;
+               }
+
+               return $results[$prefix];
+       }
+
        /**
         * Load file metadata from the DB
         */
@@ -297,9 +339,9 @@ class LocalFile extends File {
 
                # Unconditionally set loaded=true, we don't want the accessors constantly rechecking
                $this->dataLoaded = true;
+               $this->extraDataLoaded = true;
 
                $dbr = $this->repo->getMasterDB();
-
                $row = $dbr->selectRow( 'image', $this->getCacheFields( 'img_' ),
                        array( 'img_name' => $this->getName() ), $fname );
 
@@ -313,27 +355,70 @@ class LocalFile extends File {
        }
 
        /**
-        * Decode a row from the database (either object or array) to an array
-        * with timestamps and MIME types decoded, and the field prefix removed.
-        * @param $row
+        * Load lazy file metadata from the DB.
+        * This covers fields that are sometimes not cached.
+        */
+       protected function loadExtraFromDB() {
+               # Polymorphic function name to distinguish foreign and local fetches
+               $fname = get_class( $this ) . '::' . __FUNCTION__;
+               wfProfileIn( $fname );
+
+               # Unconditionally set loaded=true, we don't want the accessors constantly rechecking
+               $this->extraDataLoaded = true;
+
+               $dbr = $this->repo->getSlaveDB();
+               // In theory the file could have just been renamed/deleted...oh well
+               $row = $dbr->selectRow( 'image', $this->getLazyCacheFields( 'img_' ),
+                       array( 'img_name' => $this->getName() ), $fname );
+
+               if ( !$row ) { // fallback to master
+                       $dbr = $this->repo->getMasterDB();
+                       $row = $dbr->selectRow( 'image', $this->getLazyCacheFields( 'img_' ),
+                               array( 'img_name' => $this->getName() ), $fname );
+               }
+
+               if ( $row ) {
+                       foreach ( $this->unprefixRow( $row, 'img_' ) as $name => $value ) {
+                               $this->$name = $value;
+                       }
+               } else {
+                       throw new MWException( "Could not find data for image '{$this->getName()}'." );
+               }
+
+               wfProfileOut( $fname );
+       }
+
+       /**
+        * @param Row $row
         * @param $prefix string
-        * @throws MWException
-        * @return array
+        * @return Array
         */
-       function decodeRow( $row, $prefix = 'img_' ) {
+       protected function unprefixRow( $row, $prefix = 'img_' ) {
                $array = (array)$row;
                $prefixLength = strlen( $prefix );
 
                // Sanity check prefix once
                if ( substr( key( $array ), 0, $prefixLength ) !== $prefix ) {
-                       throw new MWException( __METHOD__ .  ': incorrect $prefix parameter' );
+                       throw new MWException( __METHOD__ . ': incorrect $prefix parameter' );
                }
 
                $decoded = array();
-
                foreach ( $array as $name => $value ) {
                        $decoded[substr( $name, $prefixLength )] = $value;
                }
+               return $decoded;
+       }
+
+       /**
+        * Decode a row from the database (either object or array) to an array
+        * with timestamps and MIME types decoded, and the field prefix removed.
+        * @param $row
+        * @param $prefix string
+        * @throws MWException
+        * @return array
+        */
+       function decodeRow( $row, $prefix = 'img_' ) {
+               $decoded = $this->unprefixRow( $row, $prefix );
 
                $decoded['timestamp'] = wfTimestamp( TS_MW, $decoded['timestamp'] );
 
@@ -357,6 +442,8 @@ class LocalFile extends File {
         */
        function loadFromRow( $row, $prefix = 'img_' ) {
                $this->dataLoaded = true;
+               $this->extraDataLoaded = true;
+
                $array = $this->decodeRow( $row, $prefix );
 
                foreach ( $array as $name => $value ) {
@@ -369,8 +456,9 @@ class LocalFile extends File {
 
        /**
         * Load file metadata from cache or DB, unless already loaded
+        * @param integer $flags
         */
-       function load() {
+       function load( $flags = 0 ) {
                if ( !$this->dataLoaded ) {
                        if ( !$this->loadFromCache() ) {
                                $this->loadFromDB();
@@ -378,6 +466,9 @@ class LocalFile extends File {
                        }
                        $this->dataLoaded = true;
                }
+               if ( ( $flags & self::LOAD_ALL ) && !$this->extraDataLoaded ) {
+                       $this->loadExtraFromDB();
+               }
        }
 
        /**
@@ -397,7 +488,7 @@ class LocalFile extends File {
                } else {
                        $handler = $this->getHandler();
                        if ( $handler ) {
-                               $validity = $handler->isMetadataValid( $this, $this->metadata );
+                               $validity = $handler->isMetadataValid( $this, $this->getMetadata() );
                                if ( $validity === MediaHandler::METADATA_BAD
                                        || ( $validity === MediaHandler::METADATA_COMPATIBLE && $wgUpdateCompatibleMetadata )
                                ) {
@@ -464,6 +555,7 @@ class LocalFile extends File {
        /**
         * Set properties in this object to be equal to those given in the
         * associative array $info. Only cacheable fields can be set.
+        * All fields *must* be set in $info except for getLazyCacheFields().
         *
         * If 'mime' is given, it will be split into major_mime/minor_mime.
         * If major_mime/minor_mime are given, $this->mime will also be set.
@@ -570,7 +662,7 @@ class LocalFile extends File {
         * @return string
         */
        function getMetadata() {
-               $this->load();
+               $this->load( self::LOAD_ALL ); // large metadata is loaded in another step
                return $this->metadata;
        }
 
@@ -646,7 +738,7 @@ class LocalFile extends File {
                        // Directory where file should be
                        // This happened occasionally due to broken migration code in 1.5
                        // Rename to broken-*
-                       for ( $i = 0; $i < 100 ; $i++ ) {
+                       for ( $i = 0; $i < 100; $i++ ) {
                                $broken = $this->repo->getZonePath( 'public' ) . "/broken-$i-$thumbName";
                                if ( !file_exists( $broken ) ) {
                                        rename( $thumbPath, $broken );
@@ -810,7 +902,7 @@ class LocalFile extends File {
        protected function purgeThumbList( $dir, $files ) {
                $fileListDebug = strtr(
                        var_export( $files, true ),
-                       array("\n"=>'')
+                       array( "\n" => '' )
                );
                wfDebug( __METHOD__ . ": $fileListDebug\n" );
 
@@ -1028,20 +1120,25 @@ class LocalFile extends File {
         * @param $source string
         * @param $watch bool
         * @param $timestamp string|bool
+        * @param $user User object or null to use $wgUser
         * @return bool
         */
        function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '',
-               $watch = false, $timestamp = false )
+               $watch = false, $timestamp = false, User $user = null )
        {
+               if ( !$user ) {
+                       global $wgUser;
+                       $user = $wgUser;
+               }
+
                $pageText = SpecialUpload::getInitialPageText( $desc, $license, $copyStatus, $source );
 
-               if ( !$this->recordUpload2( $oldver, $desc, $pageText, false, $timestamp ) ) {
+               if ( !$this->recordUpload2( $oldver, $desc, $pageText, false, $timestamp, $user ) ) {
                        return false;
                }
 
                if ( $watch ) {
-                       global $wgUser;
-                       $wgUser->addWatch( $this->getTitle() );
+                       $user->addWatch( $this->getTitle() );
                }
                return true;
        }
@@ -1194,7 +1291,7 @@ class LocalFile extends File {
                                $log->getRcComment(),
                                false
                        );
-                       if (!is_null($nullRevision)) {
+                       if ( !is_null( $nullRevision ) ) {
                                $nullRevision->insertOn( $dbw );
 
                                wfRunHooks( 'NewRevisionFromEditComplete', array( $wikiPage, $nullRevision, $latest, $user ) );
@@ -1578,7 +1675,10 @@ class LocalFile extends File {
                $dbw = $this->repo->getMasterDB();
 
                if ( !$this->locked ) {
-                       $dbw->begin( __METHOD__ );
+                       if ( !$dbw->trxLevel() ) {
+                               $dbw->begin( __METHOD__ );
+                               $this->lockedOwnTrx = true;
+                       }
                        $this->locked++;
                }
 
@@ -1593,9 +1693,10 @@ class LocalFile extends File {
        function unlock() {
                if ( $this->locked ) {
                        --$this->locked;
-                       if ( !$this->locked ) {
+                       if ( !$this->locked && $this->lockedOwnTrx ) {
                                $dbw = $this->repo->getMasterDB();
                                $dbw->commit( __METHOD__ );
+                               $this->lockedOwnTrx = false;
                        }
                }
        }
@@ -1607,6 +1708,7 @@ class LocalFile extends File {
                $this->locked = false;
                $dbw = $this->repo->getMasterDB();
                $dbw->rollback( __METHOD__ );
+               $this->lockedOwnTrx = false;
        }
 
        /**
@@ -2037,7 +2139,9 @@ class LocalFileRestoreBatch {
                        $conditions[] = 'fa_id IN (' . $dbw->makeList( $this->ids ) . ')';
                }
 
-               $result = $dbw->select( 'filearchive', '*',
+               $result = $dbw->select(
+                       'filearchive',
+                       ArchivedFile::selectFields(),
                        $conditions,
                        __METHOD__,
                        array( 'ORDER BY' => 'fa_timestamp DESC' )
@@ -2289,7 +2393,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|void
+        * @return FileRepoStatus
         */
        function cleanup() {
                if ( !$this->cleanupBatch ) {
index 40d7dca..4f27c8d 100644 (file)
@@ -42,7 +42,7 @@ class OldLocalFile extends LocalFile {
        static function newFromTitle( $title, $repo, $time = null ) {
                # The null default value is only here to avoid an E_STRICT
                if ( $time === null ) {
-                       throw new MWException( __METHOD__.' got null for $time parameter' );
+                       throw new MWException( __METHOD__ . ' got null for $time parameter' );
                }
                return new self( $title, $repo, $time, null );
        }
@@ -132,7 +132,7 @@ class OldLocalFile extends LocalFile {
                $this->requestedTime = $time;
                $this->archive_name = $archiveName;
                if ( is_null( $time ) && is_null( $archiveName ) ) {
-                       throw new MWException( __METHOD__.': must specify at least one of $time or $archiveName' );
+                       throw new MWException( __METHOD__ . ': must specify at least one of $time or $archiveName' );
                }
        }
 
@@ -164,18 +164,19 @@ class OldLocalFile extends LocalFile {
         * @return bool
         */
        function isVisible() {
-               return $this->exists() && !$this->isDeleted(File::DELETED_FILE);
+               return $this->exists() && !$this->isDeleted( File::DELETED_FILE );
        }
 
        function loadFromDB() {
                wfProfileIn( __METHOD__ );
+
                $this->dataLoaded = true;
                $dbr = $this->repo->getSlaveDB();
                $conds = array( 'oi_name' => $this->getName() );
                if ( is_null( $this->requestedTime ) ) {
                        $conds['oi_archive_name'] = $this->archive_name;
                } else {
-                       $conds[] = 'oi_timestamp = ' . $dbr->addQuotes( $dbr->timestamp( $this->requestedTime ) );
+                       $conds['oi_timestamp'] = $dbr->timestamp( $this->requestedTime );
                }
                $row = $dbr->selectRow( 'oldimage', $this->getCacheFields( 'oi_' ),
                        $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) );
@@ -184,6 +185,42 @@ class OldLocalFile extends LocalFile {
                } else {
                        $this->fileExists = false;
                }
+
+               wfProfileOut( __METHOD__ );
+       }
+
+       /**
+        * Load lazy file metadata from the DB
+        */
+       protected function loadExtraFromDB() {
+               wfProfileIn( __METHOD__ );
+
+               $this->extraDataLoaded = true;
+               $dbr = $this->repo->getSlaveDB();
+               $conds = array( 'oi_name' => $this->getName() );
+               if ( is_null( $this->requestedTime ) ) {
+                       $conds['oi_archive_name'] = $this->archive_name;
+               } else {
+                       $conds['oi_timestamp'] = $dbr->timestamp( $this->requestedTime );
+               }
+               // In theory the file could have just been renamed/deleted...oh well
+               $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ),
+                       $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) );
+
+               if ( !$row ) { // fallback to master
+                       $dbr = $this->repo->getMasterDB();
+                       $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ),
+                               $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) );
+               }
+
+               if ( $row ) {
+                       foreach ( $this->unprefixRow( $row, 'oi_' ) as $name => $value ) {
+                               $this->$name = $value;
+                       }
+               } else {
+                       throw new MWException( "Could not find data for image '{$this->archive_name}'." );
+               }
+
                wfProfileOut( __METHOD__ );
        }
 
@@ -218,7 +255,7 @@ class OldLocalFile extends LocalFile {
 
                # Don't destroy file info of missing files
                if ( !$this->fileExists ) {
-                       wfDebug( __METHOD__.": file does not exist, aborting\n" );
+                       wfDebug( __METHOD__ . ": file does not exist, aborting\n" );
                        wfProfileOut( __METHOD__ );
                        return;
                }
@@ -226,7 +263,7 @@ class OldLocalFile extends LocalFile {
                $dbw = $this->repo->getMasterDB();
                list( $major, $minor ) = self::splitMime( $this->mime );
 
-               wfDebug(__METHOD__.': upgrading '.$this->archive_name." to the current schema\n");
+               wfDebug( __METHOD__ . ': upgrading ' . $this->archive_name . " to the current schema\n" );
                $dbw->update( 'oldimage',
                        array(
                                'oi_size'       => $this->size, // sanity
index 698d1eb..9a7f653 100644 (file)
@@ -71,7 +71,7 @@ class UnregisteredLocalFile extends File {
         */
        function __construct( $title = false, $repo = false, $path = false, $mime = false ) {
                if ( !( $title && $repo ) && !$path ) {
-                       throw new MWException( __METHOD__.': not enough parameters, must specify title and repo, or a full path' );
+                       throw new MWException( __METHOD__ . ': not enough parameters, must specify title and repo, or a full path' );
                }
                if ( $title instanceof Title ) {
                        $this->title = File::normalizeTitle( $title, 'exception' );
index 38b4a82..75e55f1 100644 (file)
@@ -193,7 +193,7 @@ class CliInstaller extends Installer {
 
        public function envCheckPath( ) {
                if ( !$this->specifiedScriptPath ) {
-                       $this->showMessage( 'config-no-cli-uri', $this->getVar("wgScriptPath") );
+                       $this->showMessage( 'config-no-cli-uri', $this->getVar( "wgScriptPath" ) );
                }
                return parent::envCheckPath();
        }
index 75ede23..10d23fb 100644 (file)
@@ -62,12 +62,12 @@ abstract class DatabaseInstaller {
        /**
         * Return the internal name, e.g. 'mysql', or 'sqlite'.
         */
-       public abstract function getName();
+       abstract public function getName();
 
        /**
         * @return bool Returns true if the client library is compiled in.
         */
-       public abstract function isCompiled();
+       abstract public function isCompiled();
 
        /**
         * Checks for installation prerequisites other than those checked by isCompiled()
@@ -85,7 +85,7 @@ abstract class DatabaseInstaller {
         *
         * If this is called, $this->parent can be assumed to be a WebInstaller.
         */
-       public abstract function getConnectForm();
+       abstract public function getConnectForm();
 
        /**
         * Set variables based on the request array, assuming it was submitted
@@ -96,7 +96,7 @@ abstract class DatabaseInstaller {
         *
         * @return Status
         */
-       public abstract function submitConnectForm();
+       abstract public function submitConnectForm();
 
        /**
         * Get HTML for a web form that retrieves settings used for installation.
@@ -127,7 +127,7 @@ abstract class DatabaseInstaller {
         *
         * @return Status
         */
-       public abstract function openConnection();
+       abstract public function openConnection();
 
        /**
         * Create the database and return a Status object indicating success or
@@ -135,7 +135,7 @@ abstract class DatabaseInstaller {
         *
         * @return Status
         */
-       public abstract function setupDatabase();
+       abstract public function setupDatabase();
 
        /**
         * Connect to the database using the administrative user/password currently
@@ -218,7 +218,7 @@ abstract class DatabaseInstaller {
         *
         * @return String
         */
-       public abstract function getLocalSettings();
+       abstract public function getLocalSettings();
 
        /**
         * Override this to provide DBMS-specific schema variables, to be
@@ -240,7 +240,7 @@ abstract class DatabaseInstaller {
                if ( $status->isOK() ) {
                        $status->value->setSchemaVars( $this->getSchemaVars() );
                } else {
-                       throw new MWException( __METHOD__.': unexpected DB connection error' );
+                       throw new MWException( __METHOD__ . ': unexpected DB connection error' );
                }
        }
 
@@ -252,7 +252,7 @@ abstract class DatabaseInstaller {
        public function enableLB() {
                $status = $this->getConnection();
                if ( !$status->isOK() ) {
-                       throw new MWException( __METHOD__.': unexpected DB connection error' );
+                       throw new MWException( __METHOD__ . ': unexpected DB connection error' );
                }
                LBFactory::setInstance( new LBFactory_Single( array(
                        'connection' => $status->value ) ) );
index ac3f7b6..746cd12 100644 (file)
@@ -451,7 +451,7 @@ abstract class DatabaseUpdater {
                $key = "updatelist-$version-" . time();
                $this->db->insert( 'updatelog',
                        array( 'ul_key' => $key, 'ul_value' => serialize( $updates ) ),
-                        __METHOD__ );
+                       __METHOD__ );
                $this->db->setFlag( DBO_DDLMODE );
        }
 
@@ -575,7 +575,7 @@ abstract class DatabaseUpdater {
         *
         * @return Array
         */
-       protected abstract function getCoreUpdateList();
+       abstract protected function getCoreUpdateList();
 
        /**
         * Append an SQL fragment to the open file handle.
@@ -633,7 +633,7 @@ abstract class DatabaseUpdater {
                } else {
                        $this->db->sourceFile( $path );
                }
-               $this->output( "done.\n" );
+               $this->output( "done.\n" );
                return true;
        }
 
index 9a389dd..e2fb735 100644 (file)
@@ -44,9 +44,9 @@ class InstallDocFormatter {
                $text = preg_replace( '/^\t\t/m', '::', $text );
                $text = preg_replace( '/^\t/m', ':', $text );
                // turn (bug nnnn) into links
-               $text = preg_replace_callback('/bug (\d+)/', array( $this, 'replaceBugLinks' ), $text );
+               $text = preg_replace_callback( '/bug (\d+)/', array( $this, 'replaceBugLinks' ), $text );
                // add links to manual to every global variable mentioned
-               $text = preg_replace_callback('/(\$wg[a-z0-9_]+)/i', array( $this, 'replaceConfigLinks' ), $text );
+               $text = preg_replace_callback( '/(\$wg[a-z0-9_]+)/i', array( $this, 'replaceConfigLinks' ), $text );
                return $text;
        }
 
index 6ed8dd3..ecee84c 100644 (file)
@@ -17,19 +17,19 @@ $messages['en'] = array(
        'config-information'              => 'Information',
        'config-localsettings-upgrade'    => "A <code>LocalSettings.php</code> file has been detected.
 To upgrade this installation, please enter the value of <code>\$wgUpgradeKey</code> in the box below.
-You will find it in LocalSettings.php.",
-       'config-localsettings-cli-upgrade'    => 'A LocalSettings.php file has been detected.
-To upgrade this installation, please run update.php instead',
+You will find it in <code>LocalSettings.php</code>.",
+       'config-localsettings-cli-upgrade'    => 'A <code>LocalSettings.php</code> file has been detected.
+To upgrade this installation, please run <code>update.php</code> instead',
        'config-localsettings-key'        => 'Upgrade key:',
        'config-localsettings-badkey'     => 'The key you provided is incorrect.',
        'config-upgrade-key-missing'      => 'An existing installation of MediaWiki has been detected.
-To upgrade this installation, please put the following line at the bottom of your LocalSettings.php:
+To upgrade this installation, please put the following line at the bottom of your <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'The existing LocalSettings.php appears to be incomplete.
+       'config-localsettings-incomplete' => 'The existing <code>LocalSettings.php</code> appears to be incomplete.
 The $1 variable is not set.
-Please change LocalSettings.php so that this variable is set, and click "Continue".',
-       'config-localsettings-connection-error' => 'An error was encountered when connecting to the database using the settings specified in LocalSettings.php or AdminSettings.php. Please fix these settings and try again.
+Please change <code>LocalSettings.php</code> so that this variable is set, and click "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'An error was encountered when connecting to the database using the settings specified in <code>LocalSettings.php</code> or <code>AdminSettings.php</code>. Please fix these settings and try again.
 
 $1',
        'config-session-error'            => 'Error starting session: $1',
@@ -163,7 +163,9 @@ Installation aborted.',
        'config-using531'                 => 'MediaWiki cannot be used with PHP $1 due to a bug involving reference parameters to <code>__call()</code>.
 Upgrade to PHP 5.3.2 or higher, or downgrade to PHP 5.3.0 to resolve this.
 Installation aborted.',
-       'config-suhosin-max-value-length' => "Suhosin is installed and limits the GET parameter length to $1 bytes. MediaWiki's ResourceLoader component will work around this limit, but that will degrade performance. If at all possible, you should set suhosin.get.max_value_length to 1024 or higher in php.ini , and set \$wgResourceLoaderMaxQueryLength to the same value in LocalSettings.php .",
+       'config-suhosin-max-value-length' => "Suhosin is installed and limits the GET parameter <code>length</code> to $1 bytes.
+MediaWiki's ResourceLoader component will work around this limit, but that will degrade performance.
+If at all possible, you should set <code>suhosin.get.max_value_length</code> to 1024 or higher in <code>php.ini</code>, and set <code>\$wgResourceLoaderMaxQueryLength</code> to the same value in <code>LocalSettings.php</code>.",
        'config-db-type'                  => 'Database type:',
        'config-db-host'                  => 'Database host:',
        'config-db-host-help'             => 'If your database server is on different server, enter the host name or IP address here.
@@ -249,7 +251,7 @@ If you do not see the database system you are trying to use listed below, then f
        'config-support-postgres'         => '* $1 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]). There may be some minor outstanding bugs, and it is not recommended for use in a production environment.',
        'config-support-sqlite'           => '* $1 is a lightweight database system which is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)',
        'config-support-oracle'           => '* $1 is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
-       'config-support-ibm_db2'          => '* $1 is a commercial enterprise database.',
+       'config-support-ibm_db2'          => '* $1 is a commercial enterprise database. ([http://www.php.net/manual/en/ibm-db2.installation.php How to compile PHP with IBM DB2 support])',
        'config-header-mysql'             => 'MySQL settings',
        'config-header-postgres'          => 'PostgreSQL settings',
        'config-header-sqlite'            => 'SQLite settings',
@@ -316,8 +318,8 @@ This is '''not recommended''' unless you are having problems with your wiki.",
        'config-upgrade-done-no-regenerate' => "Upgrade complete.
 
 You can now [$1 start using your wiki].",
-       'config-regenerate'               => 'Regenerate LocalSettings.php →',
-       'config-show-table-status'        => 'SHOW TABLE STATUS query failed!',
+       'config-regenerate'               => 'Regenerate <code>LocalSettings.php</code> →',
+       'config-show-table-status'        => '<code>SHOW TABLE STATUS</code> query failed!',
        'config-unknown-collation'        => "'''Warning:''' Database is using unrecognised collation.",
        'config-db-web-account'           => 'Database account for web access',
        'config-db-web-help'              => 'Select the username and password that the web server will use to connect to the database server, during ordinary operation of the wiki.',
@@ -548,7 +550,7 @@ $3
 '''Note''': If you do not do this now, this generated configuration file will not be available to you later if you exit the installation without downloading it.
 
 When that has been done, you can '''[$2 enter your wiki]'''.",
-       'config-download-localsettings' => 'Download LocalSettings.php',
+       'config-download-localsettings' => 'Download <code>LocalSettings.php</code>',
        'config-help' => 'help',
        'config-nofile'     => 'File "$1" could not be found. Has it been deleted?',
        'mainpagetext'      => "'''MediaWiki has been successfully installed.'''",
@@ -583,7 +585,7 @@ $messages['qqq'] = array(
        'config-title' => 'Parameters:
 * $1 is the version of MediaWiki that is being installed.',
        'config-information' => '{{Identical|Information}}',
-       'config-localsettings-cli-upgrade' => 'Do not translate the <code>LocalSettings.php</code> and the <code>update.php</code> parts.',
+       'config-localsettings-cli-upgrade' => '{{doc-important|Do not translate the <code>LocalSettings.php</code> and the <code>update.php</code> parts.}}',
        'config-session-error' => 'Parameters:
 * $1 is the error that was encountered with the session.',
        'config-session-expired' => 'Parameters:
@@ -601,15 +603,17 @@ $messages['qqq'] = array(
 * $1 is the version of PHP that has been installed.',
        'config-unicode-pure-php-warning' => 'PECL is the name of a group producing standard pieces of software for PHP, and intl is the name of their library handling some aspects of internationalization.',
        'config-unicode-update-warning' => "ICU is a body producing standard software tools for support of Unicode and other internationalization aspects. This message warns the system administrator installing MediaWiki that the server's software is not up-to-date and MediaWiki will have problems handling some characters.",
-       'config-no-db' => 'Do not translate: <code>./configure --with-mysql</code>.
-<br />
-Do not translate: <code>php5-mysql</code>.
-
+       'config-no-db' => '{{doc-important|Do not translate "<code>./configure --with-mysql</code>" and "<code>php5-mysql</code>".}}
 Parameters:
 * $1 is comma separated list of database types supported by MediaWiki.',
        'config-no-fts3' => 'A "[[:wikipedia:Front and back ends|backend]]" is a system or component that ordinary users don\'t interact with directly and don\'t need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are "system" or "service", or (depending on context and language) even leave it untranslated.',
+       'config-magic-quotes-runtime' => '{{Related|Config-fatal}}',
+       'config-magic-quotes-sybase' => '{{Related|Config-fatal}}',
+       'config-mbstring' => '{{Related|Config-fatal}}',
+       'config-ze1' => '{{Related|Config-fatal}}',
        'config-pcre' => 'PCRE is an initialism for "Perl-compatible regular expression". Perl is programming language whose [[:w:regular expression|regular expression]] syntax is popular and used in other languages using a library called PCRE.',
-       'config-pcre-no-utf8' => "PCRE is a name of a programmers' library for supporting regular expressions. It can probably be translated without change.",
+       'config-pcre-no-utf8' => "PCRE is a name of a programmers' library for supporting regular expressions. It can probably be translated without change.
+{{Related|Config-fatal}}",
        'config-memory-raised' => 'Parameters:
 * $1 is the configured <code>memory_limit</code>.
 * $2 is the value to which <code>memory_limit</code> was raised.',
@@ -625,7 +629,8 @@ Add dir="ltr" to the <nowiki><code></nowiki> for right-to-left languages.',
        'config-no-cli-uri' => 'Parameters:
 * $1 is the default value for scriptpath.',
        'config-no-cli-uploads-check' => 'CLI = [[w:Command-line interface|command-line interface]] (i.e. the installer runs as a command-line script, not using HTML interface via an internet browser)',
-       'config-suhosin-max-value-length' => 'Message shown when PHP parameter suhosin.get.max_value_length is between 0 and 1023 (that max value is hard set in MediaWiki software)',
+       'config-suhosin-max-value-length' => '{{doc-important|Do not translate "length", "suhosin.get.max_value_length", "php.ini", "$wgResourceLoaderMaxQueryLength" and "LocalSettings.php".}}
+Message shown when PHP parameter <code>suhosin.get.max_value_length</code> is between 0 and 1023 (that max value is hard set in MediaWiki software).',
        'config-db-host-help' => '{{doc-singularthey}}',
        'config-db-host-oracle' => 'TNS = [[:wikipedia:Transparent Network Substrate|Transparent Network Substrate]] (<== wikipedia link)',
        'config-db-wiki-settings' => 'This is more acurate: "Enter identifying or distinguishing data for this wiki" since a MySQL database can host tables of several wikis.',
@@ -647,6 +652,7 @@ Add dir="ltr" to the <nowiki><code></nowiki> for right-to-left languages.',
 * $1 - a link to the SQLite home page having the anchor text "SQLite".',
        'config-support-oracle' => 'Parameters:
 * $1 - a link to the Oracle home page, the anchor text of which is "Oracle".',
+       'config-support-ibm_db2' => 'Used in the DBConnect step of the installer, explaining what is the ibm_db2 database',
        'config-connection-error' => '$1 is the external error from the database, such as "DB connection error: Access denied for user \'dba\'@\'localhost\' (using password: YES) (localhost)."
 
 If you\'re translating this message to a right-to-left language, consider writing <nowiki><div dir="ltr">$1.</div></nowiki>. (When the bidi features for HTML5 will be implemented in the browsers, it will probably be a good idea to write it as <nowiki><div dir="auto">$1.</div></nowiki>.)',
@@ -654,7 +660,7 @@ If you\'re translating this message to a right-to-left language, consider writin
        'config-sqlite-dir-unwritable' => 'webserver refers to a software like Apache or Lighttpd.',
        'config-can-upgrade' => 'Parameters:
 * $1 - Version or Revision indicator.',
-       'config-show-table-status' => '{{doc-important|"SHOW TABLE STATUS" is a MySQL command. Do not translate this.}}',
+       'config-show-table-status' => '{{doc-important|"<code>SHOW TABLE STATUS</code>" is a MySQL command. Do not translate this.}}',
        'config-db-web-account-same' => 'checkbox label',
        'config-db-web-create' => 'checkbox label',
        'config-ns-generic' => '{{Identical|Project}}',
@@ -662,6 +668,7 @@ If you\'re translating this message to a right-to-left language, consider writin
        'config-admin-password' => '{{Identical|Password}}',
        'config-admin-email' => '{{Identical|E-mail address}}',
        'config-subscribe' => 'Used as label for the installer checkbox',
+       'config-subscribe-help' => '"Low-volume" in this context means that there will be few e-mails to that mailing list per time period.',
        'config-profile-help' => 'Messages referenced:
 * {{msg-mw|config-profile-wiki}}
 * {{msg-mw|config-profile-no-anon}}
@@ -669,10 +676,13 @@ If you\'re translating this message to a right-to-left language, consider writin
 * {{msg-mw|config-profile-private}}',
        'config-upload-help' => 'The word "mode" here refers to the access rights given to various user groups when attempting to create and store files and/or subdiretories in the said directory on the server. It also refers to the <code>mode</code> command used to maipulate said right mask under Unix, Linux, and similar operating systems. A less operating-system-centric translation is fine.',
        'config-logo-help' => '',
-       'config-cc-not-chosen' => 'Do not translate the <code>"proceed".</code> part.
-This message refers to a block of HTML being embedded into the installer page. It comes from the Creative Commons Web site. The block is in the English language. It is a scripted license chooser. When an individual license has been selected, it asks you to klick "proceed" so as to return to the MediaWiki installer page.',
+       'config-cc-not-chosen' => '{{doc-important|Do not translate the "<code>proceed</code>" part.}}
+This message refers to a block of HTML being embedded into the installer page. It comes from the Creative Commons Web site. The block is in the English language. It is a scripted license chooser. When an individual license has been selected, it asks you to click "proceed" so as to return to the MediaWiki installer page.',
+       'config-memcached-servers' => '{{doc-important|Do not translate "memcached".}}
+{{Identical|Memcached server}}',
        'config-extensions' => '{{Identical|Extension}}',
        'config-install-step-done' => '{{Identical|Done}}',
+       'config-install-step-failed' => '{{Identical|Failed}}',
        'config-install-database' => '*{{msg-mw|Config-install-database}}
 *{{msg-mw|Config-install-tables}}
 *{{msg-mw|Config-install-schema}}
@@ -878,8 +888,8 @@ U gebruik tans $2.',
        'config-upgrade-done-no-regenerate' => 'Opgradering is voltooi.
 
 U kan nou [$1 u wiki gebruik].',
-       'config-regenerate' => 'Herskep LocalSettings.php →',
-       'config-show-table-status' => 'Die uitvoer van SHOW TABLE STATUS het gefaal!',
+       'config-regenerate' => 'Herskep <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Die uitvoer van <code>SHOW TABLE STATUS</code> het gefaal!',
        'config-db-web-account' => 'Databasisgebruiker vir toegang tot die web',
        'config-mysql-engine' => 'Stoor-enjin:',
        'config-mysql-innodb' => 'InnoDB',
@@ -904,7 +914,7 @@ U kan nou [$1 u wiki gebruik].',
        'config-admin-email' => 'E-posadres:',
        'config-optional-continue' => 'Vra my meer vrae.',
        'config-optional-skip' => 'Ek is reeds verveeld, installeer maar net die wiki.',
-       'config-profile-wiki' => 'Tradisionele wiki',
+       'config-profile-wiki' => 'Tradisionele wiki', # Fuzzy
        'config-profile-no-anon' => 'Skep van gebruiker is verpligtend',
        'config-profile-fishbowl' => 'Slegs vir gemagtigde redaksie',
        'config-profile-private' => 'Privaat wiki',
@@ -961,7 +971,7 @@ U sal dit moet [$1 aflaai] en dit in die hoofgids van u wiki-installasie plaas;
 '''Let wel''': As u dit nie nou doen nie, sal die gegenereerde konfigurasielêer nie later meer beskikbaar wees nadat u die installasie afgesluit het nie.
 
 As dit gedoen is, kan u '''[u $2 wiki besoek]'''.", # Fuzzy
-       'config-download-localsettings' => 'Laai LocalSettings.php af',
+       'config-download-localsettings' => 'Laai <code>LocalSettings.php</code> af',
        'config-help' => 'hulp',
        'mainpagetext' => "'''MediaWiki is suksesvol geïnstalleer.'''",
        'mainpagedocfooter' => "Konsulteer '''[//meta.wikimedia.org/wiki/Help:Contents User's Guide]''' vir inligting oor hoe om die wikisagteware te gebruik.
@@ -969,7 +979,7 @@ As dit gedoen is, kan u '''[u $2 wiki besoek]'''.", # Fuzzy
 == Hoe om te Begin ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]", # Fuzzy
 );
 
 /** Gheg Albanian (Gegë)
@@ -1120,16 +1130,63 @@ $messages['as'] = array(
 );
 
 /** Asturian (asturianu)
+ * @author Xuacu
  */
 $messages['ast'] = array(
+       'config-desc' => "L'instalador pa MediaWiki",
+       'config-title' => 'Instalación de MediaWiki $1',
+       'config-information' => 'Información',
+       'config-localsettings-upgrade' => "Detectose un ficheru <code>LocalSettings.php</code>.
+P'anovar esta instalación, escriba'l valor de
+<code>\$wgUpgradeKey</code> nel cuadru d'abaxo.
+Alcontraralu en <code>LocalSettings.php</code>.",
+       'config-localsettings-cli-upgrade' => "Deteutose un ficheru <code>LocalSettings.php</code>.
+P'anovar esta instalación, execute <code>update.php</code>",
+       'config-localsettings-key' => "Clave d'anovamientu:",
+       'config-localsettings-badkey' => 'La clave que dio ye incorreuta.',
+       'config-upgrade-key-missing' => "Deteutose una instalación esistente de MediaWiki.
+P'anovar esta instalación, ponga la llinia siguiente al final del ficheru <code>LocalSettings.php</code>:
+
+$1",
+       'config-localsettings-incomplete' => 'Paez que\'l ficheru <code>LocalSettings.php</code> esistente ta incompletu.
+La variable $1 nun ta definida.
+Camude\'l ficheru <code>LocalSettings.php</code> pa qu\'esta variable quede definida y calque "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Alcontrose un error al conectar cola base de datos usando la configuración especificada en <code>LocalSettings.php</code> o <code>AdminSettings.php</code>. Corrixa esta configuración y vuelva a intentalo.
+
+$1',
+       'config-your-language' => 'La so llingua:',
+       'config-your-language-help' => "Seleicione la llingua a emplegar nel procesu d'instalación.",
+       'config-wiki-language' => 'Llingua de la wiki:',
+       'config-wiki-language-help' => "Seleicione la llingua que s'usará preferentemente na wiki.",
+       'config-back' => '← Atrás',
+       'config-continue' => 'Siguir →',
+       'config-page-language' => 'Llingua',
+       'config-page-welcome' => '¡Bienveníu a MediaWiki!',
+       'config-page-dbconnect' => 'Conectar cola base de datos',
+       'config-page-upgrade' => 'Anovar instalación esistente',
+       'config-page-dbsettings' => 'Configuración de la base de datos',
+       'config-page-name' => 'Nome',
+       'config-page-options' => 'Opciones',
+       'config-page-install' => 'Instalar',
+       'config-page-complete' => '¡Completo!',
+       'config-page-restart' => 'Reaniciar la instalación',
+       'config-page-readme' => 'Llei-me',
+       'config-page-releasenotes' => 'Notes de la versión',
+       'config-page-copying' => 'Copiar',
+       'config-page-upgradedoc' => 'Anovando',
+       'config-page-existingwiki' => 'Wiki esistente',
+       'config-download-localsettings' => 'Descargar <code>LocalSettings.php</code>',
+       'config-help' => 'Ayuda',
+       'config-nofile' => 'Nun pudo atopase\'l ficheru "$1". ¿Desaniciose?',
        'mainpagetext' => "'''MediaWiki instalóse correchamente.'''",
-       'mainpagedocfooter' => "Visita la [//meta.wikimedia.org/wiki/Help:Contents Guía d'usuariu] pa saber cómo usar esti software wiki.
+       'mainpagedocfooter' => 'Visita la [//meta.wikimedia.org/wiki/Help:Contents Guía del usuariu] pa saber cómo usar esti software wiki.
 
 == Empecipiando ==
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Llista de les opciones de configuración]
 * [//www.mediawiki.org/wiki/Manual:FAQ FAQ de MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de les ediciones de MediaWiki]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de les ediciones de MediaWiki]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources Llocaliza MediaWiki na to llingua]',
 );
 
 /** Kotava (Kotava)
@@ -1242,6 +1299,7 @@ $messages['be'] = array(
  * @author Jim-by
  * @author Wizardist
  * @author Zedlik
+ * @author 아라
  */
 $messages['be-tarask'] = array(
        'config-desc' => 'Праграма ўсталяваньня MediaWiki',
@@ -1249,19 +1307,19 @@ $messages['be-tarask'] = array(
        'config-information' => 'Інфармацыя',
        'config-localsettings-upgrade' => 'Выяўлены файл <code>LocalSettings.php</code>.
 Каб абнавіць гэтае усталяваньне, калі ласка, увядзіце значэньне <code>$wgUpgradeKey</code> у полі ніжэй.
-Яго можна знайсьці ў LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Быў знойдзены файл LocalSettings.php.
-Каб зьмяніць гэтае ўсталяваньне, калі ласка, запусьціце update.php',
+Яго можна знайсьці ў <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Быў знойдзены файл <code>LocalSettings.php</code>.
+Каб зьмяніць гэтае ўсталяваньне, калі ласка, запусьціце <code>update.php</code>',
        'config-localsettings-key' => 'Ключ паляпшэньня:',
        'config-localsettings-badkey' => 'Пададзены Вамі ключ зьяўляецца няслушным',
        'config-upgrade-key-missing' => 'Выяўленае існуючае ўсталяваньне MediaWiki.
-Каб абнавіць гэтае ўсталяваньне, калі ласка, устаўце наступны радок у канец Вашага LocalSettings.php:
+Каб абнавіць гэтае ўсталяваньне, калі ласка, устаўце наступны радок у канец Вашага <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Выглядае, што існуючы LocalSettings.php зьяўляецца няпоўным.
+       'config-localsettings-incomplete' => 'Выглядае, што існуючы <code>LocalSettings.php</code> зьяўляецца няпоўным.
 Не ўстаноўленая пераменная $1.
-Калі ласка, зьмяніце LocalSettings.php так, каб была ўстаноўленая гэтая пераменная, і націсьніце «Працягваць».',
-       'config-localsettings-connection-error' => 'Адбылася памылка падчас злучэньня з базай зьвестак з выкарыстаньнем наладаў, пазначаных у LocalSettings.php ці AdminSettings.php. Калі ласка, выпраўце гэтыя налады і паспрабуйце зноў.
+Калі ласка, зьмяніце <code>LocalSettings.php</code> так, каб была ўстаноўленая гэтая пераменная, і націсьніце «{{int:Config-continue}}».',
+       'config-localsettings-connection-error' => 'Адбылася памылка падчас злучэньня з базай зьвестак з выкарыстаньнем наладаў, пазначаных у <code>LocalSettings.php</code> ці <code>AdminSettings.php</code>. Калі ласка, выпраўце гэтыя налады і паспрабуйце зноў.
 
 $1',
        'config-session-error' => 'Памылка стварэньня сэсіі: $1',
@@ -1395,7 +1453,9 @@ MediaWiki патрабуе падтрымкі UTF-8 для слушнай пра
        'config-using531' => 'PHP $1 не сумяшчальнае з MediaWiki з-за памылкі ў перадачы парамэтраў па ўказальніку да <code>__call()</code>.
 Абнавіце PHP да вэрсіі 5.3.2 ці болей позьняй, ці адкаціце да вэрсіі 5.3.0 каб гэта выправіць.
 Усталяваньне перарванае.',
-       'config-suhosin-max-value-length' => 'Suhosin усталяваны і абмяжоўвае даўжыню парамэтра GET у $1 {{PLURAL:$1|байт|байты|байтаў}}. ResourceLoader для MediaWiki будзе абходзіць гэтае абмежаваньне, што, аднак, адаб’ецца на хуткадзеяньні. Калі магчыма, варта ўстанавіць suhosin.get.max_value_length роўным 1024 ці больш у php.ini, а таксама ўстанавіць тое ж значэньне для $wgResourceLoaderMaxQueryLength у LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'Suhosin усталяваны і абмяжоўвае <code>даўжыню</code> парамэтра GET да $1 {{PLURAL:$1|байта|байтаў}}.
+ResourceLoader, складнік MediaWiki, будзе абходзіць гэтае абмежаваньне, што, адаб’ецца на прадукцыйнасьці.
+Калі магчыма, варта ўсталяваць у <code>php.ini</code> <code>suhosin.get.max_value_length</code> роўным 1024 ці больш, а таксама вызначыць тое ж значэньне для <code>$wgResourceLoaderMaxQueryLength</code> у LocalSettings.php.',
        'config-db-type' => 'Тып базы зьвестак:',
        'config-db-host' => 'Хост базы зьвестак:',
        'config-db-host-help' => 'Калі сэрвэр Вашай базы зьвестак знаходзіцца на іншым сэрвэры, увядзіце тут імя хоста ці IP-адрас.
@@ -1479,7 +1539,7 @@ $1
        'config-support-postgres' => '* $1 — вядомая сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL ([http://www.php.net/manual/en/pgsql.installation.php як кампіляваць PHP з падтрымкай PostgreSQL]). Яна можа ўтрымліваць дробныя памылкі, і не рэкамэндуецца выкарыстоўваць яе для працуючых праектаў.',
        'config-support-sqlite' => '* $1 — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([http://www.php.net/manual/en/pdo.installation.php як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)',
        'config-support-oracle' => '* $1 зьяўляецца камэрцыйнай прафэсійнай базай зьвестак. ([http://www.php.net/manual/en/oci8.installation.php Як скампіляваць PHP з падтрымкай OCI8])',
-       'config-support-ibm_db2' => '* $1 â\80\94 Ð±Ð°Ð·Ð° Ð·Ñ\8cвеÑ\81Ñ\82ак ÐºÐ°Ð¼Ñ\8dÑ\80Ñ\86Ñ\8bйнага Ð¿Ñ\80адпÑ\80Ñ\8bемÑ\81Ñ\82ва.',
+       'config-support-ibm_db2' => '* $1 â\80\94 Ð±Ð°Ð·Ð° Ð·Ñ\8cвеÑ\81Ñ\82ак Ð¼Ð°Ñ\88Ñ\82абÑ\83 Ð¿Ñ\80адпÑ\80Ñ\8bемÑ\81Ñ\82ва. ([http://www.php.net/manual/en/ibm-db2.installation.php Ð¯Ðº Ñ\81кампÑ\96лÑ\8fваÑ\86Ñ\8c PHP Ð· Ð¿Ð°Ð´Ñ\82Ñ\80Ñ\8bмкай IBM DB2])',
        'config-header-mysql' => 'Налады MySQL',
        'config-header-postgres' => 'Налады PostgreSQL',
        'config-header-sqlite' => 'Налады SQLite',
@@ -1546,8 +1606,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => 'Абнаўленьне скончанае.
 
 Цяпер Вы можаце [$1 пачаць працу з вікі].',
-       'config-regenerate' => 'Рэгенэраваць LocalSettings.php →',
-       'config-show-table-status' => "Запыт 'SHOW TABLE STATUS' не атрымаўся!",
+       'config-regenerate' => 'Рэгенэраваць <code>LocalSettings.php</code> →',
+       'config-show-table-status' => "Запыт '<code>SHOW TABLE STATUS</code>' не атрымаўся!",
        'config-unknown-collation' => "'''Папярэджаньне:''' база зьвестак выкарыстоўвае нераспазнанае супастаўленьне.",
        'config-db-web-account' => 'Рахунак базы зьвестак для вэб-доступу',
        'config-db-web-help' => 'Выберыце імя карыстальніка і пароль, які выкарыстоўваецца вэб-сэрвэрам для злучэньня з сэрвэрам базы зьвестак, падчас звычайных апэрацыяў вікі.',
@@ -1619,7 +1679,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => 'Задаць болей пытаньняў.',
        'config-optional-skip' => 'Хопіць, проста ўсталяваць вікі.',
        'config-profile' => 'Профіль правоў удзельніка:',
-       'config-profile-wiki' => 'ТÑ\80адÑ\8bÑ\86Ñ\8bйная вікі',
+       'config-profile-wiki' => 'Ð\90дкÑ\80Ñ\8bÑ\82ая вікі',
        'config-profile-no-anon' => 'Патрэбнае стварэньне рахунку',
        'config-profile-fishbowl' => 'Толькі для аўтарызаваных рэдактараў',
        'config-profile-private' => 'Прыватная вікі',
@@ -1635,7 +1695,7 @@ chmod a+w $3</pre>',
 Сцэнар '''{{int:config-profile-fishbowl}}''' дазваляе рэдагаваць зацьверджаным удзельнікам, але ўсе могуць праглядаць старонкі іх гісторыю.
 '''{{int:config-profile-private}}''' дазваляе праглядаць і рэдагаваць старонкі толькі зацьверджаным удзельнікам.
 
-Больш складаныя правы ўдзельнікаў даступныя пасьля ўсталяваньня, глядзіце [//www.mediawiki.org/wiki/Manual:User_rights адпаведную старонку дакумэнтацыі].",
+Больш складаныя правы ўдзельнікаў даступныя пасьля ўсталяваньня, глядзіце [//www.mediawiki.org/wiki/Manual:User_rights адпаведную старонку дакумэнтацыі].", # Fuzzy
        'config-license' => 'Аўтарскія правы і ліцэнзія:',
        'config-license-none' => 'Без інфармацыі пра ліцэнзію',
        'config-license-cc-by-sa' => 'Creative Commons Attribution Share Alike',
@@ -1720,7 +1780,7 @@ chmod a+w $3</pre>',
        'config-install-alreadydone' => "'''Папярэджаньне:''' здаецца, што Вы ўжо ўсталёўвалі MediaWiki і спрабуеце зрабіць гэтай зноў.
 Калі ласка, перайдзіце на наступную старонку.",
        'config-install-begin' => 'Пасьля націску кнопкі «{{int:config-continue}}» пачнецца ўсталяваньне MediaWiki.
-Калі Вы жадаеце што-небудзь зьмяніць, націсьніце кнопку «Вярнуцца».',
+Калі Вы жадаеце што-небудзь зьмяніць, націсьніце кнопку «Вярнуцца».', # Fuzzy
        'config-install-step-done' => 'зроблена',
        'config-install-step-failed' => 'не атрымалася',
        'config-install-extensions' => 'Уключаючы пашырэньні',
@@ -1776,7 +1836,7 @@ $3
 '''Заўвага''': калі Вы гэтага ня зробіце зараз, то створаны файл ня будзе даступны Вам потым, калі Вы выйдзеце з праграмы ўсталяваньня  без яго загрузкі.
 
 Калі Вы гэта зробіце, Вы можаце '''[$2 ўвайсьці ў Вашую вікі]'''.",
-       'config-download-localsettings' => 'Загрузіць LocalSettings.php',
+       'config-download-localsettings' => 'Загрузіць <code>LocalSettings.php</code>',
        'config-help' => 'дапамога',
        'config-nofile' => 'Файл «$1» ня знойдзены. Ці быў ён выдалены?',
        'mainpagetext' => "'''MediaWiki пасьпяхова ўсталяваная.'''",
@@ -1785,11 +1845,12 @@ $3
 == З чаго пачаць ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Сьпіс парамэтраў канфігурацыі]
 * [//www.mediawiki.org/wiki/Manual:FAQ Частыя пытаньні MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка паведамленьняў пра зьяўленьне новых вэрсіяў MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка паведамленьняў пра зьяўленьне новых вэрсіяў MediaWiki]', # Fuzzy
 );
 
 /** Bulgarian (български)
  * @author DCLXVI
+ * @author 아라
  */
 $messages['bg'] = array(
        'config-desc' => 'Инсталатор на МедияУики',
@@ -1797,19 +1858,19 @@ $messages['bg'] = array(
        'config-information' => 'Информация',
        'config-localsettings-upgrade' => 'Беше открит файл <code>LocalSettings.php</code>.
 За надграждане на съществуващата инсталация, необходимо е в кутията по-долу да се въведе стойността на <code>$wgUpgradeKey</code>.
-Тази информация е налична в LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Беше открит файл LocalSettings.php.
-За надграждане на наличната инсталация, необходимо е да се стартира update.php',
+Тази информация е налична в <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Беше открит файл <code>LocalSettings.php</code>.
+За надграждане на наличната инсталация, необходимо е да се стартира <code>update.php</code>',
        'config-localsettings-key' => 'Ключ за надграждане:',
        'config-localsettings-badkey' => 'Предоставеният ключ е неправилен.',
        'config-upgrade-key-missing' => 'Беше открита съществуваща инсталация на МедияУики.
-За надграждане на съществуващата инсталация, необходимо е да се постави следният ред в края на файла LocalSettings.php:
+За надграждане на съществуващата инсталация, необходимо е да се постави следният ред в края на файла <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Съществуващият файл LocalSettings.php изглежда непълен.
+       'config-localsettings-incomplete' => 'Съществуващият файл <code>LocalSettings.php</code> изглежда непълен.
 Променливата $1 не е зададена.
-Необходимо е да се редактира файлът LocalSettings.php и да се зададе променливата, след което да се натисне "Продължаване".',
-       'config-localsettings-connection-error' => 'Възникна грешка при свързване с базата от данни чрез данните, посочени в LocalSettings.php или AdminSettings.php. Необходимо е да се коригират тези настройки преди повторен опит за свързване.
+Необходимо е да се редактира файлът <code>LocalSettings.php</code> и да се зададе променливата, след което да се натисне „{{int:Config-continue}}“.',
+       'config-localsettings-connection-error' => 'Възникна грешка при свързване с базата от данни чрез данните, посочени в <code>LocalSettings.php</code> или <code>AdminSettings.php</code>. Необходимо е да се коригират тези настройки преди повторен опит за свързване.
 
 $1',
        'config-session-error' => 'Грешка при създаване на сесия: $1',
@@ -1937,7 +1998,7 @@ $1
        'config-using531' => 'МедияУики не може да се използва с PHP $1 заради проблем с референтните параметри за <code>__call()</code>.
 За разрешаване на този проблем е необходимо да се обнови до PHP 5.3.2 или по-нова версия или да се инсталира по-стара версия, напр. PHP 5.3.0.
 Инсталацията беше прекратена.',
-       'config-suhosin-max-value-length' => 'Suhosin е инсталиран и ограничава дължината на параметъра GET на $1 байта. Компонентът на МедияУики ResourceLoader ще може да пренебрегне частично това ограничение, но това ще намали производителността. По възможност е препоръчително да се настрои suhosin.get.max_value_length на 1024 или по-голяма стойност в php.ini и в LocalSettings.php да се настрои $wgResourceLoaderMaxQueryLength със същата стойност.',
+       'config-suhosin-max-value-length' => 'Suhosin е инсталиран и ограничава дължината на параметъра GET на $1 байта. Компонентът на МедияУики ResourceLoader ще може да пренебрегне частично това ограничение, но това ще намали производителността. По възможност е препоръчително да се настрои <code>suhosin.get.max_value_length</code> на 1024 или по-голяма стойност в <code>php.ini</code> и в LocalSettings.php да се настрои <code>$wgResourceLoaderMaxQueryLength</code> със същата стойност.', # Fuzzy
        'config-db-type' => 'Тип на базата от данни:',
        'config-db-host' => 'Хост на базата от данни:',
        'config-db-host-help' => 'Ако базата от данни е на друг сървър, в кутията се въвежда името на хоста или IP адреса.
@@ -2004,7 +2065,7 @@ $1
        'config-support-postgres' => '* $1 е популярна система за бази от данни с отворен изходен код, която е алтернатива на MySQL ([http://www.php.net/manual/en/pgsql.installation.php как се компилира PHP с поддръжка на PostgreSQL]). Възможно е все още да има грешки, затова не се препоръчва да се използва в общодостъпна среда.',
        'config-support-sqlite' => '* $1 е лека система за база от данни, която е много добре поддържана. ([http://www.php.net/manual/en/pdo.installation.php Как се компилира PHP с поддръжка на SQLite], използва PDO)',
        'config-support-oracle' => '* $1 е комерсиална корпоративна база от данни. ([http://www.php.net/manual/en/oci8.installation.php Как се компилира PHP с поддръжка на OCI8])',
-       'config-support-ibm_db2' => '* $1 е комерсиална фирмена база от данни.',
+       'config-support-ibm_db2' => '* $1 е комерсиална фирмена база от данни. ([http://www.php.net/manual/en/ibm-db2.installation.php Как се компилира PHP с поддръжка на IBM DB2])',
        'config-header-mysql' => 'Настройки за MySQL',
        'config-header-postgres' => 'Настройки за PostgreSQL',
        'config-header-sqlite' => 'Настройки за SQLite',
@@ -2071,8 +2132,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => 'Обновяването приключи.
 
 Вече е възможно [$1 да използвате уикито].',
-       'config-regenerate' => 'Създаване на LocalSettings.php →',
-       'config-show-table-status' => 'Заявката SHOW TABLE STATUS не сполучи!',
+       'config-regenerate' => 'Създаване на <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Заявката <code>SHOW TABLE STATUS</code> не сполучи!',
        'config-unknown-collation' => "'''Предупреждение:''' Базата от данни използва неразпозната колация.",
        'config-db-web-account' => 'Сметка за уеб достъп до базата от данни',
        'config-db-web-help' => 'Избиране на потребителско име и парола, които уеб сървърът ще използва да се свързва с базата от данни при обичайната работа на уикито.',
@@ -2143,7 +2204,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => 'Задаване на допълнителни въпроси.',
        'config-optional-skip' => 'Достатъчно, инсталиране на уикито.',
        'config-profile' => 'Профил на потребителските права:',
-       'config-profile-wiki' => 'ТÑ\80адиÑ\86ионно уики',
+       'config-profile-wiki' => 'Ð\9eÑ\82воÑ\80ено уики',
        'config-profile-no-anon' => 'Необходимо е създаване на сметка',
        'config-profile-fishbowl' => 'Само одобрени редактори',
        'config-profile-private' => 'Затворено уики',
@@ -2159,7 +2220,7 @@ chmod a+w $3</pre>',
 Уики, което е '''{{int:config-profile-fishbowl}}''' позволява на всички да преглеждат страниците, но само предварително одобрени редактори могат да редактират съдържанието.
 В '''{{int:config-profile-private}}''' само предварително одобрени потребители могат да четат и редактират съдържанието.
 
-Детайлно обяснение на конфигурациите на потребителските права е достъпно след инсталацията в [//www.mediawiki.org/wiki/Manual:User_rights Наръчника за потребителски права].",
+Детайлно обяснение на конфигурациите на потребителските права е достъпно след инсталацията в [//www.mediawiki.org/wiki/Manual:User_rights Наръчника за потребителски права].", # Fuzzy
        'config-license' => 'Авторски права и лиценз:',
        'config-license-none' => 'Без лиценз',
        'config-license-cc-by-sa' => 'Криейтив Комънс Признание-Споделяне на споделеното',
@@ -2242,8 +2303,8 @@ chmod a+w $3</pre>',
 Възможно е те да изискват допълнително конфигуриране, но сега могат да бъдат включени.',
        'config-install-alreadydone' => "'''Предупреждение:''' Изглежда вече сте инсталирали МедияУики и се опитвате да го инсталирате отново.
 Продължете към следващата страница.",
-       'config-install-begin' => 'Инсталацията на МедияУики ще започне след натискане на бутона "{{int:config-continue}}".
\90ко Ð¶ÐµÐ»Ð°ÐµÑ\82е Ð´Ð° Ð½Ð°Ð¿Ñ\80авиÑ\82е Ð¿Ñ\80омени, Ð½Ð°Ñ\82иÑ\81неÑ\82е Ð\92Ñ\80Ñ\8aÑ\89ане.',
+       'config-install-begin' => 'Инсталацията на МедияУики ще започне след натискане на бутона „{{int:config-continue}}“.
\92 Ñ\81лÑ\83Ñ\87ай, Ñ\87е Ðµ Ð½ÐµÐ¾Ð±Ñ\85одимо Ð´Ð° Ñ\81е Ð½Ð°Ð¿Ñ\80авÑ\8fÑ\82 Ð¿Ñ\80омени, Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° Ñ\81е Ð±Ñ\83Ñ\82она â\80\9e{{int:config-back}}â\80\9c.',
        'config-install-step-done' => 'готово',
        'config-install-step-failed' => 'неуспешно',
        'config-install-extensions' => 'Добавяне на разширенията',
@@ -2298,16 +2359,17 @@ $3
 '''Забележка''': Ако това не бъде извършено сега, генерираният конфигурационен файл няма да е достъпен на по-късен етап ако не бъде изтеглен сега или инсталацията приключи без изтеглянето му.
 
 Когато файлът вече е в основната директория, '''[$2 уикито ще е достъпно на този адрес]'''.",
-       'config-download-localsettings' => 'Изтегляне на LocalSettings.php',
+       'config-download-localsettings' => 'Изтегляне на <code>LocalSettings.php</code>',
        'config-help' => 'помощ',
        'config-nofile' => 'Файлът „$1“ не може да бъде открит. Да не е бил изтрит?',
        'mainpagetext' => "'''Уикито беше успешно инсталирано.'''",
-       'mainpagedocfooter' => 'Разгледайте [//meta.wikimedia.org/wiki/Help:Contents ръководството] за подробна информация относно използването на софтуера.
+       'mainpagedocfooter' => 'РазгледайÑ\82е [//meta.wikimedia.org/wiki/Help:Contents Ñ\80Ñ\8aководÑ\81Ñ\82воÑ\82о] Ð·Ð° Ð¿Ð¾Ð´Ñ\80обна Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\8f Ð¾Ñ\82ноÑ\81но Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½ÐµÑ\82о Ð½Ð° Ñ\83ики Ñ\81оÑ\84Ñ\82Ñ\83еÑ\80а.
 
 == Първи стъпки ==
-* [//www.mediawiki.org/wiki/Manual:Configuration_settings Ð\9aонÑ\84игÑ\83Ñ\80аÑ\86ионни Ð½Ð°Ñ\81Ñ\82Ñ\80ойки]
+* [//www.mediawiki.org/wiki/Manual:Configuration_settings Ð\9dаÑ\81Ñ\82Ñ\80ойки Ð·Ð° ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80иÑ\80ане]
 * [//www.mediawiki.org/wiki/Manual:FAQ ЧЗВ за МедияУики]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Пощенски списък относно нови версии на МедияУики]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Пощенски списък относно нови версии на МедияУики]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources Локализиране на МедияУики]',
 );
 
 /** Banjar (Bahasa Banjar)
@@ -2457,6 +2519,7 @@ $messages['bpy'] = array(
  * @author Fulup
  * @author Gwendal
  * @author Y-M D
+ * @author 아라
  */
 $messages['br'] = array(
        'config-desc' => 'Poellad staliañ MediaWIki',
@@ -2464,19 +2527,19 @@ $messages['br'] = array(
        'config-information' => 'Titouroù',
        'config-localsettings-upgrade' => 'Kavet ez eus bet ur restr <code>LocalSettings.php</code>.
 Evit hizivaat ar staliadur-se, merkit an talvoud <code>$wgUpgradeKey</code> er voest dindan.
-E gavout a rit e LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Dinoet ez eus bet ur restr LocalSettings.php.
-Evit lakaat ar staliadur-mañ a-live, implijit update.php e plas',
+E gavout a rit e <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Dinoet ez eus bet ur restr <code>LocalSettings.php</code>.
+Evit lakaat ar staliadur-mañ a-live, implijit <code>update.php</code> e plas',
        'config-localsettings-key' => "Alc'hwez hizivaat :",
        'config-localsettings-badkey' => "Direizh eo an alc'hwez merket ganeoc'h",
        'config-upgrade-key-missing' => 'Kavet ez eus bet ur staliadur kent eus MediaWiki.
-Evit hizivaat ar staliadur-se, ouzhpennit al linenn da-heul e traoñ ho restr LocalSettings.php:
+Evit hizivaat ar staliadur-se, ouzhpennit al linenn da-heul e traoñ ho restr <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => "Diglok e seblant bezañ ar restr LocalSettings.php zo anezhi dija.
+       'config-localsettings-incomplete' => "Diglok e seblant bezañ ar restr <code>LocalSettings.php</code> zo anezhi dija.
 An argemmenn $1 n'eo ket termenet.
-Kemmit LocalSettings.php evit ma vo termenet an argemmenn-se, ha klikit war « Kenderc'hel ».",
-       'config-localsettings-connection-error' => "C'hoarvezet ez eus ur fazi en ur gevreañ ouzh an diaz roadennoù oc'h implijout an arventennoù diferet e LocalSettings.php pe AdminSettings.php. Reizhit an arventennoù-se hag esaeit en-dro.
+Kemmit <code>LocalSettings.php</code> evit ma vo termenet an argemmenn-se, ha klikit war « {{int:Config-continue}} ».",
+       'config-localsettings-connection-error' => "C'hoarvezet ez eus ur fazi en ur gevreañ ouzh an diaz roadennoù oc'h implijout an arventennoù diferet e <code>LocalSettings.php</code> pe <code>AdminSettings.php</code>. Reizhit an arventennoù-se hag esaeit en-dro.
 
 $1",
        'config-session-error' => "Fazi e-ser loc'hañ an dalc'h : $1",
@@ -2655,7 +2718,7 @@ Ma ne welit ket amañ dindan ar reizhiad diaz titouroù a fell deoc'h ober ganti
        'config-support-postgres' => "* Ur reizhiad diaz titouroù brudet ha digor eo $1. Gallout a ra ober evit MySQL ([http://www.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL]). Gallout a ra bezañ un nebeud drein bihan enni ha n'eo ket erbedet he implijout en un endro produiñ.",
        'config-support-sqlite' => "* $1 zo ur reizhiad diaz titouroù skañv skoret eus ar c'hentañ. ([http://www.php.net/manual/en/pdo.installation.php Penaos kempunañ PHP gant skor SQLite], implijout a ra PDO)",
        'config-support-oracle' => '* $1 zo un diaz titouroù kenwerzhel. ([http://www.php.net/manual/en/oci8.installation.php Penaos kempunañ PHP gant skor OCI8])',
-       'config-support-ibm_db2' => '* Un diaz titouroù evit embregerezhioù kenwerzhel eo $1.',
+       'config-support-ibm_db2' => '* Un diaz titouroù evit embregerezhioù kenwerzhel eo $1.', # Fuzzy
        'config-header-mysql' => 'Arventennoù MySQL',
        'config-header-postgres' => 'Arventennoù PostgreSQL',
        'config-header-sqlite' => 'Arventennoù SQLite',
@@ -2697,8 +2760,8 @@ Da hizivaat anezho da VediaWiki $1, klikañ war '''Kenderc'hel'''.",
        'config-upgrade-done-no-regenerate' => 'Hizivadenn kaset da benn.
 
 Gallout a rit [$1 kregiñ da implijout ho wiki].',
-       'config-regenerate' => 'Adgenel LocalSettings.php →',
-       'config-show-table-status' => "C'hwitet ar reked SHOW TABLE STATUS !",
+       'config-regenerate' => 'Adgenel <code>LocalSettings.php</code> →',
+       'config-show-table-status' => "C'hwitet ar reked <code>SHOW TABLE STATUS</code> !",
        'config-unknown-collation' => "'''Diwallit :''' Emañ an diaz roadennoù o renkañ an traoù diouzh un urzh lizherennek dianav.",
        'config-db-web-account' => 'Kont an diaz roadennoù evit ar voned Kenrouedad',
        'config-db-web-help' => 'Diuzañ an anv implijer hag ar ger-tremen a vo implijet gant ar servijer web evit kevreañ ouzh ar servijer diaz roadennoù pa vez ar wiki o vont en-dro war ar pemdez.',
@@ -2745,7 +2808,7 @@ Gellout a rit tremen ar c'hefluniadur nevez ha staliañ ar wiki war-eeun.",
        'config-optional-continue' => "Sevel muioc'h a goulennoù ouzhin.",
        'config-optional-skip' => 'Aet on skuizh, staliañ ar wiki hepken.',
        'config-profile' => 'Profil ar gwirioù implijer :',
-       'config-profile-wiki' => 'Wiki hengounel',
+       'config-profile-wiki' => 'Wiki hengounel', # Fuzzy
        'config-profile-no-anon' => 'Krouidigezh ur gont ret',
        'config-profile-fishbowl' => 'Embanner aotreet hepken',
        'config-profile-private' => 'Wiki prevez',
@@ -2802,7 +2865,7 @@ Marteze e vo ezhomm kefluniañ pelloc'h met gallout a rit o gweredekaat bremañ.
        'config-install-alreadydone' => "'''Diwallit''': Staliet hoc'h eus MediaWiki dija war a seblant hag emaoc'h o klask e staliañ c'hoazh.
 Kit d'ar bajenn war-lerc'h, mar plij.",
        'config-install-begin' => 'Pa vo bet pouezet ganeoc\'h war "{{int:config-continue}}"  e krogo staliadur MediaWiki.
-Pouezit war Kent mar fell deoc\'h cheñch tra pe dra.',
+Pouezit war Kent mar fell deoc\'h cheñch tra pe dra.', # Fuzzy
        'config-install-step-done' => 'graet',
        'config-install-step-failed' => "c'hwitet",
        'config-install-extensions' => 'En ur gontañ an astennoù',
@@ -2830,7 +2893,7 @@ Gwiriit hag-eñ e c'hall an implijer « $1 » skrivañ er brastres « $2 ».",
        'config-install-mainpage' => "O krouiñ ar bajenn bennañ gant un endalc'had dre ziouer",
        'config-install-extension-tables' => 'O krouiñ taolennoù evit an astennoù gweredekaet',
        'config-install-mainpage-failed' => "Ne c'haller ket ensoc'hañ ar bajenn bennañ: $1",
-       'config-download-localsettings' => 'Pellgargañ LocalSettings.php',
+       'config-download-localsettings' => 'Pellgargañ <code>LocalSettings.php</code>',
        'config-help' => 'skoazell',
        'mainpagetext' => "'''Meziant MediaWiki staliet.'''",
        'mainpagedocfooter' => "Sellit ouzh [//meta.wikimedia.org/wiki/Help:Contents Sturlevr an implijerien] evit gouzout hiroc'h war an doare da implijout ar meziant wiki.
@@ -2839,7 +2902,7 @@ Gwiriit hag-eñ e c'hall an implijer « $1 » skrivañ er brastres « $2 ».",
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]", # Fuzzy
 );
 
 /** Bosnian (bosanski)
@@ -2851,7 +2914,7 @@ $messages['bs'] = array(
        'config-information' => 'Informacija',
        'config-localsettings-upgrade' => 'Otkrivena je datoteka <code>LocalSettings.php</code>.
 Da biste unaprijedili vaš softver, molimo vas upišite vrijednost od <code>$wgUpgradeKey</code> u okvir ispod.
-Naći ćete ga u LocalSettings.php.',
+Naći ćete ga u <code>LocalSettings.php</code>.',
        'config-localsettings-key' => 'Ključ za nadgradnju:',
        'config-session-error' => 'Greška pri pokretanju sesije: $1',
        'config-no-session' => 'Vaši podaci sesije su izgubljeni!
@@ -2924,15 +2987,28 @@ Ovo '''nije preporučeno''' osim ako nemate problema s vašom wiki.",
 == Početak ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Lista postavki]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki najčešće postavljana pitanja]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista E-Mail adresa MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista E-Mail adresa MediaWiki]', # Fuzzy
 );
 
 /** Catalan (català)
+ * @author Pitort
  * @author පසිඳු කාවින්ද
  */
 $messages['ca'] = array(
        'config-page-language' => 'Llengua',
        'config-page-name' => 'Nom',
+       'config-charset-mysql5' => 'MySQL 4.1/5.0 UTF-8',
+       'config-mysql-innodb' => 'InnoDB',
+       'config-mysql-myisam' => 'MyISAM',
+       'config-mysql-utf8' => 'UTF-8',
+       'config-ns-generic' => 'Projecte',
+       'config-admin-password' => 'Contrasenya:',
+       'config-profile-wiki' => 'Wiki públic',
+       'config-profile-private' => 'Wiki privat',
+       'config-license-pd' => 'Domini públic',
+       'config-upload-deleted' => 'Directori pels arxius suprimits:',
+       'config-advanced-settings' => 'Configuració avançada',
+       'config-extensions' => 'Extensions',
        'mainpagetext' => "'''El programari del MediaWiki s'ha instaŀlat correctament.'''",
        'mainpagedocfooter' => "Consulteu la [//meta.wikimedia.org/wiki/Help:Contents Guia d'Usuari] per a més informació sobre com utilitzar-lo.
 
@@ -2940,7 +3016,7 @@ $messages['ca'] = array(
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Llista de característiques configurables]
 * [//www.mediawiki.org/wiki/Manual:FAQ PMF del MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de correu (''listserv'') per a anuncis del MediaWiki]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de correu (''listserv'') per a anuncis del MediaWiki]", # Fuzzy
 );
 
 /** Chechen (нохчийн)
@@ -3025,25 +3101,26 @@ $messages['crh-latn'] = array(
 /** Czech (česky)
  * @author Danny B.
  * @author Mormegil
+ * @author 아라
  */
 $messages['cs'] = array(
        'config-desc' => 'Instalační program pro MediaWiki',
        'config-title' => 'Instalace MediaWiki $1',
        'config-information' => 'Informace',
        'config-localsettings-upgrade' => 'Byl nalezen soubor <code>LocalSettings.php</code>.
-Pokud chcete stávající instalaci aktualizovat, zadejte hodnotu <code>$wgUpgradeKey</code>, kterou naleznete v souboru LocalSettings.php, do následujícího rámečku.',
-       'config-localsettings-cli-upgrade' => 'Byl detekován soubor <code>LocalSettings.php</code>
+Pokud chcete stávající instalaci aktualizovat, zadejte hodnotu <code>$wgUpgradeKey</code>, kterou naleznete v souboru <code>LocalSettings.php</code>, do následujícího rámečku.',
+       'config-localsettings-cli-upgrade' => 'Byl detekován soubor <code><code>LocalSettings.php</code></code>
 Pro aktualizaci spusťte místo instalace skript <code>update.php</code>.',
        'config-localsettings-key' => 'Klíč pro aktualizaci:',
        'config-localsettings-badkey' => 'Zadaný klíč je nesprávný.',
        'config-upgrade-key-missing' => 'Byla detekována existující instalace MediaWiki.
-Pokud ji chcete aktualizovat, přidejte následující řádku na konec souboru LocalSettings.php:
+Pokud ji chcete aktualizovat, přidejte následující řádku na konec souboru <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Existující soubor LocalSettings.php vypadá neúplný.
+       'config-localsettings-incomplete' => 'Existující soubor <code>LocalSettings.php</code> vypadá neúplný.
 Není nastavena proměnná $1.
-Upravte soubor LocalSettings.php tak, aby tuto proměnnou obsahoval, a klikněte na „Pokračovat“.',
-       'config-localsettings-connection-error' => 'Při připojování k databázi s využitím nastavení uvedených v LocalSettings.php nebo AdminSettings.php došlo k chybě. Opravte tato nastavení a zkuste to znovu.
+Upravte soubor <code>LocalSettings.php</code> tak, aby tuto proměnnou obsahoval, a klikněte na „{{int:Config-continue}}“.',
+       'config-localsettings-connection-error' => 'Při připojování k databázi s využitím nastavení uvedených v <code>LocalSettings.php</code> nebo <code>AdminSettings.php</code> došlo k chybě. Opravte tato nastavení a zkuste to znovu.
 
 $1',
        'config-session-error' => 'Nepodařilo se inicializovat relaci: $1',
@@ -3175,7 +3252,9 @@ Instalace přerušena.',
        'config-using531' => 'MediaWiki nelze používat na PHP $1 kvůli chybě při předávání parametrů odkazem do <code>__call()</code>.
 Pro vyřešení upgradujte na PHP 5.3.2 nebo vyšší nebo downgradujte na PHP 5.3.0.
 Instalace přerušena.',
-       'config-suhosin-max-value-length' => 'Je nainstalován Suhosin, který omezuje délku parametrů GET na $1 bajtů. Komponenta ResourceLoader z MediaWiki dokáže s tímto omezením pracovat, ale sníží to výkon. Pokud to je alespoň trochu možné, měli byste v php.ini nastavit suhosin.get.max_value_length na 1024 nebo vyšší a na stejnou hodnotu nastavit v LocalSettings.php proměnnou $wgResourceLoaderMaxQueryLength.',
+       'config-suhosin-max-value-length' => 'Je nainstalován Suhosin, který omezuje délku parametrů GET na $1 bajtů.
+Komponenta ResourceLoader z MediaWiki dokáže s tímto omezením pracovat, ale sníží to výkon.
+Pokud to je alespoň trochu možné, měli byste v <code>php.ini</code> nastavit <code>suhosin.get.max_value_length</code> na 1024 nebo vyšší a na stejnou hodnotu nastavit v <code>LocalSettings.php</code> proměnnou <code>$wgResourceLoaderMaxQueryLength</code>.',
        'config-db-type' => 'Typ databáze:',
        'config-db-host' => 'Databázový server:',
        'config-db-host-help' => 'Pokud je váš databázový server na jiném počítači, zadejte zde jméno stroje nebo IP adresu.
@@ -3261,7 +3340,7 @@ Pokud v nabídce níže nevidíte databázový systém, který chcete použít,
        'config-support-postgres' => '* $1 je populární open-source 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]). Mohou se vyskytnout ještě nějaké menší chyby, použití v produkčním prostředí se nedoporučuje.',
        'config-support-sqlite' => '* $1 je velmi dobře podporovaný lehký 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-support-oracle' => '* $1 je komerční podniková databáze. ([http://www.php.net/manual/en/oci8.installation.php Jak přeložit PHP s podporou OCI8])',
-       'config-support-ibm_db2' => '* $1 je komerční podniková databáze.',
+       'config-support-ibm_db2' => '* $1 je komerční podniková databáze. ([http://www.php.net/manual/en/ibm-db2.installation.php Jak přeložit PHP s podporou IBM DB2])',
        'config-header-mysql' => 'Nastavení MySQL',
        'config-header-postgres' => 'Nastavení PostgreSQL',
        'config-header-sqlite' => 'Nastavení SQLite',
@@ -3328,8 +3407,8 @@ To se ale '''nedoporučuje''', pokud s wiki nemáte problémy.",
        'config-upgrade-done-no-regenerate' => 'Aktualizace byla dokončena.
 
 Svou wiki teď můžete [$1 začít používat].',
-       'config-regenerate' => 'Přegenerovat LocalSettings.php →',
-       'config-show-table-status' => 'Dotaz SHOW TABLE STATUS se nezdařil!',
+       'config-regenerate' => 'Přegenerovat <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Dotaz <code>SHOW TABLE STATUS</code> se nezdařil!',
        'config-unknown-collation' => "'''Upozornění:''' Databáze používá nerozpoznané řazení.",
        'config-db-web-account' => 'Databázový účet pro webový přístup',
        'config-db-web-help' => 'Zvolte uživatelské jméno a heslo, které bude webový server používat pro připojení k databázovému serveru při běžném provozu wiki.',
@@ -3401,7 +3480,7 @@ Zbývající konfiguraci už můžete přeskočit a nainstalovat wiki hned teď.
        'config-optional-continue' => 'Ptejte se mě dál.',
        'config-optional-skip' => 'Už mě to nudí, prostě nainstalujte wiki.',
        'config-profile' => 'Profil uživatelských práv:',
-       'config-profile-wiki' => 'Tradiční wiki',
+       'config-profile-wiki' => 'Otevřená wiki',
        'config-profile-no-anon' => 'Vyžadována registrace uživatelů',
        'config-profile-fishbowl' => 'Editace jen pro vybrané',
        'config-profile-private' => 'Soukromá wiki',
@@ -3411,7 +3490,7 @@ V MediaWiki můžete snadno kontrolovat poslední změny a vracet zpět libovoln
 Mnoho lidí však zjistilo, že je MediaWiki užitečné v širokém spektru rolí a někdy není snadné všechny přesvědčit o výhodách wikizvyklostí.
 Takže si můžete vybrat.
 
-'''{{int:config-profile-wiki}}''' dovoluje editovat všem, aniž by se museli přihlašovat.
+Model '''{{int:config-profile-wiki}}''' dovoluje editovat všem, aniž by se museli přihlašovat.
 Na wiki, kde je '''{{int:config-profile-no-anon}}''', se lépe řídí zodpovědnost, ale může to odradit náhodné přispěvatele.
 
 Profil '''{{int:config-profile-fishbowl}}''' umožňuje schváleným uživatelům editovat, ale veřejnost si může stránky prohlížet včetně jejich historie.
@@ -3502,7 +3581,7 @@ Mohou vyžadovat dodatečnou konfiguraci, ale teď je můžete povolit.',
        'config-install-alreadydone' => "'''Upozornění:''' Vypadá to, že jste MediaWiki již nainstalovali a teď se o to pokoušíte znovu.
 Pokračujte na další stránku.",
        'config-install-begin' => 'Stisknutím „{{int:config-continue}}“ spustíte instalaci MediaWiki.
-Pokud ještě chcete udělat nějaké změny, stiskněte tlačítko zpět.',
+Pokud ještě chcete udělat nějaké změny, stiskněte „{{int:config-back}}“.',
        'config-install-step-done' => 'hotovo',
        'config-install-step-failed' => 'selhaly',
        'config-install-extensions' => 'Vkládají se rozšíření',
@@ -3558,7 +3637,7 @@ $3
 '''Poznámka''': Pokud to neuděláte hned, tento vygenerovaný konfigurační soubor nebude později dostupný, pokud instalaci opustíte, aniž byste si ho stáhli.
 
 Až to dokončíte, můžete '''[$2 vstoupit do své wiki]'''.",
-       'config-download-localsettings' => 'Stáhnout LocalSettings.php',
+       'config-download-localsettings' => 'Stáhnout <code>LocalSettings.php</code>',
        'config-help' => 'nápověda',
        'config-nofile' => 'Soubor „$1“ nelze nalézt. Byl smazán?',
        'mainpagetext' => "'''MediaWiki byla úspěšně nainstalována.'''",
@@ -3568,7 +3647,8 @@ Až to dokončíte, můžete '''[$2 vstoupit do své wiki]'''.",
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Nastavení konfigurace]
 * [//www.mediawiki.org/wiki/Manual:FAQ Často kladené otázky o MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-mailová konference oznámení MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-mailová konference oznámení MediaWiki]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources Překlad MediaWiki do vašeho jazyka]',
 );
 
 /** Kashubian (kaszëbsczi)
@@ -3624,6 +3704,8 @@ $messages['da'] = array(
  * @author Rillke
  * @author The Evil IP address
  * @author Umherirrender
+ * @author Wikinaut
+ * @author 아라
  */
 $messages['de'] = array(
        'config-desc' => 'Das MediaWiki-Installationsprogramm',
@@ -3631,19 +3713,19 @@ $messages['de'] = array(
        'config-information' => 'Informationen',
        'config-localsettings-upgrade' => 'Eine Datei <code>LocalSettings.php</code> wurde gefunden.
 Um die vorhandene Installation aktualisieren zu können, muss der Wert des Parameters <code>$wgUpgradeKey</code> im folgenden Eingabefeld angegeben werden.
-Der Parameterwert befindet sich in der Datei LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Eine Datei <code>LocalSettings.php</code> wurde gefunden.
+Der Parameterwert befindet sich in der Datei <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Eine Datei <code><code>LocalSettings.php</code></code> wurde gefunden.
 Um die vorhandene Installation zu aktualisieren, muss die Datei <code>update.php</code> ausgeführt werden.',
        'config-localsettings-key' => 'Aktualisierungsschlüssel:',
        'config-localsettings-badkey' => 'Der angegebene Aktualisierungsschlüssel ist falsch.',
        'config-upgrade-key-missing' => 'Eine MediaWiki-Installation wurde gefunden.
-Um die vorhandene Installation aktualisieren zu können, muss die unten angegebene Codezeile in die Datei LocalSettings.php an deren Ende eingefügt werden:
+Um die vorhandene Installation aktualisieren zu können, muss die unten angegebene Codezeile in die Datei <code>LocalSettings.php</code> an deren Ende eingefügt werden:
 
 $1',
-       'config-localsettings-incomplete' => 'Die vorhandene Datei LocalSettings.php scheint unvollständig zu sein.
+       'config-localsettings-incomplete' => 'Die vorhandene Datei <code>LocalSettings.php</code> scheint unvollständig zu sein.
 Die Variable <code>$1</code> wurde nicht definiert.
-Die Datei LocalSettings.php muss entsprechend geändert werden, so dass sie definiert ist. Klicke danach auf „Weiter“.',
-       'config-localsettings-connection-error' => 'Beim Verbindungsversuch zur Datenbank ist, unter Verwendung der in den Dateien LocalSettings.php oder AdminSettings.php hinterlegten Einstellungen, ein Fehler aufgetreten. Diese Einstellungen müssen korrigiert werden. Danach kann ein erneuter Versuch unternommen werden.
+Die Datei <code>LocalSettings.php</code> muss entsprechend geändert werden, so dass sie definiert ist. Klicke danach auf „{{int:Config-continue}}“.',
+       'config-localsettings-connection-error' => 'Beim Verbindungsversuch zur Datenbank ist, unter Verwendung der in den Dateien <code>LocalSettings.php</code> oder <code>AdminSettings.php</code> hinterlegten Einstellungen, ein Fehler aufgetreten. Diese Einstellungen müssen korrigiert werden. Danach kann ein erneuter Versuch unternommen werden.
 
 $1',
        'config-session-error' => 'Fehler beim Starten der Sitzung: $1',
@@ -3674,7 +3756,7 @@ Die Datei <code>php.ini</code> muss geprüft und es muss dabei sichergestellt we
        'config-page-copying' => 'Kopie der Lizenz',
        'config-page-upgradedoc' => 'Aktualisiere',
        'config-page-existingwiki' => 'Vorhandenes Wiki',
-       'config-help-restart' => 'Sollen alle bereits eingegebene Daten gelöscht und der Installationsvorgang erneut gestartet werden?',
+       'config-help-restart' => 'Sollen alle bereits eingegebenen Daten gelöscht und der Installationsvorgang erneut gestartet werden?',
        'config-restart' => 'Ja, erneut starten',
        'config-welcome' => '=== Prüfung der Installationsumgebung ===
 Die Basisprüfungen werden durchgeführt, um festzustellen, ob die Installationsumgebung für die Installation von MediaWiki geeignet ist.
@@ -3774,7 +3856,10 @@ PHP muss auf Version 5.2.9 oder später sowie libxml2 auf die Version 2.7.3 oder
        'config-using531' => 'MediaWiki kann nicht zusammen mit PHP $1 verwendet werden. Grund hierfür ist ein Fehler im Zusammenhang mit den Verweisparametern zu <code>__call()</code>.
 PHP muss auf Version 5.3.2 oder höher oder 5.3.0 oder niedriger aktualisiert werden, um das Problem zu beheben.
 Die Installation wurde abgebrochen.',
-       'config-suhosin-max-value-length' => 'Suhosin ist installiert und beschränkt die Länge des GET-Parameters auf $1 Bytes. Der ResouceLoader von MediaWiki wird zwar unter diesen Bedingungen funktionieren, allerdings nur mit verminderter Leistungsfähigkeit. Sofern möglich sollte der Parameter <code>suhosin.get.max_value_length</code> in der Datei php.ini auf 1024 oder höher festgelegt werden. Gleichzeitig muss der Parameter <code>$wgResourceLoaderMaxQueryLength</code> in der Datei LocalSettings.php auf den selben Wert eingestellt werden.',
+       'config-suhosin-max-value-length' => 'Suhosin ist installiert und beschränkt die Länge des GET-Parameters auf $1 Bytes.
+Der ResouceLoader von MediaWiki wird zwar unter diesen Bedingungen funktionieren, allerdings nur mit verminderter Leistungsfähigkeit.
+Sofern möglich sollte der Parameter <code>suhosin.get.max_value_length</code> in der Datei <code>php.ini</code> auf 1024 oder höher festgelegt werden.
+Gleichzeitig muss der Parameter <code>$wgResourceLoaderMaxQueryLength</code> in der Datei <code>LocalSettings.php</code> auf den selben Wert eingestellt werden.',
        'config-db-type' => 'Datenbanksystem:',
        'config-db-host' => 'Datenbankserver:',
        'config-db-host-help' => 'Sofern sich die Datenbank auf einem anderen Server befindet, ist hier der Servername oder die entsprechende IP-Adresse anzugeben.
@@ -3858,7 +3943,7 @@ Sofern nicht das Datenbanksystem angezeigt wird, das verwendet werden soll, gibt
        'config-support-postgres' => '* $1 ist ein beliebtes Open-Source-Datenbanksystem und eine Alternative zu MySQL ([http://www.php.net/manual/de/pgsql.installation.php Anleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung]). Es gibt allerdings einige kleinere Implementierungsfehler, so dass von der Nutzung in einer Produktivumgebung abgeraten wird.',
        'config-support-sqlite' => '* $1 ist ein verschlanktes Datenbanksystem, das auch gut unterstützt wird ([http://www.php.net/manual/de/pdo.installation.php Anleitung zur Kompilierung von PHP mit SQLite-Unterstützung], verwendet PHP Data Objects (PDO))',
        'config-support-oracle' => '* $1 ist eine kommerzielle Unternehmensdatenbank ([http://www.php.net/manual/en/oci8.installation.php Anleitung zur Kompilierung von PHP mit OCI8-Unterstützung (en)])',
-       'config-support-ibm_db2' => '* $1 ist eine kommerzielle Unternehmensdatenbank',
+       'config-support-ibm_db2' => '* $1 ist eine kommerzielle Unternehmensdatenbank ([http://www.php.net/manual/en/ibm-db2.installation.php PHP mit IBM-DB2-Support kompilieren])',
        'config-header-mysql' => 'MySQL-Einstellungen',
        'config-header-postgres' => 'PostgreSQL-Einstellungen',
        'config-header-sqlite' => 'SQLite-Einstellungen',
@@ -3926,8 +4011,8 @@ Dies wird '''nicht empfohlen''', es sei denn, es treten Probleme mit dem Wiki au
        'config-upgrade-done-no-regenerate' => 'Die Aktualisierung ist abgeschlossen.
 
 Das Wiki kann nun [$1 genutzt werden].',
-       'config-regenerate' => 'LocalSettings.php neu erstellen →',
-       'config-show-table-status' => 'Die Abfrage SHOW TABLE STATUS ist gescheitert!',
+       'config-regenerate' => '<code>LocalSettings.php</code> neu erstellen →',
+       'config-show-table-status' => 'Die Abfrage <code>SHOW TABLE STATUS</code> ist gescheitert!',
        'config-unknown-collation' => "'''Warnung:''' Die Datenbank nutzt eine unbekannte Kollation.",
        'config-db-web-account' => 'Datenbankkonto für den Webzugriff',
        'config-db-web-help' => 'Bitte Benutzernamen und Passwort auswählen, die der Webserver während des Normalbetriebes dazu verwenden soll, eine Verbindung zum Datenbankserver herzustellen.',
@@ -4153,7 +4238,7 @@ $3
 '''Hinweis:''' Die Konfigurationsdatei sollte jetzt unbedingt heruntergeladen werden. Sie wird nach Beenden des Installationsprogramms, nicht mehr zur Verfügung stehen.
 
 Sobald alles erledigt wurde, kann auf das '''[$2 Wiki zugegriffen werden]'''. Wir wünschen viel Spaß und Erfolg mit dem Wiki.",
-       'config-download-localsettings' => 'LocalSettings.php herunterladen',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> herunterladen',
        'config-help' => 'Hilfe',
        'config-nofile' => 'Die Datei „$1“ konnte nicht gefunden werden. Wurde sie gelöscht?',
        'mainpagetext' => "'''MediaWiki wurde erfolgreich installiert.'''",
@@ -4313,8 +4398,8 @@ $messages['el'] = array(
        'config-invalid-db-type' => 'Μη έγκυρος τύπος βάσης δεδομένων',
        'config-mysql-utf8' => 'UTF-8',
        'config-site-name' => 'Όνομα του βίκι:',
-       'config-site-name-blank' => 'Εισαγάτε όνομα ιστοχώρου.',
-       'config-project-namespace' => 'ΠεÏ\81ιοÏ\87ή Î¿Î½Ï\8cμαÏ\84ος εγχειρήματος:',
+       'config-site-name-blank' => 'Εισαγάγετε όνομα ιστοχώρου.',
+       'config-project-namespace' => 'Î\9fνομαÏ\84οÏ\87Ï\8eÏ\81ος εγχειρήματος:',
        'config-ns-generic' => 'Εγχείρημα',
        'config-ns-site-name' => 'Ίδιο με το όνομα του wiki: $1',
        'config-ns-other' => 'Άλλο (προσδιορίστε)',
@@ -4375,6 +4460,7 @@ $messages['eo'] = array(
  * @author Sanbec
  * @author Translationista
  * @author Vivaelcelta
+ * @author 아라
  */
 $messages['es'] = array(
        'config-desc' => 'El instalador para MediaWiki',
@@ -4382,19 +4468,19 @@ $messages['es'] = array(
        'config-information' => 'Información',
        'config-localsettings-upgrade' => 'Se ha encontrado un archivo <code>LocalSettings.php</code>.
 Para actualizar esta instalación, por favor ingresa el valor de <code>$wgUpgradeKey</code> en el cuadro de abajo.
-Lo encontrarás en LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Se ha detectado un archivo LocalSettings.php.
-Para actualizar la instalación, vuelva a ejecutar update.php',
+Lo encontrarás en <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Se ha detectado un archivo <code>LocalSettings.php</code>.
+Para actualizar la instalación, vuelva a ejecutar <code>update.php</code>',
        'config-localsettings-key' => 'Clave de actualización:',
        'config-localsettings-badkey' => 'La clave proporcionada es incorrecta.',
        'config-upgrade-key-missing' => 'Se ha detectado una instalación existente de MediaWiki.
-Para actualizar la instalación, por favor, ponga la siguiente línea al final de su archivo LocalSettings.php:
+Para actualizar la instalación, por favor, ponga la siguiente línea al final de su archivo <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'El archivo LocalSettings.php existente parece estar incompleto.
+       'config-localsettings-incomplete' => 'El archivo <code>LocalSettings.php</code> existente parece estar incompleto.
 La variable $1 no está definida.
-Cambie el archivo LocalSettings.php para que esta variable quede establecida y haga clic en "Continuar".',
-       'config-localsettings-connection-error' => 'Se detectó un error al conectarse a la base de datos utilizando la configuración especificada en los archivos LocalSettings.php o AdminSettings.php. Corrija estas opciones y vuelva a intentarlo.
+Cambie el archivo <code>LocalSettings.php</code> para que esta variable quede establecida y haga clic en "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Se detectó un error al conectarse a la base de datos utilizando la configuración especificada en los archivos <code>LocalSettings.php</code> o <code>AdminSettings.php</code>. Corrija estas opciones y vuelva a intentarlo.
 
 $1',
        'config-session-error' => 'Error comenzando sesión: $1',
@@ -4527,7 +4613,9 @@ Instalación anulada.',
        'config-using531' => 'MediaWiki no puede utilizarse con PHP $1 debido a un error con los parámetros de referencia para <code>__call()</code> .
 Actualice el sistema a PHP 5.3.2 o superior, o vuelva a la versión PHP 5.3.0 para resolver este problema.
 Instalación anulada.',
-       'config-suhosin-max-value-length' => 'Suhosin está instalado y limita la longitud del parámetro GET a $1 bytes. El componente ResourceLoader de MediaWiki trabajará en este límite, pero eso degradará el rendimiento. Si es posible, debe establecer el valor de suhosin.get.max_value_length en 1024 o superior en el archivo php.ini y establecer $wgResourceLoaderMaxQueryLength en el mismo valor en LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'Suhosin está instalado y limita el parámetro <code>length</code> GET a $1 bytes. 
+El componente ResourceLoader (gestor de recursos) de MediaWiki trabajará en este límite, pero eso perjudicará el rendimiento.
+Si es posible, deberías establecer <code>suhosin.get.max_value_length</code> en el valor 1024 o superior en <code>php.ini</code> y establecer <code>$wgResourceLoaderMaxQueryLength</code> en el mismo valor en <code>php.ini</code>.',
        'config-db-type' => 'Tipo de base de datos',
        'config-db-host' => 'Servidor de la base de datos:',
        'config-db-host-help' => 'Si su servidor de base de datos está en otro servidor, escriba el nombre del host o su dirección IP aquí.
@@ -4608,9 +4696,9 @@ $1
 Si no encuentras en el listado el sistema de base de datos que estás intentando utilizar, sigue las instrucciones vinculadas arriba para habilitar la compatibilidad.',
        'config-support-mysql' => '* $1 es la base de datos mayoritaria para MediaWiki y la que goza de mayor compatibilidad ([http://www.php.net/manual/es/mysql.installation.php cómo compilar PHP con compatibilidad MySQL])',
        'config-support-postgres' => '$1 es un popular sistema de base de datos de código abierto, alternativa a MySQL. ([http://www.php.net/manual/es/pgsql.installation.php cómo compilar PHP con compatibilidad PostgreSQL]). Puede haber algunos defectos menores destacables, y no es recomendable para uso en un entorno de producción.',
-       'config-support-sqlite' => '* $1 es una base de datos ligera con gran compatibilidad con MediaWiki. ([http://www.php.net/manual/es/pdo.installation.php Cómo compilar PHP con compatibilidad SQLite], usa PDO)',
+       'config-support-sqlite' => '* $1 es una base de datos ligera con gran compatibilidad con MediaWiki ([http://www.php.net/manual/es/pdo.installation.php cómo compilar PHP con compatibilidad SQLite usando PDO]).',
        'config-support-oracle' => '* $1 es una base de datos comercial a nivel empresarial ([http://www.php.net/manual/es/oci8.installation.php cómo compilar PHP con compatibilidad con OCI8])',
-       'config-support-ibm_db2' => ' $1  es una base de datos de empresa comercial.',
+       'config-support-ibm_db2' => '* $1 es una base de datos comercial a nivel empresarial ([http://www.php.net/manual/es/ibm-db2.installation.php cómo compilar PHP con compatibilidad con ibm_db2]).', # Fuzzy
        'config-header-mysql' => 'Configuración de MySQL',
        'config-header-postgres' => 'Configuración de PostgreSQL',
        'config-header-sqlite' => 'Configuración de SQLite',
@@ -4676,8 +4764,8 @@ Esto '''no se recomienda''' a menos que esté teniendo problemas con su wiki.",
        'config-upgrade-done-no-regenerate' => 'Actualización completa.
 
 Usted puede ahora [$1  empezar a usar su wiki].',
-       'config-regenerate' => 'Regenerar LocalSettings.php →',
-       'config-show-table-status' => 'SHOW TABLE STATUS ha fallado!',
+       'config-regenerate' => 'Regenerar <code>LocalSettings.php</code> →',
+       'config-show-table-status' => '<code>SHOW TABLE STATUS</code> ha fallado!',
        'config-unknown-collation' => "'''Advertencia:''' La base de datos está utilizando una intercalación no reconocida.",
        'config-db-web-account' => 'Cuenta de base de datos para acceso Web',
        'config-db-web-help' => 'Elige el usuario y contraseña que el servidor Web usará para conectarse al servidor de la base de datos durante el fincionamiento normal del wiki.',
@@ -4750,7 +4838,7 @@ Ahora puedes saltarte el resto de pasos e instalar el wiki con valores predeterm
        'config-optional-continue' => 'Hazme más preguntas.',
        'config-optional-skip' => 'Ya estoy aburrido, sólo instala el wiki.',
        'config-profile' => 'Perfil de derechos de usuario:',
-       'config-profile-wiki' => 'Wiki tradicional',
+       'config-profile-wiki' => 'Wiki tradicional', # Fuzzy
        'config-profile-no-anon' => 'Creación de cuenta requerida',
        'config-profile-fishbowl' => 'Sólo editores autorizados',
        'config-profile-private' => 'Wiki privado',
@@ -4765,7 +4853,7 @@ Un wiki con '''{{int:config-profile-no-anon}}''' ofrece rendición de cuentas ad
 El escenario '''{{int:config-profile-fishbowl}}''' permite editar a los usuarios autorizados, pero el público puede ver las páginas, incluyendo el historial.
 Un '''{{int:config-profile-private}}''' sólo permite ver páginas a los usuarios autorizados, el mismo grupo al que le está permitido editar.
 
-Configuraciones más complejas de derechos de usuario están disponibles después de la instalación, consulte [//www.mediawiki.org/wiki/Manual:User_rights esta entrada en el manual].",
+Configuraciones más complejas de derechos de usuario están disponibles después de la instalación, consulte [//www.mediawiki.org/wiki/Manual:User_rights esta entrada en el manual].", # Fuzzy
        'config-license' => 'Copyright and licencia:',
        'config-license-none' => 'Pie sin licencia',
        'config-license-cc-by-sa' => 'Creative Commons Reconocimiento Compartir Igual',
@@ -4850,7 +4938,7 @@ Puede que necesiten configuraciones adicionales, pero puedes habilitarlas ahora.
        'config-install-alreadydone' => "'''Aviso:''' Parece que ya habías instalado MediaWiki y estás intentando instalarlo nuevamente.
 Pasa a la próxima página, por favor.",
        'config-install-begin' => 'Pulsando "{{int:config-continue}}", se iniciará la instalación de MediaWiki.
-Si todavía desea realizar algún cambio, pulse atrás.',
+Si todavía desea realizar algún cambio, pulse atrás.', # Fuzzy
        'config-install-step-done' => 'hecho',
        'config-install-step-failed' => 'falló',
        'config-install-extensions' => 'Extensiones inclusive',
@@ -4904,7 +4992,7 @@ $3
 '''Nota''': Si no haces esto ahora, este archivo de configuración generado no estará disponible para usted más tarde si sale de la instalación sin descargarlo.
 
 Cuando lo haya hecho, usted puede '''[$2  entrar en su wiki]'''.",
-       'config-download-localsettings' => 'Descargar archivo LocalSettings.php',
+       'config-download-localsettings' => 'Descargar archivo <code>LocalSettings.php</code>',
        'config-help' => 'Ayuda',
        'config-nofile' => 'El archivo "$1" no se pudo encontrar. ¿Se ha eliminado?',
        'mainpagetext' => "'''MediaWiki ha sido instalado con éxito.'''",
@@ -5193,6 +5281,7 @@ $messages['fa'] = array(
  * @author Olli
  * @author Str4nd
  * @author VezonThunder
+ * @author 아라
  */
 $messages['fi'] = array(
        'config-desc' => 'MediaWiki-asennin',
@@ -5200,19 +5289,19 @@ $messages['fi'] = array(
        'config-information' => 'Tiedot',
        'config-localsettings-upgrade' => '<code>LocalSettings.php</code>-tiedosto havaittiin.
 Kirjoita muuttujan <code>$wgUpgradeKey</code> arvo alla olevaan kenttään päivittääksesi asennuksen.
-Löydät sen LocalSettings.php-tiedostosta.',
-       'config-localsettings-cli-upgrade' => 'LocalSettings.php-tiedosto havaittiin.
-Päivitä asennus suorittamalla update.php.',
+Löydät sen <code>LocalSettings.php</code>-tiedostosta.',
+       'config-localsettings-cli-upgrade' => '<code>LocalSettings.php</code>-tiedosto havaittiin.
+Päivitä asennus suorittamalla <code>update.php</code>.',
        'config-localsettings-key' => 'Päivitysavain',
        'config-localsettings-badkey' => 'Antamasi avain on virheellinen.',
        'config-upgrade-key-missing' => 'Havaittiin aiempi MediaWiki-asennus.
-Päivittääksesi tämän asennuksen lisää LocalSettings.php-tiedostosi loppuun seuraava rivi:
+Päivittääksesi tämän asennuksen lisää <code>LocalSettings.php</code>-tiedostosi loppuun seuraava rivi:
 
 $1',
-       'config-localsettings-incomplete' => 'Nykyinen LocalSettings.php-tiedosto näyttää olevan puutteellinen.
+       'config-localsettings-incomplete' => 'Nykyinen <code>LocalSettings.php</code>-tiedosto näyttää olevan puutteellinen.
 Muuttujaa $1 ei ole asetettu.
-Muuta LocalSettings.php-tiedostoa siten, että muuttuja on asetettu ja napsauta »Jatka».',
-       'config-localsettings-connection-error' => 'Virhe yhdistettäessä tietokantaan käyttäen tiedostossa LocalSettings.php tai AdminSettings.php määritettyjä asetuksia. Korjaa asetukset ja yritä uudelleen.
+Muuta <code>LocalSettings.php</code>-tiedostoa siten, että muuttuja on asetettu ja napsauta »{{int:Config-continue}}».',
+       'config-localsettings-connection-error' => 'Virhe yhdistettäessä tietokantaan käyttäen tiedostossa <code>LocalSettings.php</code> tai <code>AdminSettings.php</code> määritettyjä asetuksia. Korjaa asetukset ja yritä uudelleen.
 
 $1',
        'config-session-error' => 'Istunnon aloittaminen epäonnistui: $1',
@@ -5294,7 +5383,7 @@ Asennus saattaa epäonnistua!",
        'config-type-sqlite' => 'SQLite',
        'config-type-oracle' => 'Oracle',
        'config-type-ibm_db2' => 'IBM DB2',
-       'config-support-ibm_db2' => '* $1 on kaupallinen tietokanta yrityskäyttöön.',
+       'config-support-ibm_db2' => '* $1 on kaupallinen tietokanta yrityskäyttöön.', # Fuzzy
        'config-header-mysql' => 'MySQL-asetukset',
        'config-header-postgres' => 'PostgreSQL-asetukset',
        'config-header-sqlite' => 'SQLite-asetukset',
@@ -5323,8 +5412,8 @@ Tämä '''ei ole suositeltavaa''', jos wikissäsi ei ole ongelmia.",
        'config-upgrade-done-no-regenerate' => 'Päivitys valmis.
 
 Voit [$1 aloittaa wikin käytön].',
-       'config-regenerate' => 'Luo LocalSettings.php uudelleen →',
-       'config-show-table-status' => 'Kysely SHOW TABLE STATUS epäonnistui!',
+       'config-regenerate' => 'Luo <code>LocalSettings.php</code> uudelleen →',
+       'config-show-table-status' => 'Kysely <code>SHOW TABLE STATUS</code> epäonnistui!',
        'config-mysql-engine' => 'Tallennusmoottori',
        'config-mysql-innodb' => 'InnoDB',
        'config-mysql-myisam' => 'MyISAM',
@@ -5344,7 +5433,7 @@ Voit [$1 aloittaa wikin käytön].',
        'config-admin-error-bademail' => 'Annoit virheellisen sähköpostiosoitteen.',
        'config-almost-done' => 'Olet jo lähes valmis!
 Voit ohittaa jäljellä olevat määritykset ja asentaa wikin juuri nyt.',
-       'config-profile-wiki' => 'Perinteinen wiki',
+       'config-profile-wiki' => 'Avoin wiki',
        'config-profile-no-anon' => 'Tunnuksen luonti vaaditaan',
        'config-profile-private' => 'Yksityinen wiki',
        'config-license' => 'Tekijänoikeus ja lisenssi:',
@@ -5357,7 +5446,7 @@ Voit ohittaa jäljellä olevat määritykset ja asentaa wikin juuri nyt.',
        'config-install-step-failed' => 'epäonnistui',
        'config-install-user-alreadyexists' => 'Käyttäjä $1 on jo olemassa',
        'config-install-interwiki-list' => 'Tiedostoa <code>interwiki.list</code> ei voitu lukea.',
-       'config-download-localsettings' => 'Lataa LocalSettings.php',
+       'config-download-localsettings' => 'Lataa <code>LocalSettings.php</code>',
        'config-help' => 'ohje',
        'mainpagetext' => "'''MediaWiki on onnistuneesti asennettu.'''",
        'mainpagedocfooter' => "Lisätietoja käytöstä on sivulla [//meta.wikimedia.org/wiki/Help:Contents User's Guide].
@@ -5402,6 +5491,7 @@ $messages['fo'] = array(
  * @author Verdy p
  * @author Wyz
  * @author Yumeki
+ * @author 아라
  */
 $messages['fr'] = array(
        'config-desc' => 'Le programme d’installation de MediaWiki',
@@ -5409,20 +5499,20 @@ $messages['fr'] = array(
        'config-information' => 'Informations',
        'config-localsettings-upgrade' => 'Un fichier <code>LocalSettings.php</code> a été détecté.
 Pour mettre à jour cette installation, veuillez saisir la valeur de <code>$wgUpgradeKey</code> dans le champ ci-dessous.
-Vous la trouverez dans LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Un fichier LocalSettings.php a été détecté.
-Pour mettre à niveau cette installation, veuillez exécuter update.php',
+Vous la trouverez dans <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Un fichier <code>LocalSettings.php</code> a été détecté.
+Pour mettre à niveau cette installation, veuillez exécuter <code>update.php</code>',
        'config-localsettings-key' => 'Clé de mise à jour :',
        'config-localsettings-badkey' => 'La clé que vous avez fournie est incorrecte',
        'config-upgrade-key-missing' => 'Une installation existante de MediaWiki a été détectée.
 
-Pour mettre à jour cette installation, veuillez ajouter la ligne suivante à la fin de votre fichier LocalSettings.php
+Pour mettre à jour cette installation, veuillez ajouter la ligne suivante à la fin de votre fichier <code>LocalSettings.php</code>
 
 $1',
-       'config-localsettings-incomplete' => 'Le fichier LocalSettings.php existant semble être incomplet.
+       'config-localsettings-incomplete' => 'Le fichier <code>LocalSettings.php</code> existant semble être incomplet.
 La variable $1 n’est pas définie.
-Veuillez modifier LocalSettings.php de sorte que cette variable soit définie, puis cliquer sur « Continuer ».',
-       'config-localsettings-connection-error' => 'Une erreur est survenue lors de la connexion à la base de données en utilisant la configuration spécifiée dans LocalSettings.php ou AdminSettings.php. Veuillez corriger cette configuration puis réessayer.
+Veuillez modifier <code>LocalSettings.php</code> de sorte que cette variable soit définie, puis cliquer sur « {{int:Config-continue}} ».',
+       'config-localsettings-connection-error' => 'Une erreur est survenue lors de la connexion à la base de données en utilisant la configuration spécifiée dans <code>LocalSettings.php</code> ou <code>AdminSettings.php</code>. Veuillez corriger cette configuration puis réessayer.
 
 $1',
        'config-session-error' => 'Erreur lors du démarrage de la session : $1',
@@ -5554,7 +5644,8 @@ Installation interrompue.',
        'config-using531' => 'MediaWiki ne peut pas être utilisé avec PHP $1 à cause d’un bogue affectant les paramètres passés par référence à <code>__call()</code>.
 Veuillez mettre à jour votre système vers PHP 5.3.2 ou plus récent ou revenir à PHP 5.3.0 pour résoudre ce problème.
 Installation interrompue.',
-       'config-suhosin-max-value-length' => 'Suhosin est installé et limite la longueur du paramètre GET à $1 octets. Le <code>ResourceLoader</code> de MediaWiki va répondre en respectant cette limite, mais ses performances seront dégradées. Si possible, vous devriez définir <code>suhosin.get.max_value_length</code> à 1024 ou plus dans le fichier <code>php.ini</code>, et fixer <code>$wgResourceLoaderMaxQueryLength</code> à la même valeur dans <code>LocalSettings.php</code>.',
+       'config-suhosin-max-value-length' => 'Suhosin est installé et limite la <code>longueur</code> du paramètre GET à $1 octets.
+Le composant ResourceLoader de MediaWiki va répondre en respectant cette limite, mais ses performances seront dégradées. Si possible, vous devriez définir <code>suhosin.get.max_value_length</code> à 1024 ou plus dans le fichier <code>php.ini</code>, et fixer <code>$wgResourceLoaderMaxQueryLength</code> à la même valeur dans <code>LocalSettings.php</code>.',
        'config-db-type' => 'Type de base de données :',
        'config-db-host' => 'Nom d’hôte de la base de données :',
        'config-db-host-help' => 'Si votre serveur de base de données est sur un serveur différent, saisissez ici son nom d’hôte ou son adresse IP.
@@ -5636,7 +5727,7 @@ Si vous ne voyez pas le système de base de données que vous essayez d'utiliser
        'config-support-postgres' => "* $1 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 how to compile PHP with PostgreSQL support]). Il peut contenir quelques bogues mineurs et n'est pas recommandé dans un environnement de production.",
        'config-support-sqlite' => '* $1 est un système de base de données léger qui est bien supporté. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], utilise PDO)',
        'config-support-oracle' => '* $1 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-support-ibm_db2' => "* $1 est une base de données d'entreprise commerciale.",
+       'config-support-ibm_db2' => "* $1 est une base de données d'entreprise commerciale. ([http://www.php.net/manual/en/ibm-db2.installation.php Comment compiler PHP avec le support de DB2 d’IBM])",
        'config-header-mysql' => 'Paramètres de MySQL',
        'config-header-postgres' => 'Paramètres de PostgreSQL',
        'config-header-sqlite' => 'Paramètres de SQLite',
@@ -5703,8 +5794,8 @@ Ce '''n'est pas recommandé''' sauf si vous rencontrez des problèmes avec votre
        'config-upgrade-done-no-regenerate' => 'Mise à jour terminée.
 
 Vous pouvez maintenant [$1 commencer à utiliser votre wiki].',
-       'config-regenerate' => 'Regénérer LocalSettings.php →',
-       'config-show-table-status' => 'Échec de la requête SHOW TABLE STATUS !',
+       'config-regenerate' => 'Regénérer <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Échec de la requête <code>SHOW TABLE STATUS</code> !',
        'config-unknown-collation' => "'''Attention:''' La base de données effectue un classement alphabétique (''collation'') inconnu.",
        'config-db-web-account' => "Compte de la base de données pour l'accès Web",
        'config-db-web-help' => "Sélectionnez le nom d'utilisateur et le mot de passe que le serveur web utilisera pour se connecter au serveur de base de données pendant le fonctionnement habituel du wiki.",
@@ -5925,7 +6016,7 @@ $3
 '''Note''': Si vous ne le faites pas maintenant, ce fichier de configuration généré ne sera pas disponible plus tard si vous quittez l'installation sans le télécharger.
 
 Lorsque c'est fait, vous pouvez '''[$2 accéder à votre wiki]'''.",
-       'config-download-localsettings' => 'Télécharger LocalSettings.php',
+       'config-download-localsettings' => 'Télécharger <code>LocalSettings.php</code>',
        'config-help' => 'aide',
        'config-nofile' => 'Le fichier « $1 » est introuvable. A-t-il été supprimé ?',
        'mainpagetext' => "'''MediaWiki a été installé avec succès.'''",
@@ -6020,8 +6111,8 @@ Portant, MediaWiki at fôta de PHP $2 ou ben ples hôt.',
        'config-missing-db-host' => 'Vos dête buchiér una valor por « Hôto de la bâsa de balyês »',
        'config-missing-db-server-oracle' => 'Vos dête buchiér una valor por « TNS de la bâsa de balyês »',
        'config-sqlite-readonly' => 'Lo fichiér <code>$1</code> est pas accèssiblo en ècritura.',
-       'config-regenerate' => 'Refâre LocalSettings.php →',
-       'config-show-table-status' => 'Falyita de la requéta SHOW TABLE STATUS !',
+       'config-regenerate' => 'Refâre <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Falyita de la requéta <code>SHOW TABLE STATUS</code> !',
        'config-db-web-account' => 'Compto de la bâsa de balyês por l’accès vouèbe',
        'config-db-web-account-same' => 'Utilisâd lo mémo compto que por l’enstalacion',
        'config-db-web-create' => 'Féte lo compto s’ègziste p’oncor',
@@ -6047,7 +6138,7 @@ Portant, MediaWiki at fôta de PHP $2 ou ben ples hôt.',
        'config-admin-email' => 'Adrèce èlèctronica :',
        'config-optional-continue' => 'Mè posar més de quèstions.',
        'config-profile' => 'Profil des drêts d’usanciér :',
-       'config-profile-wiki' => 'Vouiqui tradicionâl',
+       'config-profile-wiki' => 'Vouiqui tradicionâl', # Fuzzy
        'config-profile-no-anon' => 'Crèacion de compto nècèssèra',
        'config-profile-fishbowl' => 'Solament los èditors ôtorisâs',
        'config-profile-private' => 'Vouiqui privâ',
@@ -6100,7 +6191,7 @@ Portant, MediaWiki at fôta de PHP $2 ou ben ples hôt.',
        'config-install-mainpage' => 'Crèacion de la pâge principâla avouéc un contegnu per dèfôt',
        'config-install-extension-tables' => 'Crèacion de trâbles por les èxtensions activâs',
        'config-install-mainpage-failed' => 'Empossiblo d’entrebetar la pâge principâla : $1',
-       'config-download-localsettings' => 'Tèlèchargiér LocalSettings.php',
+       'config-download-localsettings' => 'Tèlèchargiér <code>LocalSettings.php</code>',
        'config-help' => 'éde',
        'mainpagetext' => "'''MediaWiki at étâ enstalâ avouéc reusséta.'''",
        'mainpagedocfooter' => 'Vêde lo [//meta.wikimedia.org/wiki/Aide:Contenu guido d’usanciér] por més d’enformacions sur l’usâjo de la programeria vouiqui.
@@ -6108,7 +6199,7 @@ Portant, MediaWiki at fôta de PHP $2 ou ben ples hôt.',
 == Emmodar avouéc MediaWiki ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Lista des paramètres de configuracion]
 * [//www.mediawiki.org/wiki/Manual:FAQ/fr FDQ sur MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de discussion sur les distribucions de MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de discussion sur les distribucions de MediaWiki]', # Fuzzy
 );
 
 /** Northern Frisian (Nordfriisk)
@@ -6213,6 +6304,7 @@ $messages['gd'] = array(
 /** Galician (galego)
  * @author Elisardojm
  * @author Toliño
+ * @author 아라
  */
 $messages['gl'] = array(
        'config-desc' => 'O programa de instalación de MediaWiki',
@@ -6220,19 +6312,19 @@ $messages['gl'] = array(
        'config-information' => 'Información',
        'config-localsettings-upgrade' => 'Detectouse un ficheiro <code>LocalSettings.php</code>.
 Para actualizar esta instalación, introduza o valor de <code>$wgUpgradeKey</code> na caixa.
-Pode atopalo en LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Detectouse un ficheiro LocalSettings.php.
-Para actualizar esta instalación, execute update.php',
+Pode atopalo en <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Detectouse un ficheiro <code>LocalSettings.php</code>.
+Para actualizar esta instalación, execute <code>update.php</code>',
        'config-localsettings-key' => 'Clave de actualización:',
        'config-localsettings-badkey' => 'A clave dada é incorrecta',
        'config-upgrade-key-missing' => 'Detectouse unha instalación existente de MediaWiki.
-Para actualizar esta instalación, inclúa esta liña ao final do ficheiro LocalSettings.php:
+Para actualizar esta instalación, inclúa esta liña ao final do ficheiro <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Semella que o ficheiro LocalSettings.php existente está incompleto.
+       'config-localsettings-incomplete' => 'Semella que o ficheiro <code>LocalSettings.php</code> existente está incompleto.
 A variable $1 non está establecida.
-Modifique o ficheiro LocalSettings.php de xeito que a variable quede establecida e prema en "Continuar".',
-       'config-localsettings-connection-error' => 'Atopouse un erro ao conectar coa base de datos empregando a configuración especificada no ficheiro LocalSettings.php ou no ficheiro AdminSettings.php. Corrixa esta configuración e inténteo de novo.
+Modifique o ficheiro <code>LocalSettings.php</code> de xeito que a variable quede establecida e prema en "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Atopouse un erro ao conectar coa base de datos empregando a configuración especificada no ficheiro <code>LocalSettings.php</code> ou no ficheiro <code>AdminSettings.php</code>. Corrixa esta configuración e inténteo de novo.
 
 $1',
        'config-session-error' => 'Erro ao iniciar a sesión: $1',
@@ -6365,7 +6457,9 @@ Instalación abortada.',
        'config-using531' => 'O PHP $1 non é compatible con MediaWiki debido a un erro que afecta aos parámetros de referencia de <code>__call()</code>.
 Actualice o sistema á versión 5.3.2 ou posterior do PHP ou volva á versión 5.3.0 do PHP para arranxar o problema.
 Instalación abortada.',
-       'config-suhosin-max-value-length' => 'Suhosin está instalado e limita a lonxitude do parámetro GET a $1 bytes. O compoñente ResourceLoader (xestor de recursos) de MediaWiki traballa neste límite, pero este prexudica o rendemento. Se é posible, debería establecer suhosin.get.max_value_length no valor 1024 ou superior en php.ini e establecer $wgResourceLoaderMaxQueryLength no mesmo valor en LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'Suhosin está instalado e limita o parámetro GET <code>length</code> a $1 bytes.
+O compoñente ResourceLoader (xestor de recursos) de MediaWiki traballa neste límite, pero este prexudica o rendemento.
+Se é posible, debería establecer <code>suhosin.get.max_value_length</code> no valor 1024 ou superior en <code>php.ini</code> e establecer <code>$wgResourceLoaderMaxQueryLength</code> no mesmo valor en <code>LocalSettings.php</code>.',
        'config-db-type' => 'Tipo de base de datos:',
        'config-db-host' => 'Servidor da base de datos:',
        'config-db-host-help' => 'Se o servidor da súa base de datos está nun servidor diferente, escriba o nome do servidor ou o enderezo IP aquí.
@@ -6448,8 +6542,8 @@ Se non ve listado a continuación o sistema de base de datos que intenta usar, s
        'config-support-mysql' => '* $1 é o obxectivo principal para MediaWiki e está mellor soportado ([http://www.php.net/manual/en/mysql.installation.php como compilar o PHP con soporte MySQL])',
        'config-support-postgres' => '* $1 é 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 o PHP con soporte PostgreSQL]). É posible que haxa algúns pequenos erros e non se recomenda o seu uso nunha contorna de produción.',
        'config-support-sqlite' => '* $1 é 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-support-oracle' => '* $1 é un sistema comercial de xestión de base de datos de empresa. ([http://www.php.net/manual/en/oci8.installation.php Como compilar PHP con soporte OCI8])',
-       'config-support-ibm_db2' => '* $1 é unha base de datos de empresa comercial.',
+       'config-support-oracle' => '* $1 é un sistema comercial de xestión de base de datos de empresa. ([http://www.php.net/manual/en/oci8.installation.php Como compilar PHP con soporte OCI8])',
+       'config-support-ibm_db2' => '* $1 é unha base de datos de empresa comercial. ([http://www.php.net/manual/en/ibm-db2.installation.php Como compilar o PHP con soporte IBM DB2])',
        'config-header-mysql' => 'Configuración do MySQL',
        'config-header-postgres' => 'Configuración do PostgreSQL',
        'config-header-sqlite' => 'Configuración do SQLite',
@@ -6516,8 +6610,8 @@ Isto '''non é recomendable''' a menos que estea a ter problemas co seu wiki.",
        'config-upgrade-done-no-regenerate' => 'Actualización completada.
 
 Xa pode [$1 comezar a usar o seu wiki].',
-       'config-regenerate' => 'Rexenerar LocalSettings.php →',
-       'config-show-table-status' => 'A pescuda SHOW TABLE STATUS fallou!',
+       'config-regenerate' => 'Rexenerar <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'A pescuda <code>SHOW TABLE STATUS</code> fallou!',
        'config-unknown-collation' => "'''Atención:''' A base de datos está a empregar unha clasificación alfabética irrecoñecible.",
        'config-db-web-account' => 'Conta na base de datos para o acceso á internet',
        'config-db-web-help' => 'Seleccione o nome de usuario e contrasinal que o servidor web empregará para se conectar ao servidor da base de datos durante o funcionamento normal do wiki.',
@@ -6746,7 +6840,7 @@ $3
 '''Nota:''' Se non fai iso agora, este ficheiro de configuración xerado non estará dispoñible máis adiante se sae da instalación sen descargalo.
 
 Cando faga todo isto, xa poderá '''[$2 entrar no seu wiki]'''.",
-       'config-download-localsettings' => 'Descargar o LocalSettings.php',
+       'config-download-localsettings' => 'Descargar o <code>LocalSettings.php</code>',
        'config-help' => 'axuda',
        'config-nofile' => 'Non se puido atopar o ficheiro "$1". Se cadra, foi borrado?',
        'mainpagetext' => "'''MediaWiki instalouse correctamente.'''",
@@ -6790,7 +6884,7 @@ $messages['gsw'] = array(
        'config-information' => 'Information',
        'config-localsettings-upgrade' => "'''Warnig:''' E Datei <code>LocalSettings.php</code> isch gfunde wore.
 Fir d Aktualisierig vu dr däre Inschtallation, gib bitte dr Wärt vum Parameter <code>\$wgUpgradeKey</code> im Fäld unten yy.
-Du findsch dr Wärt in dr Datei LocalSettings.php.",
+Du findsch dr Wärt in dr Datei <code>LocalSettings.php</code>.",
        'config-localsettings-key' => 'Aktualisierigsschlissel:',
        'config-localsettings-badkey' => 'Dr Aktualisierigsschlissel, wu du aagee hesch, isch falsch.',
        'config-session-error' => 'Fähler bim Starte vu dr Sitzig: $1',
@@ -6889,7 +6983,7 @@ S Objäktcaching isch wäge däm nit aktiviert.",
 Miniaturaasichte vu Bilder sin megli, sobald s Uffelade vu Dateie aktiviert isch.',
        'config-help' => 'Hilf',
        'mainpagetext' => "'''MediaWiki isch erfolgrich inschtalliert worre.'''",
-       'mainpagedocfooter' => 'Lueg uf d [//meta.wikimedia.org/wiki/MediaWiki_localisation Dokumentation fir d Aapassig vu dr Benutzeroberflächi] un s [//meta.wikimedia.org/wiki/Help:Contents Benutzerhandbuech] fir d Hilf iber d Benutzig un s Yystelle.',
+       'mainpagedocfooter' => 'Lueg uf d [//meta.wikimedia.org/wiki/MediaWiki_localisation Dokumentation fir d Aapassig vu dr Benutzeroberflächi] un s [//meta.wikimedia.org/wiki/Help:Contents Benutzerhandbuech] fir d Hilf iber d Benutzig un s Yystelle.', # Fuzzy
 );
 
 /** Gujarati (ગુજરાતી)
@@ -6934,6 +7028,7 @@ $messages['haw'] = array(
  * @author Amire80
  * @author YaronSh
  * @author ערן
+ * @author 아라
  */
 $messages['he'] = array(
        'config-desc' => 'תכנית ההתקנה של מדיה־ויקי',
@@ -6941,19 +7036,19 @@ $messages['he'] = array(
        'config-information' => 'פרטים',
        'config-localsettings-upgrade' => 'זוהה קובץ <code>LocalSettings.php</code>.
 כדי לשדרג את ההתקנה הזאת, נא להקליד את הערך של <code>$wgUpgradeKey</code> בתיבה להלן.
-אפשר למצוא אותו בקובץ LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'זוהה קובץ LocalSettings.php.
-כדי לשדרג את ההתקנה הזאת, הריצו את update.php ולא את הקובץ הזה.',
+אפשר למצוא אותו בקובץ <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'זוהה קובץ <code>LocalSettings.php</code>.
+כדי לשדרג את ההתקנה הזאת, הריצו את <code>update.php</code> ולא את הקובץ הזה.',
        'config-localsettings-key' => 'מפתח השדרוג:',
        'config-localsettings-badkey' => 'המפתח שהקלדתם שגוי',
        'config-upgrade-key-missing' => 'זוהתה התקנה קיימת של מדיה־ויקי.
-כדי לשדרג את ההתקנה הזאת, אנא כתבו את השורה הבא בתחתית קובץ LocalSettings.php שלכם:
+כדי לשדרג את ההתקנה הזאת, אנא כתבו את השורה הבא בתחתית קובץ <code>LocalSettings.php</code> שלכם:
 
 $1',
-       'config-localsettings-incomplete' => 'נראה שקובץ LocalSettings.php הקיים אינו שלם.
+       'config-localsettings-incomplete' => 'נראה שקובץ <code>LocalSettings.php</code> הקיים אינו שלם.
 המשתנה $1 אינו מוגדר.
-נו לשנות את קובץ LocalSettings.php שלכם כך שהמשתנה הזה יהיה מוגדר וללחוץ "המשך".',
-       'config-localsettings-connection-error' => 'אירעה שגיאה בעת חיבור למסד נתונים עם הגדרות ב־LocalSettings.php או ב־AdminSettings.php. נא לתקן את ההגדרות האלו ולנסות שוב.
+נו לשנות את קובץ <code>LocalSettings.php</code> שלכם כך שהמשתנה הזה יהיה מוגדר וללחוץ "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'אירעה שגיאה בעת חיבור למסד נתונים עם הגדרות ב־<code>LocalSettings.php</code> או ב־<code>AdminSettings.php</code>. נא לתקן את ההגדרות האלו ולנסות שוב.
 
 $1',
        'config-session-error' => 'שגיאה באתחול שיחה: $1',
@@ -7085,7 +7180,7 @@ $1
        'config-using531' => 'אי־אפשר להשתמש במדיה־ויקי עם <span dir="ltr">PHP $1</span> בגלל באג בפרמטרים של הפניות (reference parameters) ל־<code dir="ltr">__call()</code>.
 שדרגו ל־PHP 5.3.2 או לגרסה גבוהה יותר כדי לתקן את זה ([//bugs.php.net/bug.php?id=50394 bug filed with PHP]) או שַנמכו ל־PHP 5.3.0 כדי לפתור את הבעיה הזאת.
 ההתקנה בוטלה.',
-       'config-suhosin-max-value-length' => '×\9e×\95תק×\9f ×¤×\94 Suhosin ×\95×\94×\95×\90 ×\9e×\92×\91×\99×\9c ×\90ת ×\90×\95ר×\9a ×¤×¨×\9e×\98ר GET ×\9cÖ¾$1 ×\91ת×\99×\9d. ×¨×\9b×\99×\91 ResourceLoader ×©×\9c ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99 ×\99עק×\95×£ ×\90ת ×\94×\9e×\92×\9c×\91×\94 ×\94×\96×\90ת, ×\90×\91×\9c ×\96×\94 ×\99פ×\92×¢ ×\91×\91×\99צ×\95×¢×\99×\9d. ×\90×\9d ×\96×\94 ×\91×\9b×\9c×\9c ×\90פשר×\99, ×\9b×\93×\99 ×\9cתק×\9f ×\90ת ×\94ער×\9a ×©×\9c suhosin.get.max_value_length ×\9cÖ¾1024 ×\91ק×\95×\91×¥ php.ini ×\95×\9c×\94×\92×\93×\99ר ×\90ת â\80\8e$wgResourceLoaderMaxQueryLength לאותו הערך בקובץ LocalSettings.php.',
+       'config-suhosin-max-value-length' => '×\9e×\95תק×\9f ×¤×\94 Suhosin ×\95×\94×\95×\90 ×\9e×\92×\91×\99×\9c ×\90ת ×\90×\95ר×\9a ×¤×¨×\9e×\98ר GET ×\9cÖ¾$1 ×\91ת×\99×\9d. ×¨×\9b×\99×\91 ResourceLoader ×©×\9c ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99 ×\99עק×\95×£ ×\90ת ×\94×\9e×\92×\9c×\91×\94 ×\94×\96×\90ת, ×\90×\91×\9c ×\96×\94 ×\99פ×\92×¢ ×\91×\91×\99צ×\95×¢×\99×\9d. ×\90×\9d ×\96×\94 ×\91×\9b×\9c×\9c ×\90פשר×\99, ×\9b×\93×\90×\99 ×\9cתק×\9f ×\90ת ×\94ער×\9a ×©×\9c <code>suhosin.get.max_value_length</code> ×\9cÖ¾1024 ×\90×\95 ×\99×\95תר ×\91ק×\95×\91×¥ <code>php.ini</code> ×\95×\9c×\94×\92×\93×\99ר ×\90ת â\80\8e<code>$wgResourceLoaderMaxQueryLength</code> לאותו הערך בקובץ LocalSettings.php.',
        'config-db-type' => 'סוג מסד הנתונים:',
        'config-db-host' => 'שרת מסד הנתונים:',
        'config-db-host-help' => 'אם שרת מסד הנתונים שלכם נמצא על שרת אחר, הקלידו את שם המחשב או את כתובת ה־IP כאן.
@@ -7166,7 +7261,7 @@ $1
        'config-support-postgres' => '$1 הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL (ר׳ [http://www.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]). ייתכן שיש בתצורה הזאת באגים מסוימים והיא לא מומלצת לסביבות מבצעיות.',
        'config-support-sqlite' => '* $1 הוא מסד נתונים קליל עם תמיכה טובה מאוד. (ר׳ [http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], משתמש ב־PDO)',
        'config-support-oracle' => '* $1 הוא מסד נתונים עסקי מסחרי. (ר׳ [http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
-       'config-support-ibm_db2' => '* $1 הוא מסד נתונים מסחרי ארגוני.',
+       'config-support-ibm_db2' => '* $1 הוא מסד נתונים מסחרי ארגוני. ([http://www.php.net/manual/en/ibm-db2.installation.php How to compile PHP with IBM DB2 support])',
        'config-header-mysql' => 'הגדרות MySQL',
        'config-header-postgres' => 'הגדרות PostgreSQL',
        'config-header-sqlite' => 'הגדרות SQLite',
@@ -7233,8 +7328,8 @@ chmod a+w $3</pre></div>',
        'config-upgrade-done-no-regenerate' => 'השדרוג הושלם.
 
 עכשיו אפשר [$1 להתחיל להשתמש בוויקי שלכם].',
-       'config-regenerate' => 'לחולל מחדש את LocalSettings.php ←',
-       'config-show-table-status' => 'שאילתת SHOW TABLE STATUS נכשלה!',
+       'config-regenerate' => 'לחולל מחדש את <code>LocalSettings.php</code> ←',
+       'config-show-table-status' => 'שאילתת <code>SHOW TABLE STATUS</code> נכשלה!',
        'config-unknown-collation' => "'''אזהרה:''' מסד הנתונים משתמש בשיטת מיון שאינה מוּכּרת.",
        'config-db-web-account' => 'חשבון במסד הנתונים לגישה מהרשת',
        'config-db-web-help' => 'לבחור את שם המשתמש ואת הססמה ששרת הווב ישתמש בו להתחברות לשרת מסד הנתונים בזמן פעילות רגילה של הוויקי.',
@@ -7306,7 +7401,7 @@ chmod a+w $3</pre></div>',
        'config-optional-continue' => 'הצגת שאלות נוספות.',
        'config-optional-skip' => 'משעמם לי, תתקינו לי כבר את הוויקי הזה.',
        'config-profile' => 'תסריט הרשאות משתמשים:',
-       'config-profile-wiki' => '×\95×\99ק×\99 ×\9eס×\95רת×\99',
+       'config-profile-wiki' => '×\95×\99ק×\99 ×¤×\99ת×\95×\97',
        'config-profile-no-anon' => 'נדרשת יצירת חשבון',
        'config-profile-fishbowl' => 'עורכים מורשים בלבד',
        'config-profile-private' => 'ויקי פרטי',
@@ -7315,7 +7410,7 @@ chmod a+w $3</pre></div>',
 
 עם זאת, אנשים שונים מצאו למדיה־ויקי שימושים מגוּונים ולעתים לא קל לשכנע את כולם ביתרונות של \"דרך הוויקי\" המסורתית. ולכן יש לכם בררה.
 
-באתר '''{{int:config-profile-wiki}}''' – לכולם יש הרשאה לערוך, אפילו בלי להיכנס לחשבון.
+באתר מסוג '''{{int:config-profile-wiki}}''' – לכולם יש הרשאה לערוך, אפילו בלי להיכנס לחשבון.
 באתר וויקי מסוג '''{{int:config-profile-no-anon}}''' יש ביטחון גדול יותר, אבל הגדרה כזאת יכולה להרתיע תורמים מזדמנים.
 
 בתסריט '''{{int:config-profile-fishbowl}}''' רק משתמשים שקיבלו אישור יכולים לערוך, אבל כל הגולשים יכולים לקרוא את הדפים ואת גרסאותיהם הקודמות.
@@ -7406,7 +7501,7 @@ chmod a+w $3</pre></div>',
        'config-install-alreadydone' => "'''אזהרה:''' נראה שכבר התקנתם את מדיה־ויקי ואתם מנסים להתקין אותה שוב.
 אנה התקדמו לדף הבא.",
        'config-install-begin' => 'כשתלחצו על "{{int:config-continue}}", תתחילו את ההתקנה של מדיה־ויקי.
-אם אתם עדיין רוצים לשנות משהו, לחצו על "הקודם".',
+אם אתם עדיין רוצים לשנות משהו, לחצו על "{{int:config-back}}"',
        'config-install-step-done' => 'בוצע',
        'config-install-step-failed' => 'נכשל',
        'config-install-extensions' => 'כולל הרחבות',
@@ -7462,7 +7557,7 @@ $3
 '''שימו לב''': אם לא תעשו זאת עכשיו, קובץ ההגדרות המחוּלל לא יהיה זמין לכם שוב.
 
 אחרי שתעשו את זה, תוכלו '''[$2 להיכנס לוויקי שלכם]'''.",
-       'config-download-localsettings' => 'הורדת LocalSettings.php',
+       'config-download-localsettings' => 'הורדת <code>LocalSettings.php</code>',
        'config-help' => 'עזרה',
        'config-nofile' => 'הקובץ "$1" לא נמצא. האם הוא נמחק?',
        'mainpagetext' => "'''תוכנת מדיה־ויקי הותקנה בהצלחה.'''",
@@ -7471,7 +7566,8 @@ $3
 == קישורים שימושיים ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings רשימת ההגדרות]
 * [//www.mediawiki.org/wiki/Manual:FAQ שאלות ותשובות על מדיה־ויקי]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources תרגום מדיה־ויקי לשפה שלך]',
 );
 
 /** Hindi (हिन्दी)
@@ -7522,6 +7618,7 @@ i [//meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Vodič za suradnike] za po
 
 /** Upper Sorbian (hornjoserbsce)
  * @author Michawiki
+ * @author 아라
  */
 $messages['hsb'] = array(
        'config-desc' => 'Instalaciski program za MediaWiki',
@@ -7529,19 +7626,19 @@ $messages['hsb'] = array(
        'config-information' => 'Informacije',
        'config-localsettings-upgrade' => 'Dataja <code>LocalSettings.php</code> je so wotkryła.
 Zo by tutu instalaciju aktualizował, zapodaj prošu hódnotu za parameter <code>$wgUpgradeKey</code> do slědowaceho pola.
-Namakaš tón parameter w dataji LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Dataja LocalSettings.php bu wotkryta.
-Zo by tutu instalaciju aktualizował, wuwjedźće update.php',
+Namakaš tón parameter w dataji <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Dataja <code>LocalSettings.php</code> bu wotkryta.
+Zo by tutu instalaciju aktualizował, wuwjedźće <code>update.php</code>',
        'config-localsettings-key' => 'Aktualizaciski kluč:',
        'config-localsettings-badkey' => 'Kluč, kotryž sy podał, je wopak',
        'config-upgrade-key-missing' => 'Eksistowaca instalacija MediaWiki je so wotkryła.
-Zo by tutu instalaciju aktualizował, staj prošu slědowacu linku deleka w dataji LocalSettings.php:
+Zo by tutu instalaciju aktualizował, staj prošu slědowacu linku deleka w dataji <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Zda so, zo eksistwoaca dataja LocalSettings.php je njedospołna.
+       'config-localsettings-incomplete' => 'Zda so, zo eksistwoaca dataja <code>LocalSettings.php</code> je njedospołna.
 Wariabla $1 njeje nastajena.
-Prošu změń dataju LocalSettings.php, zo by so tuta wariabla nastajiła a klikń na "Dale".',
-       'config-localsettings-connection-error' => 'Při zwjazowanju z datowej banku z pomocu nastajenjow podatych w LocalSettings.php abo AdminSettings.php je zmylk wustupił. Prošu skoriguj tute nastajenja a spytaj hišće raz.
+Prošu změń dataju <code>LocalSettings.php</code>, zo by so tuta wariabla nastajiła a klikń na "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Při zwjazowanju z datowej banku z pomocu nastajenjow podatych w <code>LocalSettings.php</code> abo <code>AdminSettings.php</code> je zmylk wustupił. Prošu skoriguj tute nastajenja a spytaj hišće raz.
 
 $1',
        'config-session-error' => 'Zmylk při startowanju posedźenja: $1',
@@ -7669,7 +7766,7 @@ Změń ju jenož, jeli su přeswědčiwe přičiny za to.',
        'config-support-mysql' => '* $1 je primarny cil za MediaWiki a podpěruje so najlěpje ([http://www.php.net/manual/en/mysql.installation.php Nawod ke kompilowanju  PHP z  MySQL-podpěru])',
        'config-support-postgres' => '* $1 je popularny system datoweje banki zjawneho žórła jako alternatiwa k MySQL ([http://www.php.net/manual/en/pgsql.installation.php nawod za kompilowanje PHP z podpěru PostgreSQL]). Móhło hišće někotre zmylki eksistować, a njeporuča so jón w produktiwnej wokolinje wužiwać.',
        'config-support-oracle' => '* $1 je komercielna předewzaćelska datowa banka. ([http://www.php.net/manual/en/oci8.installation.php Nawod za kompilowanje PHP z OCI8-podpěru])',
-       'config-support-ibm_db2' => '* $1 je komercielna předewzaćelska datowa banka.',
+       'config-support-ibm_db2' => '* $1 je komercielna předewzaćelska datowa banka. ([http://www.php.net/manual/en/ibm-db2.installation.php How to compile PHP with IBM DB2 support])',
        'config-header-mysql' => 'Nastajenja MySQL',
        'config-header-postgres' => 'Nastajenja PostgreSQL',
        'config-header-sqlite' => 'Nastajenja SQLite',
@@ -7711,8 +7808,8 @@ Zo by je na MediaWiki $1 aktualizował, klikń na '''Dale'''.",
        'config-upgrade-done-no-regenerate' => 'Aktualizacija dokónčena.
 
 Móžeš nětko [$1 swój wiki wužiwać].',
-       'config-regenerate' => 'LocalSettings.php znowa wutworić →',
-       'config-show-table-status' => 'Naprašowanje SHOW TABLE STATUS je so njeporadźiło!',
+       'config-regenerate' => '<code>LocalSettings.php</code> znowa wutworić →',
+       'config-show-table-status' => 'Naprašowanje <code>SHOW TABLE STATUS</code> je so njeporadźiło!',
        'config-unknown-collation' => "'''Warnowanje:''' Datowa banka njeznatu kolaciju wužiwa.",
        'config-db-web-account' => 'Konto datoweje banki za webpřistup',
        'config-db-web-help' => 'wubjer wužiwarske mjeno a hesło, kotrejž webserwer budźe wužiwać, zo by z serwerom datoweje banki za wšědnu operaciju zwjazać',
@@ -7761,7 +7858,7 @@ Móžeš nětko zbytnu konfiguraciju přeskočić a wiki hnydom instalować.',
        'config-optional-continue' => 'Dalše prašenja?',
        'config-optional-skip' => 'Instaluj nětko wiki.',
        'config-profile' => 'Profil wužiwarskich prawow:',
-       'config-profile-wiki' => 'Tradicionelny wiki',
+       'config-profile-wiki' => 'Zjawny wiki',
        'config-profile-no-anon' => 'Załoženje konto je trěbne',
        'config-profile-fishbowl' => 'Jenož awtorizowani wobdźěłarjo',
        'config-profile-private' => 'Priwatny wiki',
@@ -7819,7 +7916,7 @@ To móže sej přidatnu konfiguraciju wužadać, ale móžeš je nětko zmóžni
        'config-install-alreadydone' => "'''Warnowanje:''' Zda so, zo sy hižo MediaWiki instalował a pospytuješ jón znowa instalować.
 Prošu pokročuj z přichodnej stronu.",
        'config-install-begin' => 'Přez kliknjenje na "{{int:config-continue}}" budźe so instalacija MediaWiki startować.
-Jeli hišće chceš něšto změnić, klikń na "Wróćo".',
+Jeli hišće chceš něšto změnić, klikń na "{{int:config-back}}".',
        'config-install-step-done' => 'dokónčene',
        'config-install-step-failed' => 'njeporadźiło',
        'config-install-extensions' => 'Inkluziwnje rozšěrjenja',
@@ -7855,7 +7952,7 @@ Standardna lisćina sp přeskakuje.",
        'config-install-mainpage' => 'Hłowna strona so ze standardnym wobsahom wutworja',
        'config-install-extension-tables' => 'Tabele za zmóžnjene rozšěrjenja so tworja',
        'config-install-mainpage-failed' => 'Powěsć njeda so zasunyć: $1',
-       'config-download-localsettings' => 'LocalSettings.php sćahnyć',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> sćahnyć',
        'config-help' => 'pomoc',
        'config-nofile' => 'Dataja "$1" njeje so namakała. Je so zhašała?',
        'mainpagetext' => "'''MediaWiki bu wuspěšnje instalowany.'''",
@@ -7865,7 +7962,8 @@ Standardna lisćina sp přeskakuje.",
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Wo nastajenjach]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources Localise MediaWiki for your language]',
 );
 
 /** Haitian (Kreyòl ayisyen)
@@ -7885,25 +7983,26 @@ $messages['ht'] = array(
 /** Hungarian (magyar)
  * @author Dani
  * @author Glanthor Reviol
+ * @author 아라
  */
 $messages['hu'] = array(
        'config-desc' => 'A MediaWiki telepítője',
        'config-title' => 'A MediaWiki $1 telepítése',
        'config-information' => 'Információ',
        'config-localsettings-upgrade' => 'Már létezik a <code>LocalSettings.php</code> fájl.
-A telepített szoftver frissítéséhez írd be az alábbi mezőbe a <code>$wgUpgradeKey</code> beállítás értékét, melyet a LocalSettings.php nevű fájlban találhatsz meg.',
-       'config-localsettings-cli-upgrade' => 'A LocalSettings.php fájl megtalálható.
-A telepített rendszer frissítéséhez futtasd az update.php-t.',
+A telepített szoftver frissítéséhez írd be az alábbi mezőbe a <code>$wgUpgradeKey</code> beállítás értékét, melyet a <code>LocalSettings.php</code> nevű fájlban találhatsz meg.',
+       'config-localsettings-cli-upgrade' => 'A <code>LocalSettings.php</code> fájl megtalálható.
+A telepített rendszer frissítéséhez futtasd az <code>update.php</code>-t.',
        'config-localsettings-key' => 'Frissítési kulcs:',
        'config-localsettings-badkey' => 'A megadott kulcs érvénytelen.',
        'config-upgrade-key-missing' => 'A telepítő a MediaWiki meglévő példányát észlelte.
-A telepített rendszer frissítéséhez helyezd el az alábbi sort a LocalSettings.php végére:
+A telepített rendszer frissítéséhez helyezd el az alábbi sort a <code>LocalSettings.php</code> végére:
 
 $1',
-       'config-localsettings-incomplete' => 'A meglévő LocalSettings.php hiányosnak tűnik.
+       'config-localsettings-incomplete' => 'A meglévő <code>LocalSettings.php</code> hiányosnak tűnik.
 A(z) $1 változó értéke nincs beállítva.
-Módosítsd a LocalSettings.php fájlt úgy, hogy ez a változó be legyen állítva, majd kattints a „Folytatás” gombra.',
-       'config-localsettings-connection-error' => 'Nem sikerült csatlakozni az adatbázishoz a LocalSettings.php-ben vagy az AdminSettings.php-ben megadott adatokkal. Ellenőrizd a beállításokat, majd próbáld újra.
+Módosítsd a <code>LocalSettings.php</code> fájlt úgy, hogy ez a változó be legyen állítva, majd kattints a „{{int:Config-continue}}” gombra.',
+       'config-localsettings-connection-error' => 'Nem sikerült csatlakozni az adatbázishoz a <code>LocalSettings.php</code>-ben vagy az <code>AdminSettings.php</code>-ben megadott adatokkal. Ellenőrizd a beállításokat, majd próbáld újra.
 
 $1',
        'config-session-error' => 'Nem sikerült elindítani a munkamenetet: $1',
@@ -8028,7 +8127,7 @@ Telepítés megszakítva.',
        'config-using531' => 'A MediaWiki nem használható a PHP $1-es verziójával, mert hiba van a <code>__call()</code> függvénynek átadott referenciaparaméterekkel.
 A probléma kiküszöböléséhez frissíts a PHP 5.3.2-es verziójára, vagy használd a korábbi, 5.3.0-ásat.
 Telepítés megszakítva.',
-       'config-suhosin-max-value-length' => 'A Suhosin telepítve van, és a GET paraméter hosszát $1 bájtra korlátozza. A MediaWiki erőforrásbetöltő összetevője megkerüli a problémát, de így csökkenni fog a teljesítmény. Ha lehetséges, állítsd be a suhosin.get.max_value_length értékét legalább 1024-re a php.iniben, és állítsd be a $wgResourceLoaderMaxQueryLength változót ugyanerre az értékre a LocalSettings.php-ben.',
+       'config-suhosin-max-value-length' => 'A Suhosin telepítve van, és a GET paraméter hosszát $1 bájtra korlátozza. A MediaWiki erőforrásbetöltő összetevője megkerüli a problémát, de így csökkenni fog a teljesítmény. Ha lehetséges, állítsd be a <code>suhosin.get.max_value_length</code> értékét legalább 1024-re a <code>php.ini</code>ben, és állítsd be a <code>$wgResourceLoaderMaxQueryLength</code> változót ugyanerre az értékre a LocalSettings.php-ben.', # Fuzzy
        'config-db-type' => 'Adatbázis típusa:',
        'config-db-host' => 'Adatbázis hosztneve:',
        'config-db-host-help' => 'Ha az adatbázisszerver másik szerveren található, add meg a hosztnevét vagy az IP-címét.
@@ -8106,7 +8205,7 @@ Ha az alábbi listán nem találod azt a rendszert, melyet használni szeretnél
        'config-support-postgres' => '* A $1 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.',
        'config-support-sqlite' => '* Az $1 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-support-oracle' => '* Az $1 kereskedelmi, vállalati adatbázisrendszer. ([http://www.php.net/manual/en/oci8.installation.php Hogyan fordítható a PHP OCI8-támogatással])',
-       'config-support-ibm_db2' => '* Az $1 kereskedelmi vállalati adatbázisrendszer.',
+       'config-support-ibm_db2' => '* Az $1 kereskedelmi vállalati adatbázisrendszer.', # Fuzzy
        'config-header-mysql' => 'MySQL-beállítások',
        'config-header-postgres' => 'PostgreSQL-beállítások',
        'config-header-sqlite' => 'SQLite-beállítások',
@@ -8173,8 +8272,8 @@ Ez '''nem ajánlott''', csak akkor, ha problémák vannak a wikivel.",
        'config-upgrade-done-no-regenerate' => "A frissítés befejeződött.
 
 Most már '''[$1 beléphetsz a wikibe]'''.",
-       'config-regenerate' => 'LocalSettings.php elkészítése újra →',
-       'config-show-table-status' => 'A SHOW TABLE STATUS lekérdezés nem sikerült!',
+       'config-regenerate' => '<code>LocalSettings.php</code> elkészítése újra →',
+       'config-show-table-status' => 'A <code>SHOW TABLE STATUS</code> lekérdezés nem sikerült!',
        'config-unknown-collation' => "'''Figyelmeztetés:''' az adatbázis ismeretlen egybevetést használ.",
        'config-db-web-account' => 'A webes hozzáférésnél használt adatbázisfiók',
        'config-db-web-help' => 'Add meg azt a felhasználónevet és jelszót, amit a webszerver a wiki általános működése során használ a csatlakozáshoz.',
@@ -8245,7 +8344,7 @@ A további konfigurációt kihagyhatod, és most azonnal elindíthatod a wiki te
        'config-optional-continue' => 'További információk megadása.',
        'config-optional-skip' => 'Épp elég volt, települjön a wiki!',
        'config-profile' => 'Felhasználói jogosultságok profilja:',
-       'config-profile-wiki' => 'Hagyományos wiki',
+       'config-profile-wiki' => 'Hagyományos wiki', # Fuzzy
        'config-profile-no-anon' => 'Felhasználói fiók létrehozása szükséges',
        'config-profile-fishbowl' => 'Csak engedélyezett szerkesztők',
        'config-profile-private' => 'Privát wiki',
@@ -8259,7 +8358,7 @@ Választhatsz!
 
 Lehetőség van arra is, hogy '''{{lc:{{int:config-profile-fishbowl}}}}''' módosíthassák a lapokat, de a nyilvánosság ekkor megtekintheti a lapokat és azok laptörténetét is. '''{{int:config-profile-private}}''' esetén csak az engedélyezett szerkesztők tekinthetik meg a lapokat, és ugyanez a csoport szerkeszthet.
 
-Telepítés után jóval összetettebb jogosultságrendszer állítható össze, további információ a [//www.mediawiki.org/wiki/Manual:User_rights kézikönyv kapcsolódó bejegyzésében].",
+Telepítés után jóval összetettebb jogosultságrendszer állítható össze, további információ a [//www.mediawiki.org/wiki/Manual:User_rights kézikönyv kapcsolódó bejegyzésében].", # Fuzzy
        'config-license' => 'Szerzői jog és licenc:',
        'config-license-none' => 'Nincs licencjelzés',
        'config-license-cc-by-sa' => 'Creative Commons Nevezd meg! - Így add tovább!',
@@ -8343,7 +8442,7 @@ Lehetséges, hogy további beállításra lesz szükség hozzájuk, de már most
        'config-install-alreadydone' => "'''Figyelmeztetés:''' Úgy tűnik, hogy a MediaWiki telepítve van, és te ismét megpróbálod telepíteni.
 Folytasd a következő oldalon.",
        'config-install-begin' => 'A „{{int:config-continue}}” gomb megnyomása elindítja a MediaWiki telepítését.
-Ha szeretnél módosítani a beállításokon, kattints a vissza gombra.',
+Ha szeretnél módosítani a beállításokon, kattints a vissza gombra.', # Fuzzy
        'config-install-step-done' => 'kész',
        'config-install-step-failed' => 'sikertelen',
        'config-install-extensions' => 'Kiterjesztések beillesztése',
@@ -8394,7 +8493,7 @@ $3
 '''Megjegyzés''': Ha ezt most nem teszed meg, és kilépsz a telepítésből, az elkészített konfigurációs fájlt nem tudod elérni a későbbiekben.
 
 Ha végeztél a fájl elhelyezésével, '''[$2 beléphetsz a wikibe]'''.",
-       'config-download-localsettings' => 'LocalSettings.php letöltése',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> letöltése',
        'config-help' => 'segítség',
        'mainpagetext' => "'''A MediaWiki telepítése sikeresen befejeződött.'''",
        'mainpagedocfooter' => "Ha segítségre van szükséged a wikiszoftver használatához, akkor keresd fel a [//meta.wikimedia.org/wiki/Help:Contents User's Guide] oldalt.
@@ -8402,7 +8501,7 @@ Ha végeztél a fájl elhelyezésével, '''[$2 beléphetsz a wikibe]'''.",
 == Alapok (angol nyelven) ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Beállítások listája]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki GyIK]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki-kiadások levelezőlistája]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki-kiadások levelezőlistája]", # Fuzzy
 );
 
 /** Magyar (magázó) (Magyar (magázó))
@@ -8481,7 +8580,7 @@ Ha ezzel készen van, '''[$2 beléphet a wikibe]'''.", # Fuzzy
 == Alapok (angol nyelven) ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Beállítások listája]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki GyIK]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki-kiadások levelezőlistája]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki-kiadások levelezőlistája]", # Fuzzy
 );
 
 /** Armenian (Հայերեն)
@@ -8499,6 +8598,7 @@ $messages['hy'] = array(
 
 /** Interlingua (interlingua)
  * @author McDutchie
+ * @author 아라
  */
 $messages['ia'] = array(
        'config-desc' => 'Le installator de MediaWiki',
@@ -8506,19 +8606,19 @@ $messages['ia'] = array(
        'config-information' => 'Information',
        'config-localsettings-upgrade' => 'Un file <code>LocalSettings.php</code> ha essite detegite.
 Pro actualisar iste installation, per favor entra le valor de <code>$wgUpgradeKey</code> in le quadro hic infra.
-Iste se trova in LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Un file LocalSettings.php file ha essite detegite.
-Pro actualisar iste installation, per favor executa upgrade.php.',
+Iste se trova in <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Un file <code>LocalSettings.php</code> file ha essite detegite.
+Pro actualisar iste installation, per favor executa <code>update.php</code>.',
        'config-localsettings-key' => 'Clave de actualisation:',
        'config-localsettings-badkey' => 'Le clave que tu forniva es incorrecte',
        'config-upgrade-key-missing' => 'Un installation existente de MediaWiki ha essite detegite.
-Pro actualisar iste installation, es necessari adjunger le sequente linea al fin del file LocalSettings.php:
+Pro actualisar iste installation, es necessari adjunger le sequente linea al fin del file <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Le file LocalSettings.php existente pare esser incomplete.
+       'config-localsettings-incomplete' => 'Le file <code>LocalSettings.php</code> existente pare esser incomplete.
 Le variabile $1 non es definite.
-Per favor cambia LocalSettings.php de sorta que iste variabile es definite, e clicca "Continuar".',
-       'config-localsettings-connection-error' => 'Un error esseva incontrate durante le connexion al base de datos usante le configurationes specificate in LocalSettings.php o AdminSettings.php. Per favor repara iste configurationes e tenta lo de novo.
+Per favor cambia <code>LocalSettings.php</code> de sorta que iste variabile es definite, e clicca "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Un error esseva incontrate durante le connexion al base de datos usante le configurationes specificate in <code>LocalSettings.php</code> o <code>AdminSettings.php</code>. Per favor repara iste configurationes e tenta lo de novo.
 
 $1',
        'config-session-error' => 'Error al comenciamento del session: $1',
@@ -8652,7 +8752,7 @@ Installation abortate.',
        'config-using531' => 'MediaWiki non pote esser usate con PHP $1 a causa de un defecto concernente parametros de referentia a <code>__call()</code>.
 Actualisa a PHP 5.3.2 o plus recente, o retrograda a PHP 5.3.0 pro remediar isto.
 Installation abortate.',
-       'config-suhosin-max-value-length' => 'Suhosin es installate e limita le longitude del parametro GET a $1 bytes. Le componente ResourceLoader de MediaWiki pote contornar iste limite, ma isto degradara le rendimento. Si possibile, tu deberea mitter suhosin.get.max_value_length a 1024 o plus in php.ini , e mitter $wgResourceLoaderMaxQueryLength al mesme valor in LocalSettings.php .',
+       'config-suhosin-max-value-length' => 'Suhosin es installate e limita le longitude del parametro GET a $1 bytes. Le componente ResourceLoader de MediaWiki pote contornar iste limite, ma isto degradara le rendimento. Si possibile, tu deberea mitter <code>suhosin.get.max_value_length</code> a 1024 o plus in <code>php.ini</code> , e mitter <code>$wgResourceLoaderMaxQueryLength</code> al mesme valor in LocalSettings.php .', # Fuzzy
        'config-db-type' => 'Typo de base de datos:',
        'config-db-host' => 'Servitor de base de datos:',
        'config-db-host-help' => 'Si tu servitor de base de datos es in un altere servitor, entra hic le nomine o adresse IP del servitor.
@@ -8736,7 +8836,7 @@ Si tu non vide hic infra le systema de base de datos que tu tenta usar, alora se
        'config-support-postgres' => '* $1 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]). Es possibile que resta alcun minor defectos non resolvite, dunque illo non es recommendate pro uso in un ambiente de production.',
        'config-support-sqlite' => '* $1 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-support-oracle' => '* $1 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-support-ibm_db2' => '* $1 es un systema commercial de base de datos pro interprisas.',
+       'config-support-ibm_db2' => '* $1 es un systema commercial de base de datos pro interprisas.', # Fuzzy
        'config-header-mysql' => 'Configuration de MySQL',
        'config-header-postgres' => 'Configuration de PostgreSQL',
        'config-header-sqlite' => 'Configuration de SQLite',
@@ -8803,8 +8903,8 @@ Isto '''non es recommendate''' si tu non ha problemas con tu wiki.",
        'config-upgrade-done-no-regenerate' => 'Actualisation complete.
 
 Tu pote ora [$1 comenciar a usar tu wiki].',
-       'config-regenerate' => 'Regenerar LocalSettings.php →',
-       'config-show-table-status' => 'Le consulta SHOW TABLE STATUS falleva!',
+       'config-regenerate' => 'Regenerar <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Le consulta <code>SHOW TABLE STATUS</code> falleva!',
        'config-unknown-collation' => "'''Aviso:''' Le base de datos usa un collation non recognoscite.",
        'config-db-web-account' => 'Conto de base de datos pro accesso via web',
        'config-db-web-help' => 'Selige le nomine de usator e contrasigno que le servitor web usara pro connecter al servitor de base de datos, durante le operation ordinari del wiki.',
@@ -8876,7 +8976,7 @@ Tu pote ora saltar le configuration remanente e installar le wiki immediatemente
        'config-optional-continue' => 'Pone me plus questiones.',
        'config-optional-skip' => 'Isto me es jam tediose. Simplemente installa le wiki.',
        'config-profile' => 'Profilo de derectos de usator:',
-       'config-profile-wiki' => 'Wiki traditional',
+       'config-profile-wiki' => 'Wiki traditional', # Fuzzy
        'config-profile-no-anon' => 'Creation de conto obligatori',
        'config-profile-fishbowl' => 'Modificatores autorisate solmente',
        'config-profile-private' => 'Wiki private',
@@ -8892,7 +8992,7 @@ Un wiki con '''{{int:config-profile-no-anon}}''' attribue additional responsabil
 Le scenario '''{{int:config-profile-fishbowl}}''' permitte al usatores approbate de modificar, ma le publico pote vider le paginas, includente lor historia.
 Un '''{{int:config-profile-private}}''' permitte solmente al usatores approbate de vider le paginas e de modificar los.
 
-Configurationes de derectos de usator plus complexe es disponibile post installation, vide le [//www.mediawiki.org/wiki/Manual:User_rights pertinente section del manual].",
+Configurationes de derectos de usator plus complexe es disponibile post installation, vide le [//www.mediawiki.org/wiki/Manual:User_rights pertinente section del manual].", # Fuzzy
        'config-license' => 'Copyright e licentia:',
        'config-license-none' => 'Nulle licentia in pede de paginas',
        'config-license-cc-by-sa' => 'Creative Commons Attribution Share Alike',
@@ -8977,7 +9077,7 @@ Istes pote requirer additional configuration, ma tu pote activar los ora.',
        'config-install-alreadydone' => "'''Aviso:''' Il pare que tu ha jam installate MediaWiki e tenta installar lo de novo.
 Per favor continua al proxime pagina.",
        'config-install-begin' => 'Un clic sur "{{int:config-continue}}" comencia le installation de MediaWiki.
-Pro facer alterationes, clicca sur "Retro".',
+Pro facer alterationes, clicca sur "Retro".', # Fuzzy
        'config-install-step-done' => 'finite',
        'config-install-step-failed' => 'fallite',
        'config-install-extensions' => 'Include le extensiones',
@@ -9034,7 +9134,7 @@ $3
 '''Nota''': Si tu non discarga iste file de configuration ora, illo non essera disponibile plus tarde.
 
 Post facer isto, tu pote '''[$2 entrar in tu wiki]'''.",
-       'config-download-localsettings' => 'Discargar LocalSettings.php',
+       'config-download-localsettings' => 'Discargar <code>LocalSettings.php</code>',
        'config-help' => 'adjuta',
        'config-nofile' => 'Le file "$1" non poteva esser trovate. Ha illo essite delite?',
        'mainpagetext' => "'''MediaWiki ha essite installate con successo.'''",
@@ -9043,7 +9143,7 @@ Post facer isto, tu pote '''[$2 entrar in tu wiki]'''.",
 == Pro initiar ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Lista de configurationes]
 * [//www.mediawiki.org/wiki/Manual:FAQ FAQ a proposito de MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de diffusion pro annuncios de nove versiones de MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de diffusion pro annuncios de nove versiones de MediaWiki]', # Fuzzy
 );
 
 /** Indonesian (Bahasa Indonesia)
@@ -9051,6 +9151,7 @@ Post facer isto, tu pote '''[$2 entrar in tu wiki]'''.",
  * @author IvanLanin
  * @author Kenrick95
  * @author Reedy
+ * @author 아라
  */
 $messages['id'] = array(
        'config-desc' => 'Penginstal untuk MediaWiki',
@@ -9058,19 +9159,19 @@ $messages['id'] = array(
        'config-information' => 'Informasi',
        'config-localsettings-upgrade' => 'Berkas <code>LocalSettings.php</code> sudah ada.
 Untuk memutakhirkan instalasi ini, masukkan nilai <code>$wgUpgradeKey</code> dalam kotak yang tersedia di bawah ini.
-Anda dapat menemukan nilai tersebut dalam LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Berkas LocalSettings.php terdeteksi.
-Untuk meningkatkan versi, harap jalankan update.php.',
+Anda dapat menemukan nilai tersebut dalam <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Berkas <code>LocalSettings.php</code> terdeteksi.
+Untuk meningkatkan versi, harap jalankan <code>update.php</code>.',
        'config-localsettings-key' => 'Kunci pemutakhiran:',
        'config-localsettings-badkey' => 'Kunci yang Anda berikan tidak benar',
        'config-upgrade-key-missing' => 'Suatu instalasi MediaWiki telah terdeteksi.
-Untuk memutakhirkan instalasi ini, silakan masukkan baris berikut di bagian bawah LocalSettings.php Anda:
+Untuk memutakhirkan instalasi ini, silakan masukkan baris berikut di bagian bawah <code>LocalSettings.php</code> Anda:
 
 $1',
-       'config-localsettings-incomplete' => 'LocalSettings.php yang ada tampaknya tidak lengkap.
+       'config-localsettings-incomplete' => '<code>LocalSettings.php</code> yang ada tampaknya tidak lengkap.
 Variabel $1 tidak diatur.
-Silakan ubah LocalSettings.php untuk mengatur variabel ini dan klik "Lanjutkan".',
-       'config-localsettings-connection-error' => 'Timbul galat saat menghubungkan ke basis data dengan menggunakan setelan yang ditentukan di LocalSettings.php atau AdminSettings.php. Harap perbaiki setelan ini dan coba lagi.
+Silakan ubah <code>LocalSettings.php</code> untuk mengatur variabel ini dan klik "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Timbul galat saat menghubungkan ke basis data dengan menggunakan setelan yang ditentukan di <code>LocalSettings.php</code> atau <code>AdminSettings.php</code>. Harap perbaiki setelan ini dan coba lagi.
 
 $1',
        'config-session-error' => 'Kesalahan sesi mulai: $1',
@@ -9194,7 +9295,7 @@ Instalasi dibatalkan.',
        'config-using531' => 'MediaWiki tidak dapat dijalankan dengan PHP $1 karena bug yang melibatkan parameter referensi untuk <code>__call()</code> .
 Tingkatkan ke PHP 5.3.2 atau lebih baru, atau turunkan ke PHP versi 5.3.0 untuk menyelesaikan hal ini.
 Instalasi dibatalkan.',
-       'config-suhosin-max-value-length' => 'Suhosin terpasang dan membatasi panjang parameter GET sebesar $1 bita. Komponen ResourceLoader MediaWiki akan mengatasi batasan ini, tapi penanganannya akan menurunkan kinerja. Jika memungkinkan, Anda sebaiknya menetapkan nilai suhosin.get.max_value_length menjadi 1024 atau lebih tinggi dalam php.ini dan menyetel $wgResourceLoaderMaxQueryLength dengan nilai yang sama dalam LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'Suhosin terpasang dan membatasi panjang parameter GET sebesar $1 bita. Komponen ResourceLoader MediaWiki akan mengatasi batasan ini, tapi penanganannya akan menurunkan kinerja. Jika memungkinkan, Anda sebaiknya menetapkan nilai <code>suhosin.get.max_value_length</code> menjadi 1024 atau lebih tinggi dalam <code>php.ini</code> dan menyetel <code>$wgResourceLoaderMaxQueryLength</code> dengan nilai yang sama dalam LocalSettings.php.', # Fuzzy
        'config-db-type' => 'Jenis basis data:',
        'config-db-host' => 'Inang basis data:',
        'config-db-host-help' => 'Jika server basis data Anda berada di server yang berbeda, masukkan nama inang atau alamat IP di sini.
@@ -9276,7 +9377,7 @@ Jika Anda tidak melihat sistem basis data yang Anda gunakan tercantum di bawah i
        'config-support-postgres' => '* $1 adalah sistem basis data sumber terbuka populer sebagai alternatif untuk MySQL ([http://www.php.net/manual/en/pgsql.installation.php cara mengompilasi PHP dengan dukungan PostgreSQL]). Mungkin ada beberapa bug terbuka dan alternatif ini tidak direkomendasikan untuk dipakai dalam lingkungan produksi.',
        'config-support-sqlite' => '* $1 adalah sistem basis data yang ringan yang sangat baik dukungannya. ([http://www.php.net/manual/en/pdo.installation.php cara mengompilasi PHP dengan dukungan SQLite], menggunakan PDO)',
        'config-support-oracle' => '* $1 adalah basis data komersial untuka perusahaan. ([http://www.php.net/manual/en/oci8.installation.php cara mengompilasi PHP dengan dukungan OCI8])',
-       'config-support-ibm_db2' => '* $1 adalah basis data-perusahaan komersial.',
+       'config-support-ibm_db2' => '* $1 adalah basis data-perusahaan komersial.', # Fuzzy
        'config-header-mysql' => 'Pengaturan MySQL',
        'config-header-postgres' => 'Pengaturan PostgreSQL',
        'config-header-sqlite' => 'Pengaturan SQLite',
@@ -9343,8 +9444,8 @@ Tindakan ini '''tidak dianjurkan''' kecuali jika Anda mengalami masalah dengan w
        'config-upgrade-done-no-regenerate' => 'Pemutakhiran selesai.
 
 Anda sekarang dapat [$1 mulai menggunakan wiki Anda].',
-       'config-regenerate' => 'Regenerasi LocalSettings.php →',
-       'config-show-table-status' => 'Kueri SHOW TABLE STATUS gagal!',
+       'config-regenerate' => 'Regenerasi <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Kueri <code>SHOW TABLE STATUS</code> gagal!',
        'config-unknown-collation' => "'''Peringatan:''' basis data menggunakan kolasi yang tidak dikenal.",
        'config-db-web-account' => 'Akun basis data untuk akses web',
        'config-db-web-help' => 'Masukkan nama pengguna dan sandi yang akan digunakan server web untuk terhubung ke server basis data saat operasi normal wiki.',
@@ -9407,7 +9508,7 @@ Anda sekarang dapat melewati sisa konfigurasi dan menginstal wiki sekarang.',
        'config-optional-continue' => 'Berikan saya pertanyaan lagi.',
        'config-optional-skip' => 'Saya sudah bosan, instal saja wikinya.',
        'config-profile' => 'Profil hak pengguna:',
-       'config-profile-wiki' => 'Wiki tradisional',
+       'config-profile-wiki' => 'Wiki tradisional', # Fuzzy
        'config-profile-no-anon' => 'Pembuatan akun diperlukan',
        'config-profile-fishbowl' => 'Khusus penyunting terdaftar',
        'config-profile-private' => 'Wiki pribadi',
@@ -9421,7 +9522,7 @@ Namun, berbagai kegunaan lain dari MediaWiki telah ditemukan, dan kadang tidak m
 '''{{int:config-profile-fishbowl}}''' memungkinkan pengguna yang disetujui untuk menyunting, tetapi publik dapat melihat halaman, termasuk riwayatnya.
 '''{{int:config-profile-private}}''' hanya memungkinkan pengguna yang disetujui untuk melihat dan menyunting halaman.
 
-Konfigurasi hak pengguna yang lebih kompleks tersedia setelah instalasi. Lihat [//www.mediawiki.org/wiki/Manual:User_rights/id entri manual terkait].",
+Konfigurasi hak pengguna yang lebih kompleks tersedia setelah instalasi. Lihat [//www.mediawiki.org/wiki/Manual:User_rights/id entri manual terkait].", # Fuzzy
        'config-license' => 'Hak cipta dan lisensi:',
        'config-license-none' => 'Tidak ada lisensi',
        'config-license-cc-by-sa' => 'Creative Commons Atribusi Berbagi Serupa',
@@ -9506,7 +9607,7 @@ Ekstensi tersebut mungkin memerlukan konfigurasi tambahan, tetapi Anda dapat men
        'config-install-alreadydone' => "'''Peringatan:''' Anda tampaknya telah menginstal MediaWiki dan mencoba untuk menginstalnya lagi.
 Lanjutkan ke halaman berikutnya.",
        'config-install-begin' => 'Dengan menekan "{{int:config-continue}}", Anda akan memulai instalasi MediaWiki.
-Jika Anda masih ingin membuat perubahan, tekan "{{int:config-back}}".',
+Jika Anda masih ingin membuat perubahan, tekan "{{int:config-back}}".', # Fuzzy
        'config-install-step-done' => 'selesai',
        'config-install-step-failed' => 'gagal',
        'config-install-extensions' => 'Termasuk ekstensi',
@@ -9554,7 +9655,7 @@ $3
 '''Catatan''': Jika Anda tidak melakukannya sekarang, berkas konfigurasi yang dihasilkan ini tidak akan tersedia lagi setelah Anda keluar dari proses instalasi tanpa mengunduhnya.
 
 Setelah melakukannya, Anda dapat '''[$2 memasuki wiki Anda]'''.",
-       'config-download-localsettings' => 'Unduh LocalSettings.php',
+       'config-download-localsettings' => 'Unduh <code>LocalSettings.php</code>',
        'config-help' => 'bantuan',
        'config-nofile' => 'Berkas "$1" tidak dapat ditemukan. Mungkin sudah dihapus?',
        'mainpagetext' => "'''MediaWiki telah terpasang dengan sukses'''.",
@@ -9632,6 +9733,7 @@ $messages['is'] = array(
  * @author F. Cosoleto
  * @author Gianfranco
  * @author Karika
+ * @author 아라
  */
 $messages['it'] = array(
        'config-desc' => 'Il programma di installazione per MediaWiki',
@@ -9639,19 +9741,19 @@ $messages['it'] = array(
        'config-information' => 'Informazioni',
        'config-localsettings-upgrade' => 'È stato rilevato un file <code>LocalSettings.php</code>.
 Per aggiornare questa installazione, si prega di inserire il valore di <code>$wgUpgradeKey</code> nella casella qui sotto.
-Lo potete trovare in LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'È stato rilevato un file LocalSettings.php.
-Per aggiornare questa installazione, eseguire update.php',
+Lo potete trovare in <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'È stato rilevato un file <code>LocalSettings.php</code>.
+Per aggiornare questa installazione, eseguire <code>update.php</code>',
        'config-localsettings-key' => 'Chiave di aggiornamento:',
        'config-localsettings-badkey' => 'La chiave che hai fornito non è corretta.',
        'config-upgrade-key-missing' => "È stata rilevata un'installazione esistente di MediaWiki.
-Per aggiornare questa installazione, si prega di inserire la seguente riga nella parte inferiore del tuo LocalSettings.php:
+Per aggiornare questa installazione, si prega di inserire la seguente riga nella parte inferiore del tuo <code>LocalSettings.php</code>:
 
 $1",
-       'config-localsettings-incomplete' => 'Il file LocalSettings.php esistente sembra essere incompleto.
+       'config-localsettings-incomplete' => 'Il file <code>LocalSettings.php</code> esistente sembra essere incompleto.
 La variabile $1 non è impostata.
-Cambia LocalSettings.php in modo che questa variabile sia impostata e fai clic su "Continua".',
-       'config-localsettings-connection-error' => 'Si è verificato un errore durante la connessione al database utilizzando le impostazioni specificate in LocalSettings.php o AdminSettings.php. Si prega di correggere queste impostazioni e riprovare.
+Cambia <code>LocalSettings.php</code> in modo che questa variabile sia impostata e fai clic su "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Si è verificato un errore durante la connessione al database utilizzando le impostazioni specificate in <code>LocalSettings.php</code> o <code>AdminSettings.php</code>. Si prega di correggere queste impostazioni e riprovare.
 
 $1',
        'config-session-error' => "Errore nell'avvio della sessione: $1",
@@ -9840,7 +9942,7 @@ In precedenza Wikipedia ha utilizzato la GNU Free Documentation License. La GFDL
        'config-install-subscribe-notpossible' => 'cURL non è installato e allow_url_fopen non è disponibile.',
        'config-install-mainpage' => 'Creazione della pagina principale con contenuto predefinito',
        'config-install-mainpage-failed' => 'Impossibile inserire la pagina principale: $1',
-       'config-download-localsettings' => 'Scarica LocalSettings.php',
+       'config-download-localsettings' => 'Scarica <code>LocalSettings.php</code>',
        'config-help' => 'aiuto',
        'config-nofile' => 'Il file "$1" non può essere trovato. È stato eliminato?',
        'mainpagetext' => "'''Installazione di MediaWiki completata correttamente.'''",
@@ -9872,18 +9974,22 @@ $messages['ja'] = array(
        'config-information' => '情報',
        'config-localsettings-upgrade' => 'ファイル <code>LocalSettings.php</code> を検出しました。
 インストールされているものをアップグレードするには、<code>$wgUpgradeKey</code> の値を以下の欄に入力してください。
-この値は LocalSettings.php 内にあります。',
-       'config-localsettings-cli-upgrade' => 'ファイル LocalSettings.php を検出しました。
-インストールされているものをアップグレードするには、update.php を実行してください',
+この値は <code>LocalSettings.php</code> 内にあります。',
+       'config-localsettings-cli-upgrade' => 'ファイル <code>LocalSettings.php</code> を検出しました。
+インストールされているものをアップグレードするには、<code>update.php</code> を実行してください',
        'config-localsettings-key' => 'アップグレード キー:',
        'config-localsettings-badkey' => '与えられたキーが間違っています',
        'config-upgrade-key-missing' => 'MediaWiki が既にインストールされていることを検出しました。
-インストールされているものをアップグレードするために、以下の行を LocalSettings.php の末尾に挿入してください:
+インストールされているものをアップグレードするために、以下の行を <code>LocalSettings.php</code> の末尾に挿入してください:
 
 $1',
-       'config-localsettings-incomplete' => '既存の LocalSettings.php の内容は不完全のようです。
+       'config-localsettings-incomplete' => '既存の <code>LocalSettings.php</code> の内容は不完全のようです。
 変数 $1 が設定されていません。
-LocalSettings.php 内でこの変数を設定して、「{{int:Config-continue}}」をクリックしてください。',
+<code>LocalSettings.php</code> 内でこの変数を設定して、「{{int:Config-continue}}」をクリックしてください。',
+       'config-localsettings-connection-error' => '<code>LocalSettings.php</code> または <code>AdminSettings.php</code> で指定した設定を使用してデータベースに接続する際にエラーが発生しました。
+設定を修正してから再度試してください。
+
+$1',
        'config-session-error' => 'セッションの開始エラー: $1',
        'config-session-expired' => 'セッションの有効期限が切れたようです。
 セッションの有効期間は$1に設定されています。
@@ -9912,7 +10018,7 @@ php.ini 内で <code>session.save_path</code> が適切なディレクトリに
        'config-page-copying' => 'コピー',
        'config-page-upgradedoc' => 'アップグレード',
        'config-page-existingwiki' => '既存のウィキ',
-       'config-help-restart' => '入力した保存データをすべて消去して、インストール作業を再起動しますか',
+       'config-help-restart' => '入力した保存データをすべて消去して、インストール作業を再起動しますか?',
        'config-restart' => 'はい、再起動します',
        'config-welcome' => '=== 環境の確認 ===
 基本的な確認では、現在の環境がMediaWikiのインストールに適しているかを確認します。
@@ -9920,12 +10026,12 @@ php.ini 内で <code>session.save_path</code> が適切なディレクトリに
        'config-copyright' => '=== 著作権および規約 ===
 $1
 
-この作品はフリーソフトウェアです。あなたは、フリーソフトウェア財団の発行するGNU一般公衆利用許諾書 (GNU General Public License)(バージョン2、またはそれ以降のライセンス)の規約に基づき、このライブラリを再配布および改変できます。
+この作品はフリーソフトウェアです。あなたは、フリーソフトウェア財団の発行するGNU一般公衆利用許諾書 (GNU General Public License) (バージョン2、またはそれ以降のライセンス) の規約に基づき、このライブラリを再配布および改変できます。
 
 この作品は、有用であることを期待して配布されていますが、商用あるいは特定の目的に適するかどうかも含めて、暗黙的にも、一切保証されません。
 詳しくは、GNU一般公衆利用許諾書をご覧ください。
 
-あなたはこのプログラムと共に、<doclink href=Copying>GNU一般公衆利用許諾契約書の複製</doclink>を一部受け取ったはずです。もし受け取っていなければ、フリーソフトウェア財団(宛先は the Free Software Foundation, Inc., 59Temple Place, Suite 330, Boston, MA 02111-1307 USA)まで請求してください。',
+あなたはこのプログラムと共に、<doclink href=Copying>GNU一般公衆利用許諾契約書の複製</doclink>を一部受け取ったはずです。受け取っていない場合は、フリーソフトウェア財団 (宛先は the Free Software Foundation, Inc., 59Temple Place, Suite 330, Boston, MA 02111-1307 USA) まで請求してください。',
        'config-sidebar' => '* [//www.mediawiki.org MediaWikiのホーム]
 * [//www.mediawiki.org/wiki/Help:Contents 利用者向け案内]
 * [//www.mediawiki.org/wiki/Manual:Contents 管理者向け案内]
@@ -9955,21 +10061,21 @@ Unicode を少しでも利用する可能性がある場合は、[//www.mediawik
 PHP を自分でコンパイルした場合は、例えば <code>./configure --with-mysql</code> を実行して、データベース クライアントを使用できるように再設定してください。
 Debian または Ubuntu のパッケージから PHP をインストールした場合は、php5-mysql モジュールもインストールする必要があります。',
        'config-no-fts3' => "'''警告''': SQLite は [//sqlite.org/fts3.html FTS3] モジュールなしでコンパイルされており、このバックエンドでは検索機能は利用できなくなります。",
-       'config-register-globals' => "'''警告:PHPの<code>[http://php.net/register_globals register_globals]</code>オプションが有効になっています。'''
+       'config-register-globals' => "'''警告: PHP の <code>[http://php.net/register_globals register_globals]</code> オプションが有効になっています。'''
 '''可能なら無効化してください。'''
-MediaWikiは動作しますが、サーバーは、潜在的なセキュリティ脆弱性を露呈します。",
-       'config-magic-quotes-runtime' => "'''致命的エラー:[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime]が動作しています!'''
+MediaWiki は動作しますが、サーバーの潜在的なセキュリティ脆弱性が露呈されます。",
+       'config-magic-quotes-runtime' => "'''致命的エラー: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime] が動作しています!'''
 このオプションは、予期せずデータ入力を破壊します。
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81\8cç\84¡å\8a¹å\8c\96ã\81\95ã\82\8cã\81ªã\81\84ã\81\8bã\81\8eã\82\8aã\80\81MediaWikiã\82\92ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\97å\88©ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
-       'config-magic-quotes-sybase' => "'''致命的エラー:[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-sybase magic_quotes_sybase]が動作しています!'''
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\92ç\84¡å\8a¹å\8c\96ã\81\97ã\81ªã\81\84é\99\90ã\82\8aã\80\81MediaWiki ã\81®ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\82\84使ç\94¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
+       'config-magic-quotes-sybase' => "'''致命的エラー: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-sybase magic_quotes_sybase] が動作しています!'''
 このオプションは、予期せずデータ入力を破壊します。
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81\8cç\84¡å\8a¹å\8c\96ã\81\95ã\82\8cã\81ªã\81\84ã\81\8bã\81\8eã\82\8aã\80\81MediaWikiã\82\92ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\97å\88©ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
-       'config-mbstring' => "'''致命的エラー:[http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload]が動作しています!'''
-このオプションは、エラーを引き起こし、予期せずデータ入力を破壊する可能性があります。
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81\8cç\84¡å\8a¹å\8c\96ã\81\95ã\82\8cã\81ªã\81\84ã\81\8bã\81\8eã\82\8aã\80\81MediaWikiã\82\92ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\97å\88©ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
-       'config-ze1' => "'''致命的エラー:[http://www.php.net/manual/en/ini.core.php zend.ze1_compatibility_mode]が動作しています!'''
-このオプションは、MediaWikiにおいて深刻なバグを引き起こします。
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81\8cç\84¡å\8a¹å\8c\96ã\81\95ã\82\8cã\81ªã\81\84ã\81\8bã\81\8eã\82\8aã\80\81MediaWikiã\82\92ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\97å\88©ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\92ç\84¡å\8a¹å\8c\96ã\81\97ã\81ªã\81\84é\99\90ã\82\8aã\80\81MediaWiki ã\81®ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\82\84使ç\94¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
+       'config-mbstring' => "'''致命的エラー: [http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload] が動作しています!'''
+このオプションは、エラーを引き起こし、予期せずデータを破壊するおそれがあります。
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\92ç\84¡å\8a¹å\8c\96ã\81\97ã\81ªã\81\84é\99\90ã\82\8aã\80\81MediaWiki ã\81®ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\82\84使ç\94¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
+       'config-ze1' => "'''致命的エラー: [http://www.php.net/manual/en/ini.core.php zend.ze1_compatibility_mode] が動作しています!'''
+このオプションは、MediaWiki において深刻なバグを引き起こします。
\81\93ã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\92ç\84¡å\8a¹å\8c\96ã\81\97ã\81ªã\81\84é\99\90ã\82\8aã\80\81MediaWiki ã\81®ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\82\84使ç\94¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
        'config-safe-mode' => "'''警告:''' PHPの[http://www.php.net/features.safe-mode セーフモード]が有効になっています。
 特に、ファイルのアップロードや<code>math</code>機能で、問題が発生するおそれがあります。",
        'config-xml-bad' => 'PHPのXMLモジュールが不足しています。
@@ -9989,8 +10095,8 @@ MediaWiki を正しく動作させるには、UTF-8 対応が必要です。",
        'config-no-cache' => "'''警告:''' [http://www.php.net/apc APC]、[http://xcache.lighttpd.net/ XCache]、[http://www.iis.net/download/WinCacheForPhp WinCache] のいずれも見つかりませんでした。
 オブジェクトのキャッシュは有効化されません。",
        'config-diff3-bad' => 'GNU diff3 が見つかりません。',
-       'config-imagemagick' => 'ImageMagickが見つかりました<code>$1</code>。
\82¢ã\83\83ã\83\97ã\83­ã\83¼ã\83\89ã\81\8cæ\9c\89å\8a¹ã\81ªã\82\89ã\80\81ç\94»å\83\8fã\81®ã\82µã\83 ã\83\8dã\82¤ã\83«ã\81\8c利用できます。',
+       'config-imagemagick' => 'ImageMagickが見つかりました<code>$1</code>。
\82¢ã\83\83ã\83\97ã\83­ã\83¼ã\83\89ã\81\8cæ\9c\89å\8a¹ã\81§ã\81\82ã\82\8cã\81°ã\80\81ç\94»å\83\8fã\81®ã\82µã\83 ã\83\8dã\82¤ã\83«ã\82\92利用できます。',
        'config-gd' => 'GD画像ライブラリが内蔵されていることが確認されました。
 アップロードが有効なら、画像のサムネイルが利用できます。',
        'config-no-scaling' => 'GDライブラリもImageMagickも見つかりませんでした。
@@ -10008,7 +10114,9 @@ PHPを5.2.9かそれ以降のバージョンに、libxml2を2.7.3かそれ以降
        'config-using531' => 'PHP$1は<code>__call()</code>の引数参照に関するバグのため、MediaWikiと互換性がありません。
 PHP5.3.2以降に更新するか、この([//bugs.php.net/bug.php?id=50394 PHPに提出されたバグ])を修正するためにPHP5.3.0へ戻してください。
 インストールは中止されました。',
-       'config-suhosin-max-value-length' => 'Suhosin がインストールされており、GETパラメータの長さを $1 バイトに制限しています。MediaWiki の ResourceLoader コンポーネントはこの制限を回避しますが、パフォーマンスは低下します。可能な限り、php.ini で suhosin.get.max_value_length を 1024 以上に設定し、同じ値を LocalSettings.php 中で $wgResourceLoaderMaxQueryLength に設定してください。',
+       'config-suhosin-max-value-length' => 'Suhosin がインストールされており、GET パラメーターの <code>length</code> を $1 バイトに制限しています。
+MediaWiki の ResourceLoader コンポーネントはこの制限を回避しますが、パフォーマンスは低下します。
+可能な限り、<code>php.ini</code> で <code>suhosin.get.max_value_length</code> を 1024 以上に設定し、同じ値を <code>LocalSettings.php</code> 内で <code>$wgResourceLoaderMaxQueryLength</code> に設定してください。',
        'config-db-type' => 'データベースの種類:',
        'config-db-host' => 'データベースのホスト:',
        'config-db-host-help' => '異なるサーバー上にデータベースサーバーがある場合、ホスト名またはIPアドレスをここに入力してください。
@@ -10085,11 +10193,11 @@ PostgreSQLを使用している場合、UNIXソケットで接続するにはこ
 $1
 
 使用しようとしているデータベース システムが下記の一覧にない場合は、上記リンク先の手順に従ってインストールしてください。',
-       'config-support-mysql' => '* $1ã\81¯MediaWikiã\81®ä¸»è¦\81ã\81ªå¯¾è±¡ã\81§ã\80\81ã\82\82ã\81£ã\81¨ã\82\82ã\82µã\83\9dã\83¼ã\83\88ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ï¼\88[http://www.php.net/manual/en/mysql.installation.php MySQLã\81®ã\82µã\83\9dã\83¼ã\83\88ä¸\8bã\81§PHPã\82\92ã\82³ã\83³ã\83\91ã\82¤ã\83«ã\81\99ã\82\8bæ\96¹æ³\95]ï¼\89',
-       'config-support-postgres' => '* $1は、MySQLの代替として、人気のあるオープンソースデータベースシステムです([http://www.php.net/manual/en/pgsql.installation.php PostgreSQLのサポート下でPHPをコンパイルする方法])',
-       'config-support-sqlite' => '* $1は、良くサポートされている、軽量データベースシステムです。([http://www.php.net/manual/en/pdo.installation.php SQLiteのサポート下でPHPをコンパイルする方法]、PDOを使用)',
-       'config-support-oracle' => '* $1は商業企業のデータベースです。([http://www.php.net/manual/en/oci8.installation.php OCI8サポートなPHPをコンパイルする方法])',
-       'config-support-ibm_db2' => '* $1 は商業企業のデータベースです。',
+       'config-support-mysql' => '* $1ã\81¯MediaWikiã\81®ä¸»è¦\81ã\81ªå¯¾è±¡ã\81§ã\81\82ã\82\8aã\80\81æ\9c\80ã\82\82ã\82µã\83\9dã\83¼ã\83\88ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99 ([http://www.php.net/manual/en/mysql.installation.php MySQLã\81«å¯¾å¿\9cã\81\97ã\81\9fPHPã\82\92ã\82³ã\83³ã\83\91ã\82¤ã\83«ã\81\99ã\82\8bæ\96¹æ³\95])',
+       'config-support-postgres' => '* $1は、MySQLの代替として人気があるオープンソースのデータベースシステムです ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQLに対応したPHPをコンパイルする方法])',
+       'config-support-sqlite' => '* $1は、良くサポートされている、軽量データベースシステムです。([http://www.php.net/manual/ja/pdo.installation.php SQLiteに対応したPHPをコンパイルする方法]、PDOを使用)',
+       'config-support-oracle' => '* $1は商業企業のデータベースです。([http://www.php.net/manual/en/oci8.installation.php OCI8サポートなPHPをコンパイルする方法])',
+       'config-support-ibm_db2' => '* $1 は商業企業のデータベースです。([http://www.php.net/manual/en/ibm-db2.installation.php IBM DB2に対応したPHPをコンパイルする方法])',
        'config-header-mysql' => 'MySQL の設定',
        'config-header-postgres' => 'PostgreSQL の設定',
        'config-header-sqlite' => 'SQLite の設定',
@@ -10154,8 +10262,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => 'アップグレードが完了しました。
 
 [$1 ウィキの使用を開始]することができます。',
-       'config-regenerate' => 'LocalSettings.phpを再生成→',
-       'config-show-table-status' => 'SHOW TABLE STATUS クエリが失敗しました!',
+       'config-regenerate' => '<code>LocalSettings.php</code> を再生成→',
+       'config-show-table-status' => '<code>SHOW TABLE STATUS</code> クエリが失敗しました!',
        'config-unknown-collation' => "'''警告:''' データベースは認識されない照合を使用しています。",
        'config-db-web-account' => 'ウェブアクセスのためのデータベースアカウント',
        'config-db-web-help' => 'ウィキの通常の操作の際に、ウェブ サーバーがデータベース サーバーに接続できるように、ユーザー名とパスワードを指定してください。',
@@ -10170,7 +10278,7 @@ chmod a+w $3</pre>',
 
 '''MyISAM'''は、利用者が1人の場合、あるいは読み込み専用でインストールする場合に、より処理が早くなるでしょう。
 ただし、MyISAMのデータベースは、InnoDBより高頻度で破損する傾向があります。",
-       'config-mysql-charset' => 'データベースの文字セット',
+       'config-mysql-charset' => 'データベースの文字セット:',
        'config-mysql-binary' => 'バイナリ',
        'config-mysql-utf8' => 'UTF-8',
        'config-mysql-charset-help' => "'''バイナリ モード'''では、MediaWiki は、UTF-8 テキストをデータベースのバイナリ フィールドに格納します。
@@ -10208,7 +10316,7 @@ chmod a+w $3</pre>',
        'config-admin-error-user' => '"<nowiki>$1</nowiki>"という名前の管理者を作成する際に内部エラーが発生しました。',
        'config-admin-error-password' => '管理者"<nowiki>$1</nowiki>"のパスワードを設定する際に内部エラーが発生しました: <pre>$2</pre>',
        'config-subscribe' => '[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce リリース告知のメーリングリスト]を購読する。',
-       'config-subscribe-help' => 'これは、リリースの告知(重要なセキュリティに関する案内を含む)に使われる、低容量のメーリングリストです。
+       'config-subscribe-help' => 'これは、リリースの告知 (重要なセキュリティに関する案内を含む) に使用される、流量が少ないメーリングリストです。
 このメーリングリストを購読して、新しいバージョンが出た場合にMediaWikiを更新してください。',
        'config-almost-done' => 'これでほぼ終わりました!
 残りの設定を飛ばして、ウィキを今すぐインストールできます。',
@@ -10297,8 +10405,8 @@ GFDLは有効なライセンスですが、内容を理解するのは困難で
 中〜大規模サイトではこれを有効にすることを強くお勧めします。小規模サイトでも同様に効果があります。',
        'config-cache-none' => 'キャッシングしない(機能は取り払われます、しかもより大きなウィキサイト上でスピードの問題が発生します)',
        'config-cache-accel' => 'PHP オブジェクト キャッシュ (APC、XCache、WinCache のいずれか)',
-       'config-cache-memcached' => 'Memcachedを使用(追加の設定が必要です)',
-       'config-memcached-servers' => 'メモリをキャッシュされたサーバ:',
+       'config-cache-memcached' => 'memcached を使用 (追加の設定が必要)',
+       'config-memcached-servers' => 'memcached サーバー:',
        'config-memcached-help' => 'Memcachedを使用するIPアドレスの一覧。
 カンマ区切りで、利用する特定のポートの指定が必要です。例:
 127.0.0.1:11211
@@ -10355,7 +10463,7 @@ $3
 '''注意''': この生成された設定ファイルをダウンロードせずにインストールを終了すると、このファイルは利用できなくなります。
 
 上記の作業が完了すると、'''[$2 ウィキに入る]'''ことができます。",
-       'config-download-localsettings' => 'LocalSettings.php をダウンロード',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> をダウンロード',
        'config-help' => 'ヘルプ',
        'config-nofile' => 'ファイル「$1」が見つかりませんでした。削除された可能性があります。',
        'mainpagetext' => "'''MediaWiki のインストールに成功しました。'''",
@@ -10463,7 +10571,8 @@ $messages['ka'] = array(
        'config-admin-password-confirm' => 'პაროლი ხელმეორედ:',
        'config-admin-name-blank' => 'შეიყვანეთ ადმინისტრატორის მომხმარებლის სახელი.',
        'config-admin-email' => 'ელ. ფოსტის მისამართი:',
-       'config-profile-wiki' => 'ტრადიციული ვიკი',
+       'config-profile' => 'მომხმარებელთა უფლებების პროფილი:',
+       'config-profile-wiki' => 'ღია ვიკი',
        'config-profile-private' => 'დახურული ვიკი',
        'config-license' => 'საავტორო უფლები და ლიცენზია:',
        'config-license-cc-by-sa' => 'Creative Commons Attribution Share Alike',
@@ -10483,7 +10592,7 @@ $messages['ka'] = array(
        'config-install-step-failed' => 'ვერ მოხერხდა',
        'config-install-tables' => 'ცხრილების შექმნა',
        'config-install-interwiki-list' => 'ვერ მოიძებნა ფაილი <code>interwiki.list</code>.',
-       'config-download-localsettings' => 'LocalSettings.php-ის გადმოწერა',
+       'config-download-localsettings' => '<code>LocalSettings.php</code>-ის გადმოწერა',
        'config-help' => 'დახმარება',
        'mainpagetext' => "'''მედიავიკი წარმატებით ჩაიტვირთა.'''",
        'mainpagedocfooter' => 'ვიკი პროგრამის გამოყენების ინფორმაციისთვის იხილეთ [//meta.wikimedia.org/wiki/Help:Contents მომხმარებლის მეგზური].
@@ -10626,24 +10735,24 @@ $messages['kn'] = array(
  * @author 아라
  */
 $messages['ko'] = array(
-       'config-desc' => '미디어위키 설치 마법사',
+       'config-desc' => '미디어위키 설치 프로그램',
        'config-title' => 'MediaWiki $1 설치',
        'config-information' => '정보',
-       'config-localsettings-upgrade' => '<code>LocalSettings.php</code> í\8c\8cì\9d¼ì\9d´ ê°\90ì§\80ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤.
+       'config-localsettings-upgrade' => '<code>LocalSettings.php</code> í\8c\8cì\9d¼ì\9d\84 ê°\90ì§\80í\96\88ì\8aµë\8b\88ë\8b¤.
 이 설치를 업그레이드하려면 아래 상자에 <code>$wgUpgradeKey</code>의 값을 입력하세요.
-LocalSettings.php에 찾으세요.',
-       'config-localsettings-cli-upgrade' => 'LocalSettings.php í\8c\8cì\9d¼ì\9d´ ê°\90ì§\80ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤.
-이 설치를 업그레이드하려면 update.php를 대신 실행하세요',
+<code>LocalSettings.php</code>에 찾을 수 있습니다.',
+       'config-localsettings-cli-upgrade' => '<code>LocalSettings.php</code> í\8c\8cì\9d¼ì\9d\84 ê°\90ì§\80í\96\88ì\8aµë\8b\88ë\8b¤.
+이 설치를 업그레이드하려면 <code>update.php</code>를 대신 실행하세요',
        'config-localsettings-key' => '업그레이드 키:',
        'config-localsettings-badkey' => '제공한 키가 잘못되었습니다.',
        'config-upgrade-key-missing' => '미디어위키의 기존 설치가 감지되었습니다.
-이 설치를 업그레이드하려면 LocalSettings.php의 아래에 다음 줄을 넣으세요:
+이 설치를 업그레이드하려면 <code>LocalSettings.php</code>의 아래에 다음 줄을 넣으세요:
 
 $1',
-       'config-localsettings-incomplete' => '기존 LocalSettings.php가 완전하지 않은 것 같습니다.
+       'config-localsettings-incomplete' => '기존 <code>LocalSettings.php</code>가 완전하지 않은 것 같습니다.
 $1 변수가 설정되어 있지 않습니다.
-이 변수가 설정되도록 LocalSettings.php를 바꾸고 "계속"을 클릭하세요.',
-       'config-localsettings-connection-error' => 'LocalSettings.php 또는 AdminSettings.php에 지정한 설정을 사용하여 데이터베이스에 연결할 때 오류가 발생했습니다. 이러한 설정을 수정하고 다시 시도하세요.
+이 변수가 설정되도록 <code>LocalSettings.php</code>를 바꾸고 "{{int:Config-continue}}"을 클릭하세요.',
+       'config-localsettings-connection-error' => '<code>LocalSettings.php</code> 또는 <code>AdminSettings.php</code>에 지정한 설정을 사용하여 데이터베이스에 연결할 때 오류가 발생했습니다. 이러한 설정을 수정하고 다시 시도하세요.
 
 $1',
        'config-session-error' => '세션 시작 오류: $1',
@@ -10651,12 +10760,12 @@ $1',
 세션은 $1의 작동 시간 동안 구성됩니다.
 php.ini에 있는 <code>session.gc_maxlifetime</code>에서 설정해 이를 증가시킬 수 있습니다.
 설치 과정을 다시 시작합니다.',
-       'config-no-session' => 'ì\84¸ì\85\98 ë\8d°ì\9d´í\84°ê°\80 ì\86\90ì\8b¤ë\90\98ì\97\88습니다!
+       'config-no-session' => 'ì\84¸ì\85\98 ë\8d°ì\9d´í\84°ê°\80 ì\97\86ì\96´ì¡\8c습니다!
 php.ini를 확인하고 <code>session.save_path</code>가 적절한 디렉토리로 설정되어 있는지 확인하세요.',
        'config-your-language' => '설치 언어:',
        'config-your-language-help' => '설치 과정에서 사용할 언어를 선택하세요.',
        'config-wiki-language' => '위키 언어:',
-       'config-wiki-language-help' => '주ë¡\9c ì\9e\91ì\84±ë\90  ì\9c\84í\82¤ì\97\90 ë\8c\80í\95\9c 언어를 선택하세요.',
+       'config-wiki-language-help' => 'ì\9c\84í\82¤ì\97\90 ì£¼ë¡\9c ì\9e\91ì\84±ë\90  언어를 선택하세요.',
        'config-back' => '← 뒤로',
        'config-continue' => '계속 →',
        'config-page-language' => '언어',
        'config-env-php' => 'PHP $1(이)가 설치되었습니다.',
        'config-env-php-toolow' => 'PHP $1(이)가 설치되었습니다.
 하지만 미디어위키는 PHP $2 이상이 필요합니다.',
-       'config-unicode-using-utf8' => '유니코드 정규화에 대해 Brion Vibber의 utf8_normalize.so를 사용합니다.',
-       'config-unicode-using-intl' => '유니코드 정규화에 ë\8c\80í\95´ [http://pecl.php.net/intl intl PECL í\99\95ì\9e¥]ì\9d\84 ì\82¬ì\9a©í\95©ë\8b\88ë\8b¤.',
-       'config-unicode-pure-php-warning' => "'''경고''': [http://pecl.php.net/intl intl PECL 확장]은 PHP만으로 구현하는 데에는 느려질 정도로 성능이 떨어지는 유니코드 정규화를 처리할 수 없습니다.
-높은 트래픽의 사이트에서 실행하려면 [//www.mediawiki.org/wiki/Unicode_normalization_considerations 유니코드 정규화]에 대해 약간 참고해야 합니다.",
+       'config-unicode-using-utf8' => '유니코드 정규화에 Brion Vibber의 utf8_normalize.so를 사용합니다.',
+       'config-unicode-using-intl' => '유니코드 정규화에 [http://pecl.php.net/intl intl PECL í\99\95ì\9e¥ ê¸°ë\8a¥]ì\9d\84 ì\82¬ì\9a©í\95©ë\8b\88ë\8b¤.',
+       'config-unicode-pure-php-warning' => "'''경고''': 유니코드 정규화를 처리할 [http://pecl.php.net/intl intl PECL 확장 기능]을 사용할 수 없기 때문에 느린 순수한 PHP 구현을 대신 사용합니다.
+높은 트래픽 사이트에서 실행하려면 [//www.mediawiki.org/wiki/Unicode_normalization_considerations 유니코드 정규화]를 읽어보시기 바랍니다.",
        'config-unicode-update-warning' => "'''경고''': 유니코드 정규화 래퍼의 설치된 버전은 [http://site.icu-project.org/ ICU 프로젝트]의 라이브러리의 이전 버전을 사용합니다.
 만약 유니코드를 사용하는 것에 대해 우려가 된다면 [//www.mediawiki.org/wiki/Unicode_normalization_considerations 업그레이드]해야합니다.",
        'config-no-db' => '적절한 데이터베이스 드라이버를 찾을 수 없습니다! PHP에 데이터베이스 드라이버를 설치해야 합니다.
 다음 데이터베이스 유형을 지원합니다 : $1.
 
-호스팅을 공유하고 있다면 적절한 데이터베이스 드라이버를 설치하도록 호스팅 제공 업체에 문의하세요.
-PHP를 ì§\81ì \91 ì»´í\8c\8cì\9d¼í\95  ê²½ì\9a° ë\8d°ì\9d´í\84°ë² ì\9d´ì\8a¤ í\81´ë\9d¼ì\9d´ì\96¸í\8a¸ë¥¼ ì\82¬ì\9a©í\95\98ì\97¬ í\99\9cì\84±í\99\94í\95\98ë\8f\84ë¡\9d ë\8b¤ì\8b\9c ì\84¤ì \95í\95\98ì\84¸ì\9a\94. ì\98\88ë\93¤ ë\93¤ì\96´ <code>./configure --with-mysql</code>ì\9d\84 ì\82¬ì\9a©하세요.
+공유하는 호스팅을 사용하고 있다면 적절한 데이터베이스 드라이버를 설치하도록 호스팅 제공 업체에 문의하세요.
+PHP를 ì§\81ì \91 ì»´í\8c\8cì\9d¼í\96\88ë\8b¤ë©´ ì\98\88를 ë\93¤ì\96´ <code>./configure --with-mysql</code>ì\9d\84 ì\82¬ì\9a©í\95\98ì\97¬ ë\8d°ì\9d´í\84°ë² ì\9d´ì\8a¤ í\81´ë\9d¼ì\9d´ì\96¸í\8a¸ë¥¼ í\99\9cì\84±í\99\94í\95\98ë\8f\84ë¡\9d ë\8b¤ì\8b\9c ì\84¤ì \95하세요.
 데비안이나 우분트 패키지에서 PHP를 설치했다면 php-mysql 모듈도 설치해야 합니다.',
        'config-outdated-sqlite' => "'''경고''': SQLite 필요한 최소 $2 버전보다 낮은 $1(이)가 있습니다. SQLite는 사용할 수 없습니다.",
        'config-no-fts3' => "'''경고''': SQLite는 [//sqlite.org/fts3.html FTS3 모듈] 없이 컴파일되어, 검색 기능은 백엔드에 사용할 수 없습니다.",
        'config-register-globals' => "'''경고: PHP의 <code>[http://php.net/register_globals register_globals]</code> 옵션이 활성화되어 있습니다.'''
 '''가능하면 이를 비활성화하십시오.'''
-미ë\94\94ì\96´ì\9c\84í\82¤ë\8a\94 ì\9e\91ë\8f\99í\95\98ì§\80ë§\8c ì\84\9cë²\84ì\97\90 ì\9e ì\9e¬ì \81ì\9d¸ ë³´ì\95\88 ì·¨ì\95½ì \90ì\97\90 노출됩니다.",
+미ë\94\94ì\96´ì\9c\84í\82¤ë\8a\94 ì\9e\91ë\8f\99í\95\98ì§\80ë§\8c ì\84\9cë²\84ì\97\90 ì\9e ì\9e¬ì \81ì\9d¸ ë³´ì\95\88 ì·¨ì\95½ì \90ì\9d´ 노출됩니다.",
        'config-magic-quotes-runtime' => "'''치명: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime]이 활성합니다!'''
 이 옵션은 데이터를 입력하는 데 예기치 않는 손상이 일어납니다.
\84¤ì¹\98í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤. ë\98\90ë\8a\94 ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ê°\80 ì\82¬ì\9a©í\95\98ì§\80 ì\95\8aë\8a\94 ì\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì\8b­ì\8b\9cì\98¤.",
\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì§\80 ì\95\8aë\8a\94 í\95\9c ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ë¥¼ ì\84¤ì¹\98í\95\98ê³  ì\82¬ì\9a©í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤.",
        'config-magic-quotes-sybase' => "'''치명: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-sybase magic_quotes_sybase]이 활성합니다!'''
 이 옵션은 데이터를 입력하는 데 예기치 않는 손상이 일어납니다.
\84¤ì¹\98í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤. ë\98\90ë\8a\94 ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ê°\80 ì\82¬ì\9a©í\95\98ì§\80 ì\95\8aë\8a\94 ì\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì\8b­ì\8b\9cì\98¤.",
\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì§\80 ì\95\8aë\8a\94 í\95\9c ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ë¥¼ ì\84¤ì¹\98í\95\98ê³  ì\82¬ì\9a©í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤.",
        'config-mbstring' => "'''치명: [http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload]이 활성합니다!'''
 이 옵션은 오류가 발생하고 데이터를 입력하는 데 예기치 않는 손상이 일어날 수 있습니다.
\84¤ì¹\98í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤. ë\98\90ë\8a\94 ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ê°\80 ì\82¬ì\9a©í\95\98ì§\80 ì\95\8aë\8a\94 ì\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì\8b­ì\8b\9cì\98¤.",
\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì§\80 ì\95\8aë\8a\94 í\95\9c ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ë¥¼ ì\84¤ì¹\98í\95\98ê³  ì\82¬ì\9a©í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤.",
        'config-ze1' => "'''치명: [http://www.php.net/manual/en/ini.core.php zend.ze1_compatibility_mode]이 활성합니다!'''
-이 옵션은 미디어위키에 끔찍한 버그를 일으킵니다.
\84¤ì¹\98í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤. ë\98\90ë\8a\94 ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ê°\80 ì\82¬ì\9a©í\95\98ì§\80 ì\95\8aë\8a\94 ì\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì\8b­ì\8b\9cì\98¤.",
+이 옵션은 미디어위키에 심간한 버그를 일으킵니다.
\9d´ ì\98µì\85\98ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95\98ì§\80 ì\95\8aë\8a\94 í\95\9c ë¯¸ë\94\94ì\96´ì\9c\84í\82¤ë¥¼ ì\84¤ì¹\98í\95\98ê³  ì\82¬ì\9a©í\95  ì\88\98 ì\97\86ì\8aµë\8b\88ë\8b¤.",
        'config-safe-mode' => "'''경고:''' [http://www.php.net/features.safe-mode 안전 모드]이 활성합니다!
 특히 파일을 올리거나 <code>math</code>를 지원하는 데 문제가 발생할 수 있습니다.",
        'config-xml-bad' => 'PHP의 XML 모듈이 없습니다.
@@ -10752,7 +10861,7 @@ Mandrake를 실행하고 있다면 php-xml 패키지를 설치하세요.',
        'config-apc' => '[http://www.php.net/apc APC]가 설치되었습니다',
        'config-wincache' => '[http://www.iis.net/download/WinCacheForPhp WinCache]가 설치되었습니다',
        'config-no-cache' => "'''경고:''' [http://www.php.net/apc APC], [http://xcache.lighttpd.net/ XCache] 또는 [http://www.iis.net/download/WinCacheForPhp WinCache]를 찾을 수 없습니다.
-ê°\9cì²´ ìº\90ì\8b±ì\9d´ í\99\9cì\84±í\99\94ë\90\98ì§\80 ì\95\8aì\8aµë\8b\88ë\8b¤.",
+ê°\9cì²´ ìº\90ì\8b±ì\9d\84 í\99\9cì\84±í\99\94í\95\98ì§\80 ì\95\8aì\8aµë\8b\88ë\8b¤.",
        'config-mod-security' => "'''경고''': 웹 서버에 [http://modsecurity.org/ mod_security]가 허용되었습니다. 잘못 설정된 경우 미디어위키나 사용자가 임의의 콘텐츠를 게시할 수 있는 다른 소프트웨어에 대한 문제를 일으킬 수 있습니다.
 [http://modsecurity.org/documentation/ mod_security] 문서를 참고하거나 임의의 오류가 발생할 경우 호스트의 지원 요청에 문의하십시오.",
        'config-diff3-bad' => 'GNU diff3를 찾을 수 없습니다.',
@@ -10771,21 +10880,23 @@ Mandrake를 실행하고 있다면 php-xml 패키지를 설치하세요.',
 미디어위키는 보안 위협에 대한 모든 올린 파일을 검사하지만, 올리기를 활성화하기 전에 [//www.mediawiki.org/wiki/Manual:Security#Upload_security 이 보안 취약점을 해결할 것]을 매우 권장합니다.",
        'config-no-cli-uploads-check' => "'''경고:''' 올리기에 대한 기본 디렉토리(<code>$1</code>)는 CLI를 설치하는 동안 임의의 스크립트 실행에 대한 취약점에 대해 검사되지 않습니다.",
        'config-brokenlibxml' => '시스템에 버그가 있는 PHP와 libxml2의 조합이 있으며 미디어위키나 다른 웹 어플리케이션에 숨겨진 데이터 손상을 일으킬 수 있습니다.
-PHP 5.2.9 이후와 libxml2 2.7.3 이후로 업그레이드하세요 ([//bugs.php.net/bug.php?id=45996 PHP에 제기한 버그]).
+PHP 5.2.9 이후와 libxml2 2.7.3 이후로 업그레이드하세요. ([//bugs.php.net/bug.php?id=45996 PHP에 제기한 버그])
 설치가 중단되었습니다.',
        'config-using531' => '미디어위키는 <code>__call()</code>을 참고로 매개 변수를 포함하는 버그로 인해 PHP $1(와)과 함께 사용할 수 없습니다.
 문제를 해결하려면 PHP 5.3.2 이상로 업그레이드하거나 PHP 5.3.0으로 다운그레이드를 하세요.
 설치가 중단되었습니다.',
-       'config-suhosin-max-value-length' => 'Suhosin(수호신)이 설치되었고 $1 바이트로 GET 매개 변수 길이를 제한하고 있습니다. 미디어위키의 ResourceLoader 구성 요소는 이 제한을 해결하지만 성능이 저하됩니다. 가능하면 php.ini의 suhosin.get.max_value_length에 1024 이상으로 설정하고 LocalSettings.php의 $wgResourceLoaderMaxQueryLength에 같은 값을 설정해야 합니다.',
+       'config-suhosin-max-value-length' => 'Suhosin이 설치되었고 $1 바이트로 GET 매개 변수인 <code>length</code>를 제한하고 있습니다.
+미디어위키의 ResourceLoader 구성 요소는 이 제한을 해결하지만 성능이 저하됩니다.
+가능하면 <code>php.ini</code>의 <code>suhosin.get.max_value_length</code>에 1024 이상으로 설정하고 <code>LocalSettings.php</code>의 <code>$wgResourceLoaderMaxQueryLength</code>에 같은 값을 설정해야 합니다.',
        'config-db-type' => '데이터베이스 종류:',
        'config-db-host' => '데이터베이스 호스트:',
-       'config-db-host-help' => 'ë\8d°ì\9d´í\84°ë² ì\9d´ì\8a¤ ì\84\9cë²\84ê°\80 ë\8b¤ë¥¸ ì\84\9cë²\84ì\97\90 ì\9e\88ì\9d\84 ê²½ì\9a° 여기에 호스트 이름이나 IP 주소를 입력하세요.
+       'config-db-host-help' => 'ë\8d°ì\9d´í\84°ë² ì\9d´ì\8a¤ ì\84\9cë²\84ê°\80 ë\8b¤ë¥¸ ì\84\9cë²\84ì\97\90 ì\9e\88ì\9c¼ë©´ 여기에 호스트 이름이나 IP 주소를 입력하세요.
 
-공유된 웹 호스팅을 사용하는 경우 호스팅 공급자는 올바른 호스트 이름을 설명해야 합니다.
+공유하는 웹 호스팅을 사용하고 있으면 호스팅 제공 업체는 호스트 이름을 설명하고 있을 것입니다.
 
\9c\88ë\8f\84 ì\84\9cë²\84ì\97\90 ì\84¤ì¹\98í\95\98ê³  MySQLì\9d\84 ì\82¬ì\9a©í\95  ê²½ì\9a° "localhost"ë\8a\94 ì\84\9cë²\84 ì\9d´ë¦\84ì\9c¼ë¡\9c ì\9e\91ë\8f\99í\95\98ì§\80 ì\95\8aì\9d\84 ì\88\98 ì\9e\88ì\8aµë\8b\88ë\8b¤. ê·¸ë \87ì§\80 ì\95\8aì\9c¼면 로컬 IP 주소로 "127.0.0.1"를 시도하세요.
\9c\88ë\8f\84 ì\84\9cë²\84ì\97\90 ì\84¤ì¹\98í\95\98ê³  MySQLì\9d\84 ì\82¬ì\9a©í\95\98ë©´ "localhost"ë\8a\94 ì\84\9cë²\84 ì\9d´ë¦\84ì\9c¼ë¡\9c ì\9e\91ë\8f\99í\95\98ì§\80 ì\95\8aì\9d\84 ì\88\98 ì\9e\88ì\8aµë\8b\88ë\8b¤. ê·¸ë \87ê²\8c ë\90\9cë\8b¤면 로컬 IP 주소로 "127.0.0.1"를 시도하세요.
 
-PostgreSQLì\9d\84 ì\82¬ì\9a©í\95  ê²½ì\9a° 유닉스 소켓을 통해 연결되도록 입력란을 비워두세요.',
+PostgreSQLì\9d\84 ì\82¬ì\9a©í\95\98ë©´ 유닉스 소켓을 통해 연결되도록 입력란을 비워두세요.',
        'config-db-host-oracle' => '데이터베이스 TNS:',
        'config-db-host-oracle-help' => '유효한 [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm 로컬 연결 이름]을 입력하세요. tnsnames.ora 파일이 이 설치에 보여야 합니다.<br />10g 이후의 클라이언트 라이브러리를 사용하는 경우 [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm 쉬운 연결] 네이밍 메소드도 사용할 수 있습니다.',
        'config-db-wiki-settings' => '이 위키 식별',
@@ -10793,13 +10904,13 @@ PostgreSQL을 사용할 경우 유닉스 소켓을 통해 연결되도록 입력
        'config-db-name-help' => '위키를 식별하기 위한 이름을 선택하세요.
 공백이 없어야 합니다.
 
-공유된 웹 호스팅 사용하는 경우 호스팅 제공 업체가 특정 데이터베이스 이름을 제공하거나 제어판에서 데이터베이스를 만들 수 있도록 합니다.',
+공유하는 웹 호스팅 사용하면 호스팅 제공 업체가 특정 데이터베이스 이름을 제공하거나 관리 패널에서 데이터베이스를 만들 수 있습니다.',
        'config-db-name-oracle' => '데이터베이스 스키마:',
        'config-db-account-oracle-warn' => '데이터베이스 백엔드로 오라클을 설치하기 위해 지원하는 세 가지 시나리오가 있습니다:
 
 설치 과정의 일부로 데이터베이스 계정을 만들려면 설치를 위해 데이터베이스 계정으로 SYSDBA 역할을 가진 계정을 제공하고 웹 접근 계정에 대해 원하는 자격 증명을 지정하세요, 그렇지 않으면 수동으로 웹 접근 계정을 만들 수 있으며 (필요한 경우 권한 스키마 개체를 만들어야 합니다) 또는 다른 계정 두 개를 만들고 권한을 가진 하나의 웹 접근을 위한 제한된 하나를 제공할 수 있습니다.
 
\95\84ì\9a\94í\95\9c ê¶\8cí\95\9cì\9d\84 ê°\80ì§\84 ê³\84ì \95ì\9d\84 ë§\8cë\93\9cë\8a\94 ì\8a¤í\81¬ë¦½í\8a¸ë\8a\94 ì\9d´ ì\84¤ì¹\98ì\9d\98 "maintenance/oracle/" ë\94\94ë \89í\86 ë¦¬ì\97\90ì\84\9c ì°¾ì\9d\84 ì\88\98 ì\9e\88ì\8aµë\8b\88ë\8b¤. ì \9cí\95\9cë\90\9c ê³\84ì \95ì\9d\84 ì\82¬ì\9a©í\95\98ë©´ ê¸°ë³¸ ê³\84ì \95ì\9c¼ë¡\9c ëª¨ë\93  ê´\80리 ê¸°ë\8a¥ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95  ê²\83ì\9d\84 ì\97¼ë\91\90í\95´ ë\91\90십시오.',
\95\84ì\9a\94í\95\9c ê¶\8cí\95\9cì\9d\84 ê°\80ì§\84 ê³\84ì \95ì\9d\84 ë§\8cë\93\9cë\8a\94 ì\8a¤í\81¬ë¦½í\8a¸ë\8a\94 ì\9d´ ì\84¤ì¹\98ì\9d\98 "maintenance/oracle/" ë\94\94ë \89í\86 ë¦¬ì\97\90ì\84\9c ì°¾ì\9d\84 ì\88\98 ì\9e\88ì\8aµë\8b\88ë\8b¤. ì \9cí\95\9cë\90\9c ê³\84ì \95ì\9d\84 ì\82¬ì\9a©í\95\98ë©´ ê¸°ë³¸ ê³\84ì \95ì\9c¼ë¡\9c ëª¨ë\93  ê´\80리 ê¸°ë\8a¥ì\9d\84 ë¹\84í\99\9cì\84±í\99\94í\95  ê²\83ì\9d\84 ì\9c ì\9d\98í\95\98십시오.',
        'config-db-install-account' => '설치를 위한 사용자 계정',
        'config-db-username' => '데이터베이스 사용자 이름:',
        'config-db-password' => '데이터베이스 비밀번호:',
@@ -10827,25 +10938,25 @@ PostgreSQL을 사용할 경우 유닉스 소켓을 통해 연결되도록 입력
 
 '''바이너리 모드'''에서는 미디어위키는 바이너리 필드의 데이터베이스에 UTF-8 텍스트를 저장합니다.
 MySQL의 UTF-8 모드를 보다 더 효율적이고 유니코드 문자의 전체 범위를 사용할 수 있습니다.
-'''UTF-8 모드'''에서는 MySQL은 데이터를 설정하는 어떤 문자열인지를 알 것이며, 표현하고 적절하게 그것을 변환할 수 있지만
-[//en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes 기본 다국어 범위] 상의 문자를 저장하지 못하게 될 수 있습니다.",
+'''UTF-8 모드'''에서는 MySQL은 데이터를 설정하는 문자 집합을 알고 있기 때문에 적절하게 표현하고 변환할 수 있지만
+[//ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C_%ED%8F%89%EB%A9%B4#.EA.B8.B0.EB.B3.B8_.EB.8B.A4.EA.B5.AD.EC.96.B4_.ED.8F.89.EB.A9.B4 기본 다국어 평면] 밖의 문자를 저장할 수 없습니다.",
        'config-mysql-old' => 'MySQL $1 이상이 필요하나 $2(이)가 있습니다.',
        'config-db-port' => '데이터베이스 포트:',
        'config-db-schema' => '미디어위키에 대한 스키마:',
-       'config-db-schema-help' => '이 스키마는 보통 괜찮습니다.
-필요로 알고 있을 경우에만 이를 바꾸세요.',
+       'config-db-schema-help' => '보통 이 스키마는 문제가 없습니다.
+필요한 경우에만 바꾸세요.',
        'config-pg-test-error' => "'''$1''' 데이터베이스에 연결할 수 없습니다: $2",
        'config-sqlite-dir' => 'SQLite 데이터 디렉토리:',
-       'config-sqlite-dir-help' => 'SQLite는 하나의 파일에 모든 데이터를 저장합니다.
+       'config-sqlite-dir-help' => "SQLite는 하나의 파일에 모든 데이터를 저장합니다.
 
-제공하는 디렉토리는 설치하는 동안 웹 서버에 의해 쓸 수 있어야 합니다.
+제공하는 디렉토리는 설치하는 동안 웹 서버 쓸 수 있어야 합니다.
 
-PHP 파일이 있는 곳을 우리가 맡길 수 없는 이유는 웹을 통해 접근할 수 없다는 것입니다.
+이 디렉토리는 웹을 통해 접근할 수 '''없어야''' 하는데 PHP 파일이 있는 곳에 넣을 수 없는 것은 이 때문입니다.
 
-설치 마법사가 이과 함께 .htaccess 파일을 만들지만 거기서 실패하면 누군가는 원본 데이터베이스에 접근하는 데 실패합니다.
-원본 사용자 데이터(이메일 주소, 해시한 비밀번호) 뿐만 아니라 삭제된 개정판과 위키의 다른 제한된 데이터를 포함합니다.
+설치 프로그램은 <code>.htaccess</code> 파일을 작성하지만 이것이 실패하면 누군가가 원본 데이터베이스에 접근할 수 있습니다.
+데이터베이스는 원본 사용자 데이터(이메일 주소, 해시한 비밀번호) 뿐만 아니라 삭제된 판과 위키의 다른 제한된 데이터를 포함합니다.
 
-<code>/var/lib/mediawiki/yourwiki</code>와 같이 모두 다른 곳에서 데이터베이스를 넣어보도록 하세요.',
+예를 들어 <code>/var/lib/mediawiki/yourwiki</code>와 같이 다른 곳에 데이터베이스를 넣는 것이 좋습니다.",
        'config-oracle-def-ts' => '기본 테이블공간:',
        'config-oracle-temp-ts' => '임시 테이블공간:',
        'config-type-oracle' => '오라클',
 
 데이터베이스 시스템이 표시되지 않을 때 아래에 나열된 다음 지원을 활성화하려면 위의 링크된 지시에 따라 설치해볼 수 있습니다.',
        'config-support-mysql' => '* $1은 미디어위키의 기본 대상으로 가장 잘 지원합니다. ([http://www.php.net/manual/en/mysql.installation.php MySQL을 지원하여 PHP를 컴파일하는 방법])',
-       'config-support-postgres' => '* $1은 MySQL의 대안으로 인기있는 오픈 소스 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL을 지원하여 PHP를 컴파일하는 방법]) 몇가지 사소한 해결하지 못한 버그가 있을 수 있으며, 이를 제작 환경에서 사용하지 않는 것이 좋습니다.',
+       'config-support-postgres' => '* $1은 MySQL의 대안으로 인기 있는 오픈 소스 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL을 지원하여 PHP를 컴파일하는 방법]) 몇가지 사소한 해결하지 못한 버그가 있을 수 있으며, 이를 제작 환경에서 사용하지 않는 것이 좋습니다.',
        'config-support-sqlite' => '* $1는 매우 잘 지원하는 가벼운 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pdo.installation.php SQLite를 지원하여 PHP를 컴파일하는 방법], PDO 사용)',
        'config-support-oracle' => '* $1은 상용 엔터프라이스 데이터베이스입니다. ([http://www.php.net/manual/en/oci8.installation.php OCI8을 지원하여 PHP를 컴파일하는 방법])',
-       'config-support-ibm_db2' => '* $1는 상용 엔터프라이즈 데이터베이스입니다.',
+       'config-support-ibm_db2' => '* $1는 상용 엔터프라이즈 데이터베이스입니다.([http://www.php.net/manual/en/ibm-db2.installation.php IBM DB2를 지원하여 PHP를 컴파일하는 방법])',
        'config-header-mysql' => 'MySQL 설정',
        'config-header-postgres' => 'PostgreSQL 설정',
        'config-header-sqlite' => 'SQLite 설정',
@@ -10880,39 +10991,39 @@ ASCII 글자 (a-z, A-Z), 숫자 (0-9), 밑줄 (_)과 하이픈 (-)만 사용하
 호스트, 계정 이름과 비밀번호를 확인하고 다시 시도하세요.',
        'config-invalid-schema' => '미디어위키 "$1"에 대한 스키마가 잘못됐습니다.
 ASCII 글자 (a-z, A-Z), 숫자 (0-9), 밑줄 (_)과 하이픈 (-)만 사용하세요.',
-       'config-db-sys-create-oracle' => '설치 마법사는 새 계정을 만들기 위한 SYSDBA 계정만을 지원합니다.',
+       'config-db-sys-create-oracle' => '설치 프로그램은 새 계정을 만들기 위한 SYSDBA 계정만을 지원합니다.',
        'config-db-sys-user-exists-oracle' => '"$1" 사용자 계정이 이미 존재합니다. SYSDBA는 새 계정을 만드는 데에만 사용할 수 있습니다!',
        'config-postgres-old' => 'PostgreSQL $1 이상이 필요하나 $2(이)가 있습니다.',
        'config-sqlite-name-help' => '위키를 식별하기 위한 이름을 선택하세요.
 공백이나 하이픈을 사용하지 마십시오.
 SQLite 데이터 파일 이름에 사용됩니다.',
-       'config-sqlite-parent-unwritable-group' => '<code><nowiki>$1</nowiki></code> 데이터 디렉토리를 만들 수 없으며 <code><nowiki>$2</nowiki></code> 상위 디렉토리에 웹 서버에 의해 쓸 수 없기 때문입니다.
+       'config-sqlite-parent-unwritable-group' => '<code><nowiki>$1</nowiki></code> 데이터 디렉토리를 만들 수 없으며 웹 서버는 <code><nowiki>$2</nowiki></code> 상위 디렉토리에 쓸 수 없기 때문입니다.
 
-설치 마법사는 웹 서버로 실행중인 사용자를 결정할 수 없습니다.
-ê³\84ì\86\8dí\95\98려면 ì\9d´ë¥¼ 쓸 수 있는 <code><nowiki>$3</nowiki></code> 디렉토리를 만드세요.
+설치 프로그램은 웹 서버로 실행중인 사용자를 지정할 수 없습니다.
+ê³\84ì\86\8dí\95\98려면 ì\9b¹ ì\84\9cë²\84ê°\80 쓸 수 있는 <code><nowiki>$3</nowiki></code> 디렉토리를 만드세요.
 유닉스/리눅스 시스템에서의 수행:
 
 <pre>cd $2
 mkdir $3
 chgrp $4 $3
 chmod g+w $3</pre>',
-       'config-sqlite-parent-unwritable-nogroup' => '<code><nowiki>$1</nowiki></code> 데이터 디렉토리를 만들 수 없으며 <code><nowiki>$2</nowiki></code> 상위 디렉토리에 웹 서버에 의해 쓸 수 없기 때문입니다.
+       'config-sqlite-parent-unwritable-nogroup' => '<code><nowiki>$1</nowiki></code> 데이터 디렉토리를 만들 수 없으며 웹 서버는 <code><nowiki>$2</nowiki></code> 상위 디렉토리에 쓸 수 없기 때문입니다.
 
-설치 마법사는 웹 서버로 실행중인 사용자를 결정할 수 없습니다.
-ê³\84ì\86\8dí\95\98려면 ì\9d´(ì\99\80 ê¸°í\83\80!)를 전역으로 쓸 수 있는 <code><nowiki>$3</nowiki></code> 디렉토리를 만드세요.
+설치 프로그램은 웹 서버로 실행중인 사용자를 지정할 수 없습니다.
+ê³\84ì\86\8dí\95\98려면 ì\9b¹ ì\84\9cë²\84\99\80 ê¸°í\83\80!)ê°\80 전역으로 쓸 수 있는 <code><nowiki>$3</nowiki></code> 디렉토리를 만드세요.
 유닉스/리눅스 시스템에서의 수행:
 
 <pre>cd $2
 mkdir $3
 chmod a+w $3</pre>',
-       'config-sqlite-mkdir-error' => '"$1" 데이터 디렉토리를 만드는 중 오류났습니다.
+       'config-sqlite-mkdir-error' => '"$1" 데이터 디렉토리를 만드는 중 오류가 났습니다.
 경로를 확인하고 다시 시도하세요.',
        'config-sqlite-dir-unwritable' => '"$1" 디렉토리에 쓸 수 없습니다.
 웹 서버를 쓸 수 있도록 권한을 바꾸고 다시 시도하세요.',
        'config-sqlite-connection-error' => '$1.
 
 호스트, 계정 이름과 비밀번호를 확인하고 다시 시도하세요.',
-       'config-sqlite-readonly' => '<code>$1</code> í\8c\8cì\9d¼ì\9d\80 ì\93°ê¸°ê°\80 ë¶\88ê°\80ë\8a¥í\95©니다.',
+       'config-sqlite-readonly' => '<code>$1</code> í\8c\8cì\9d¼ì\9d\80 ì\93¸ ì\88\98 ì\97\86ì\8aµ니다.',
        'config-sqlite-cant-create-db' => '<code>$1</code> 데이터베이스 파일을 만들 수 없습니다.',
        'config-sqlite-fts3-downgrade' => 'PHP가 FTS3 지원이 없어졌습니다. 테이블을 다운그레이드하세요.',
        'config-can-upgrade' => "이 데이터베이스에 미디어위키 테이블이 있습니다.
@@ -10926,8 +11037,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => '업그레이드가 완료되었습니다.
 
 이제 [$1 위키를 시작]할 수 있습니다.',
-       'config-regenerate' => 'LocalSettings.php 다시 만들기 →',
-       'config-show-table-status' => 'SHOW TABLE STATUS 쿼리 실패!',
+       'config-regenerate' => '<code>LocalSettings.php</code> 다시 만들기 →',
+       'config-show-table-status' => '<code>SHOW TABLE STATUS</code> 쿼리를 실패했습니다!',
        'config-unknown-collation' => "'''경고:''' 데이터베이스가 인식하지 않는 정렬을 사용하고 있습니다.",
        'config-db-web-account' => '웹 접근을 위한 데이터베이스 계정',
        'config-db-web-help' => '위키의 일반적인 작업 중에 데이터베이스 서버에 연결하는 데 사용할 웹 서버에 대한 계정 이름과 비밀번호를 선택하세요.',
@@ -10945,7 +11056,7 @@ chmod a+w $3</pre>',
 
 MySQL 설치가 InnoDB를 지원한다면 그 선택 대신에 InnoDB를 선택할 것을 매우 권장합니다.
 MySQL 설치가 InnoDB를 지원하지 않는다면 아마도 업그레이드를 해야 할 수도 있습니다.",
-       'config-mysql-engine-help' => "'''InnoDB'''는 동시적인 지원에 좋기 때문에 거의 항상 최고의 옵션입니다.
+       'config-mysql-engine-help' => "'''InnoDB'''는 동시적인 지원에 좋기 때문에 대부분 최고의 옵션입니다.
 
 '''MyISAM'''은 단일 사용자 또는 읽기 전용 설치에 빠를 수 있습니다.
 MyISAM 데이터베이스는 InnoDB 데이터베이스보다 더 자주 손실될 수 있습니다.",
@@ -10954,8 +11065,8 @@ MyISAM 데이터베이스는 InnoDB 데이터베이스보다 더 자주 손실
        'config-mysql-utf8' => 'UTF-8',
        'config-mysql-charset-help' => "'''바이너리 모드'''에서는 미디어위키는 바이너리 필드의 데이터베이스에 UTF-8 텍스트를 저장합니다.
 MySQL의 UTF-8 모드를 보다 더 효율적이고 유니코드 문자의 전체 범위를 사용할 수 있습니다.
-'''UTF-8 모드'''에서는 MySQL은 데이터를 설정하는 어떤 문자열인지를 알 것이며, 표현하고 적절하게 그것을 변환할 수 있지만
-[//en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes 기본 다국어 범위] 상의 문자를 저장하지 못하게 될 수 있습니다.",
+'''UTF-8 모드'''에서는 MySQL은 데이터를 설정하는 문자 집합을 알고 있기 때문에 적절하게 표현하고 변환할 수 있지만
+[//ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C_%ED%8F%89%EB%A9%B4#.EA.B8.B0.EB.B3.B8_.EB.8B.A4.EA.B5.AD.EC.96.B4_.ED.8F.89.EB.A9.B4 기본 다국어 평면] 밖의 문자를 저장할 수 없습니다.",
        'config-ibm_db2-low-db-pagesize' => "DB2 데이터베이스에 부족한 페이지 크기가 기본 테이블 공간에 있습니다. 페이지 크기는 '''32K''' 이상이어야 합니다.",
        'config-site-name' => '위키 이름:',
        'config-site-name-help' => '브라우저 제목 표시줄과 다른 여러 곳에 나타납니다.',
@@ -10999,23 +11110,23 @@ MySQL의 UTF-8 모드를 보다 더 효율적이고 유니코드 문자의 전
        'config-optional-continue' => '더 많은 질문을 물어보세요.',
        'config-optional-skip' => '지겨워요, 그냥 위키를 설치할래요.',
        'config-profile' => '사용자 권한 프로필:',
-       'config-profile-wiki' => '평범한 위키', # Fuzzy
+       'config-profile-wiki' => '열린 위키',
        'config-profile-no-anon' => '계정 만들기 필요',
-       'config-profile-fishbowl' => '승인된 편집자만 이용 가능',
+       'config-profile-fishbowl' => '승인된 편집자만',
        'config-profile-private' => '비공개 위키',
-       'config-profile-help' => "ì\9c\84í\82¤ë\8a\94 ë§\8eì\9d\80 ì\82¬ë\9e\8cë\93¤ì\9d´ ê°\80ë\8a¥í\95\9c í\95\9c í\95´ë\8b¹ ì\9c\84í\82¤ë¥¼ í\8e¸ì§\91í\95  ë\95\8c 가장 뛰어난 역할을 합니다.
-미ë\94\94ì\96´ì\9c\84í\82¤ì\97\90ì\84\9cë\8a\94 ìµ\9cê·¼ ë°\94ë\80\9cì\9d\84 ê²\80í\86 í\95\98ê³ , ì\84 í\95\98ê±°ë\82\98 ì\95\85ì\9d\98ì \81ì\9d¸ ì\82¬ì\9a©ì\9e\90ì\9d\98 ëª¨ë\93  손실을 되돌리는 것이 쉽습니다.
+       'config-profile-help' => "ì\9c\84í\82¤ë\8a\94 ë§\8eì\9d\80 ì\82¬ë\9e\8cë\93¤ì\9d´ ê°\80ë\8a¥í\95\9c í\95\9c í\8e¸ì§\91í\95  ì\88\98 ì\9e\88ë\8f\84ë¡\9d í\95\98ë©´ 가장 뛰어난 역할을 합니다.
+미ë\94\94ì\96´ì\9c\84í\82¤ì\97\90ì\84\9cë\8a\94 ìµ\9cê·¼ ë°\94ë\80\9cì\9d\84 ê²\80í\86 í\95\98기 ì\89½ê³ , ì\84 í\95\98ê±°ë\82\98 ì\95\85ì\9d\98ì \81ì\9d¸ ì\82¬ì\9a©ì\9e\90ì\9d\98 ì\96´ë\96 í\95\9c 손실을 되돌리는 것이 쉽습니다.
 
-그러나 많은 사람들이 미디어위키가 다양한 역할로 유용하지만, 때로는 모든 사람에게 위키 방식의 장점을 모두 설득하기 쉽지 않을 지도 모릅니다.
+그러나 많은 사람이 미디어위키는 다양한 역할로 유용하지만, 때로는 모든 사람에게 위키 방식의 장점을 설득하기 쉽지 않을 지도 모릅니다.
 그래서 선택할 수 있습니다.
 
-'''{{int:config-profile-wiki}}''' 로그인하지 않고도 누구나 편집할 수 있습니다.
-'''{{int:config-profile-no-anon}}'''는 각 편집에 추가적으로 강한 책임성을 제공하지만, 부담 없는 기여를 저해할 수도 있습니다.
+'''{{int:config-profile-wiki}}''' 모델은 로그인하지 않고도 누구나 편집할 수 있습니다.
+'''{{int:config-profile-no-anon}}'''인 위키는 각 편집에 추가적으로 강한 책임을 제공하지만, 부담 없는 기여를 저해할 수도 있습니다.
 
-'''{{int:config-profile-fishbowl}}''' 같은 경우는 승인된 사용자만 편집할 수 있지만, 대중은 역사를 포함하여 페이지를 볼 수 있습니다.
-'''{{int:config-profile-private}}'''는 승인된 사용자만 같은 그룹에서 편집할 수 있고 볼 수 있습니다.
+'''{{int:config-profile-fishbowl}}''' 시나리오는 승인된 사용자만 편집할 수 있지만, 대중은 역사를 포함하여 문서를 볼 수 있습니다.
+'''{{int:config-profile-private}}'''는 승인된 사용자만 문서를 볼 수 있으며 해당 그룹을 편집할 수 있습니다.
 
-더 복잡한 사용자 권한을 설정하여 설치한 후 사용할 수 있도록 하려면 [//www.mediawiki.org/wiki/Manual:User_rights 관련 매뉴얼 항목]을 참고하세요.", # Fuzzy
+더 복잡한 사용자 권한을 설정은 설치한 후 사용할 수 있으며 [//www.mediawiki.org/wiki/Manual:User_rights 관련 설명서 항목]을 참고하세요.",
        'config-license' => '저작권 및 라이선스:',
        'config-license-none' => '라이선스 바닥글 없음',
        'config-license-cc-by-sa' => '크리에이티브 커먼즈 저작자표시-동일조건변경허락',
@@ -11025,15 +11136,15 @@ MySQL의 UTF-8 모드를 보다 더 효율적이고 유니코드 문자의 전
        'config-license-gfdl' => 'GNU 자유 문서 사용 허가서 1.3 이상',
        'config-license-pd' => '퍼블릭 도메인',
        'config-license-cc-choose' => '다른 크리에이티브 커먼즈 라이선스 선택',
-       'config-license-help' => '많은 공개 위키는 모든 기여를 [http://freedomdefined.org/Definition 자유 라이선스] 하에 넣습니다.
\9d´ë\9f´ ê²½ì\9a° 커뮤니티 소유권의 이해를 할 수 있도록 하고 장기적인 기여를 장려합니다.
+       'config-license-help' => "많은 공개 위키는 모든 기여를 [http://freedomdefined.org/Definition 자유 라이선스] 하에 넣습니다.
\9d´ë \87ê²\8c í\95\98ë©´ 커뮤니티 소유권의 이해를 할 수 있도록 하고 장기적인 기여를 장려합니다.
 일반적으로 개인 또는 회사 위키에 대해서는 필요하지 않습니다.
 
-위키백과의 텍스트를 사용할 수 있도록 하고 위키백과가 위키에서 복사한 텍스트를 사용할 수 있도록 원한다면 크리에이티브 커먼즈 저작자표시-동일조건변경허락으로 선택해야 합니다.
+위키백과의 텍스트를 사용할 수 있도록 하고 위키백과가 위키에서 복사한 텍스트를 사용할 수 있도록 원한다면 '''크리에이티브 커먼즈 저작자표시-동일조건변경허락'''으로 선택해야 합니다.
 
 위키백과는 이전에 GNU 자유 문서 사용 허가서를 사용했습니다.
-GFDL은 유효한 라이선스이지만 이해하기 어렵습니다.
-GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
+GFDL은 유효한 라이선스이지만 내용을 이해하기 어렵습니다.
+GFDL 하에 사용을 허가한 내용을 재사용하는 것도 어렵습니다.",
        'config-email-settings' => '이메일 설정',
        'config-enable-email' => '발신 이메일 활성화',
        'config-enable-email-help' => '이메일을 작동하려면 [http://www.php.net/manual/en/mail.configuration.php PHP의 메일 설정]을 올바르게 설정해야 합니다.
@@ -11045,7 +11156,7 @@ GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
        'config-email-watchlist' => '주시문서 목록 알림 활성화',
        'config-email-watchlist-help' => '환경 설정에서 활성화한 경우 사용자가 주시한 문서에 대한 알림을 받도록 활성화합니다.',
        'config-email-auth' => '이메일 인증 활성화',
-       'config-email-auth-help' => "이 설정이 활성화되어 있으면 사용자는 이메일 주소를 설정하거나 바꿀 때마다 그들에게 보낸 링크를 사용하여 이메일 주소를 확인해야 합니다.
+       'config-email-auth-help' => "이 설정이 활성화되어 있으면 사용자는 이메일 주소를 설정하거나 바꿀 때마다 링크를 사용하여 이메일 주소를 확인해야 합니다.
 인증된 이메일 주소만 다른 사용자로부터의 이메일이나 바뀜 알림 이메일을 받을 수 있습니다.
 이메일 기능의 남용 가능성이 있기 때문에 이 옵션을 설정하는 것은 공개 위키에서 '''권장'''합니다.",
        'config-email-sender' => '반송 이메일 주소',
@@ -11055,7 +11166,7 @@ GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
        'config-upload-settings' => '그림과 파일 올리기',
        'config-upload-enable' => '파일 올리기 활성화',
        'config-upload-help' => '파일 올리기는 서버에 잠재적인 보안 위험에 쉽게 노출될 수 있습니다.
\9e\90ì\84¸í\95\9c ë\82´ì\9a©ì\9d\80 ë§¤ë\89´ì\96¼ì\9d\98 [//www.mediawiki.org/wiki/Manual:Security ë³´ì\95\88 ë¬¸ë\8b¨]ì\9d\84 ì\9d½ì\96´ë³´세요.
\9e\90ì\84¸í\95\9c ë\82´ì\9a©ì\9d\80 ë§¤ë\89´ì\96¼ì\9d\98 [//www.mediawiki.org/wiki/Manual:Security ë³´ì\95\88 ë¬¸ë\8b¨]ì\9d\84 ì°¸ê³ í\95\98세요.
 
 파일 올리기를 활성화하려면 미디어위키의 루트 디렉토리에 있는 <code>images</code> 하위 디렉토리에서 웹 서버가 기록할 수 있도록 모드를 바꿉니다.
 그 다음 이 옵션을 활성화합니다.',
@@ -11063,10 +11174,10 @@ GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
        'config-upload-deleted-help' => '삭제된 파일을 보관할 디렉토리를 선택하세요.
 이상적으로 웹에서 접근할 수 없게 해야 합니다.',
        'config-logo' => '로고 URL:',
-       'config-logo-help' => '미디어위키 기본 스킨은 사이드바 메뉴 위에 135×160픽셀의 로고를 포함하고 있습니다.
+       'config-logo-help' => '미디어위키의 기본 스킨은 사이드바 메뉴 위에 135×160 픽셀의 로고를 포함하고 있습니다.
 적당한 크기로 이미지를 올리고 URL을 여기에 입력하세요.
 
-ë¡\9cê³  ì\82¬ì\9a©ì\9d\84 ì\9b\90í\95\98ì§\80 ì\95\8aì\9c¼ë©´ ì\9d´ ì\83\81ì\9e\90를 ë¹\84ì\9b\8c ë\91\90ì\8b­ì\8b\9cì\98¤.',
+ë¡\9cê³  ì\82¬ì\9a©ì\9d\84 ì\9b\90í\95\98ì§\80 ì\95\8aì\9c¼ë©´ ì\9d´ ì\83\81ì\9e\90를 ë¹\84ì\9a°ì\84¸ì\9a\94.',
        'config-instantcommons' => '인스턴트 공용 활성화',
        'config-instantcommons-help' => '[//www.mediawiki.org/wiki/InstantCommons 인스턴트 공용]은 [//commons.wikimedia.org/ 위키미디어 공용] 사이트에서 찾을 수 있는 그림, 소리 및 다른 미디어를 위키에서 사용할 수 있도록 하는 기능입니다.
 이렇게 하려면 미디어위키가 인터넷에 접근해야합니다.
@@ -11100,7 +11211,7 @@ GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
        'config-install-alreadydone' => "'''경고:''' 이미 미디어위키를 설치했고 다시 설치하려고 합니다.
 다음 페이지에서 진행하세요.",
        'config-install-begin' => '"{{int:config-continue}}"을 누르면 미디어위키의 설치를 시작합니다.
-그래도 바꾸는 것을 원한다면 뒤로를 누릅니다.', # Fuzzy
+그래도 바꾸는 것을 원한다면 "{{int:config-back}}"를 누르세요.',
        'config-install-step-done' => '완료',
        'config-install-step-failed' => '실패',
        'config-install-extensions' => '확장 기능을 포함하는 중',
@@ -11118,7 +11229,7 @@ GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
 
 현재 미디어위키는 테이블을 웹 사용자가 소유해야 합니다. 다른 웹 계정 이름을 지정하거나 "뒤로"를 클릭하고 적절한 권한의 설치할 사용자를 지정하세요.',
        'config-install-user' => '데이터베이스 사용자를 만드는 중',
-       'config-install-user-alreadyexists' => '"$1" ì\82¬ì\9a©ì\9e\90ê°\80 ì\9d´ë¯¸ ì\9e\88ì\9d\8c',
+       'config-install-user-alreadyexists' => '"$1" ì\82¬ì\9a©ì\9e\90ê°\80 ì\9d´ë¯¸ ì\9e\88ì\8aµë\8b\88ë\8b¤',
        'config-install-user-create-failed' => '"$1" 사용자 만드는 중 실패: $2',
        'config-install-user-grant-failed' => '"$1" 사용자에 대한 권한 부여 실패: $2',
        'config-install-user-missing' => '지정한 "$1" 사용자가 존재하지 않습니다.',
@@ -11144,7 +11255,7 @@ GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
        'config-install-done' => "'''축하합니다!'''
 미디어위키가 성공적으로 설치되었습니다.
 
-설치 마법사가 <code>LocalSettings.php</code> 파일을 만들었습니다.
+설치 프로그램이 <code>LocalSettings.php</code> 파일을 만들었습니다.
 모든 설정이 포함되어 있습니다.
 
 파일을 다운로드하여 위키 설치의 거점에 넣어야 합니다. (index.php와 같은 디렉토리) 다운로드가 자동으로 시작됩니다.
@@ -11153,10 +11264,10 @@ GFDL 하에 라이선스 내용을 재사용하는 것도 어렵습니다.',
 
 $3
 
-'''참고''': ì§\80ê¸\88 ì\9d´ë \87ê²\8c í\95\98ì§\80 ì\95\8aì\9c¼ë©´, ì\9d´ ì\84¤ì \95 í\8c\8cì\9d¼ì\9d\84 ë\8b¤ì\9a´ë¡\9cë\93\9cí\95\98ì§\80 ì\95\8aê³  ì\84¤ì¹\98를 ì¢\85ë£\8cí\95  ê²½ì\9a° ë§\8cë\93¤ì\96´ì§\84 ì\84¤ì \95 파일은 나중에 사용할 수 없습니다.
+'''참고''': ì\9d´ ì\83\9dì\84±í\95\9c ì\84¤ì \95 í\8c\8cì\9d¼ì\9d\84 ë\8b¤ì\9a´ë¡\9cë\93\9cí\95\98ì§\80 ì\95\8aê³  ì\84¤ì¹\98를 ë\81\9dë\82´ë©´ ì\9d´ 파일은 나중에 사용할 수 없습니다.
 
 완료되었으면 '''[$2 위키에 들어갈 수 있습니다]'''.",
-       'config-download-localsettings' => 'LocalSettings.php 다운로드',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> 다운로드',
        'config-help' => '도움말',
        'config-nofile' => '"$1" 파일을 찾을 수 없습니다. 이미 삭제되었나요?',
        'mainpagetext' => "'''미디어위키가 성공적으로 설치되었습니다.'''",
@@ -11192,21 +11303,21 @@ $messages['ksh'] = array(
        'config-desc' => 'Et Projramm för Mediwiki opzesäze.',
        'config-title' => 'MediaWiki $1 opsäze',
        'config-information' => 'Enfomazjuhn',
-       'config-localsettings-upgrade' => 'De Dattei <code lang="en">LocalSettings.php</code> es ald doh.
+       'config-localsettings-upgrade' => 'De Dattei <code lang="en"><code>LocalSettings.php</code></code> es ald doh.
 De Projramme vum Wiki künne op der neußte Shtand jebraat wääde:
 Donn doför dä Wäät vum <code lang="en">$wgUpgradeKey</code> en dat heh Feld enjävve.
-Do fenggs_et en dä Dattei <code lang="en">LocalSettings.php</code> om ẞööver.',
-       'config-localsettings-cli-upgrade' => 'En Dattei <code lang="en">LocalSettings.php</code> es jefonge woode.
+Do fenggs_et en dä Dattei <code lang="en"><code>LocalSettings.php</code></code> om ẞööver.',
+       'config-localsettings-cli-upgrade' => 'En Dattei <code lang="en"><code>LocalSettings.php</code></code> es jefonge woode.
 Öm et Wiki_Projramm op ene neue Shtand ze bränge, donn <code lang="en">update.php</code> oproofe.',
        'config-localsettings-key' => 'Der Schlößel för et Projramm op ene neue Schtand ze bränge:',
        'config-localsettings-badkey' => 'Dinge Schlößel paß nit.',
        'config-upgrade-key-missing' => 'Mer han jefonge, dat MediaWiki ald enschtalleed es.
-Üm de Projramme un Daate o der neue Schtand bränge ze künne, dunn aan et Engk vun dä Dattei <code lang="en">LocalSettings.php</code> op dämm ẞööver:
+Üm de Projramme un Daate o der neue Schtand bränge ze künne, dunn aan et Engk vun dä Dattei <code lang="en"><code>LocalSettings.php</code></code> op dämm ẞööver:
 
 $1
 
 aanhange.',
-       'config-localsettings-incomplete' => 'Mer han en Dattei <code lang="en">LocalSettings.php:</code> jefonge, ävver di schingk nit kumplätt ze sin.
+       'config-localsettings-incomplete' => 'Mer han en Dattei <code lang="en"><code>LocalSettings.php</code>:</code> jefonge, ävver di schingk nit kumplätt ze sin.
 De Varijable <code lang="en">$1</code> es nit jesatz.
 Bes esu joot, un donn di Dattei esu aanpaße, dat se jesaz ea, un dann donn op „{{int:config-continue}}“ klecke.',
        'config-localsettings-connection-error' => 'Ene Fähler es opjetrodde wi mer en Verbendung noh de Datebangk opmaache wullte met dä Enshtellunge uß dä Dattei <code lang="en">LocalSettings</code> udder uß dä Dattei <code lang="en">LocalSettings</code> un et hät nit jeflupp. Bes esu joot un dat repareere un versöhg et dann norr_ens.
@@ -11344,7 +11455,7 @@ Heh jeihd et nit wigger.',
        'config-using531' => 'MediaWiki läuf nit met PHP $1 zosamme wääje enem [//bugs.php.net/bug.php?id=50394 Fähler em Zosammehang met Parrameetere för <code lang="en">__call()</code>].
 Jangk op de Version 5.3.2 vum <i lang="en">PHP</i> ov dohnoh, udder op de Version 5.3.0 udder dovöör, öm dat Problem ze ömjonn.
 Heh jeiht et nit wigger.',
-       'config-suhosin-max-value-length' => '<i lang="en">Suhosin</i> es enschtalleet. Dröm kann ene <code lang="en">GET</code>-Parrameeter nit övver {{PLURAL:$1|ei Byte|$q Bytes|noll Byte}} lang wääde. En MediaWiki singe <i lang="en">ResourceLoader</i> kütt doh zwa drömeröm, ävver dat brems. Wann müjelesch, doht <code lang="en">suhosin.get.max_value_length</code> en dä Dattei <code lang="en">php.ini</code> op 1024 Bytes udder drövver enschtälle. un dann moß <code lang="en">$wgResourceLoaderMaxQueryLength</code> en dä Dattei <code lang="en">LocalSettings.php</code> op däsälve Wäät jesaz wääde.',
+       'config-suhosin-max-value-length' => '<i lang="en">Suhosin</i> es enschtalleet. Dröm kann ene <code lang="en">GET</code>-Parrameeter nit övver {{PLURAL:$1|ei Byte|$q Bytes|noll Byte}} lang wääde. En MediaWiki singe <i lang="en">ResourceLoader</i> kütt doh zwa drömeröm, ävver dat brems. Wann müjelesch, doht <code lang="en">suhosin.get.max_value_length</code> en dä Dattei <code lang="en">php.ini</code> op 1024 Bytes udder drövver enschtälle. un dann moß <code lang="en">$wgResourceLoaderMaxQueryLength</code> en dä Dattei <code lang="en">LocalSettings.php</code> op däsälve Wäät jesaz wääde.', # Fuzzy
        'config-db-type' => 'De Zoot Daatebangk:',
        'config-db-host' => 'Dä Name vun däm Rääschner met dä Daatebangk:',
        'config-db-host-help' => 'Wann Dinge ẞööver för de Daatebangk ob enem andere Rääschner es, donn heh dämm singe Name udder dämm sing <i lang="en">IP</i>-Addräß enjävve.
@@ -11436,7 +11547,7 @@ Wann dat Daatebangk_Süßteem, wat De nämme wells, onge nit dobei es, dann donn
        'config-support-postgres' => '* <i lang="en">$1</i> es e bikannt Daatebangksüßteem met offe Quälltäxde, un en och en Wahl nävve <i lang="en">MySQL</i> ([http://www.php.net/manual/de/pgsql.installation.php Aanleidung för et Övversäze un Enreeschte von PHP met <i lang="en">PostgreSQL</i> dobei, op Deutsch]) Et sinn_er ävver paa klein Fählershe bekannt, um kunne dat em Momang för et reschtijje Werke nit emfähle.',
        'config-support-sqlite' => '* <i lang="en">$1</i> es e eijfach Daatebangksüßteem, wat joot ongershtöz weed. ([http://www.php.net/manual/de/pdo.installation.php Aanleidong för et Övversäze un Enreeschte von PHP met <i lang="en">SQLite</i> dobei, op Deutsch])',
        'config-support-oracle' => '* <i lang="en">$1</i> es e jeschäfflesch Daatebangksüßteem för Ferme. ([http://www.php.net/manual/de/oci8.installation.php Aanleidong för et Övversäze un Enreeschte von PHP met <i lang="en">OCI8</i> dobei, op Deutsch])',
-       'config-support-ibm_db2' => '* $1 es en Datebengk för et Jeschäff un fö Ongernehme.',
+       'config-support-ibm_db2' => '* $1 es en Datebengk för et Jeschäff un fö Ongernehme.', # Fuzzy
        'config-header-mysql' => 'De Enshtällunge för de <i lang="en">MySQL</i> Daatebangk',
        'config-header-postgres' => 'De Enshtällunge för de <i lang="en">PostgreSQL</i> Daatebangk',
        'config-header-sqlite' => 'De Enshtällunge för de <i lang="en">SQLite</i> Daatebangk',
@@ -11500,7 +11611,7 @@ Dat dom_mer ävver '''nit vörschlonn'''em Jääjedeil, ußer, wann et Probleme
 
 Mer kann dat Wiki jäz [$1 bruche].',
        'config-regenerate' => 'Donn de Dattei <code lang="en">LocalSettings.php</code> neu opsäze →',
-       'config-show-table-status' => 'Et Kommando <code lang="en">SHOW TABLE STATUS</code> aan de Daatebangk es donävve jejange!',
+       'config-show-table-status' => 'Et Kommando <code lang="en"><code>SHOW TABLE STATUS</code></code> aan de Daatebangk es donävve jejange!',
        'config-unknown-collation' => "'''Opjepaß:''' De Daatabangk deiht en onbikannte Reijefollsch bruche, för Booshtaabe un Zeishe ze verjliishe un ze zotteere.",
        'config-db-web-account' => 'Dä Zohjang zor Daatebangk för et Wiki',
        'config-db-web-help' => 'Donn ene Name un e Paßwoot för der Zohjang zor Daatebangk för et Wiki em nomaale Bedrief aanjävve.',
@@ -11573,7 +11684,7 @@ Do künnts jez der Räß vun de einzel Enshtellunge övverjonn, un et Wiki tirä
        'config-optional-continue' => 'De wells noch mieh Frore jeshtallt krijje un noch mieh Enshtällunge maache?',
        'config-optional-skip' => 'Nä, lohß dä Ömshtand, donn eifarr_et Wiki opsäze.',
        'config-profile' => 'Enshtällunge för de Metmaacher ier Rääschte:',
-       'config-profile-wiki' => 'E tradizjonäll offe Wiki',
+       'config-profile-wiki' => 'E tradizjonäll offe Wiki', # Fuzzy
        'config-profile-no-anon' => 'Schriever möße enlogge',
        'config-profile-fishbowl' => 'Bloß ußdröcklesch zohjelohße Schriever',
        'config-profile-private' => 'E jeschloße Privat_Wiki',
@@ -11591,7 +11702,7 @@ Esu häß De de Wahl:
 
 '''{{int:config-profile-private}}''' kann nur lässe, wäh en et Wiki zohjelohße es, un desellve Jropp kann uch schrieve.
 
-Noch ander un un opwändijere Enshtellunge för de Rääschte sin müjjelesch, wann et Wiki ens aam Loufe es. Loor Der doför de [//www.mediawiki.org/wiki/Manual:User_rights zopaß Hölp em Handbooch] aan.",
+Noch ander un un opwändijere Enshtellunge för de Rääschte sin müjjelesch, wann et Wiki ens aam Loufe es. Loor Der doför de [//www.mediawiki.org/wiki/Manual:User_rights zopaß Hölp em Handbooch] aan.", # Fuzzy
        'config-license' => 'Urhävverrääsch un Lizänz:',
        'config-license-none' => 'Kein Fooßreih övver de Lizänz',
        'config-license-cc-by-sa' => '<i lang="en">Creative Commons</i> Der Name moß jenannt sin, et Wiggerjävve es zohjelohße onger dersellve Bedengunge',
@@ -11674,7 +11785,7 @@ Do kann se heh un jez aanschallde, ävver se künnte noch zohsäzlesch Enshtellu
 Et sühd esu uß, wi wann De MediaWiki ald enshtalleet hätß, un wöhrs aam Versöhke, dat norr_ens ze donn.
 Jang wigger op de näähßte Sigg.",
        'config-install-begin' => 'Wann De op „{{int:config-continue}}“ klecks, jeiht de Enshtallazjuhn vum MediaWiki loßß.
-Wann De noch Änderonge maache wells, dann kleck op „{{int:config-back}}“.',
+Wann De noch Änderonge maache wells, dann kleck op „{{int:config-back}}“.', # Fuzzy
        'config-install-step-done' => 'jedonn',
        'config-install-step-failed' => 'donävve jejange',
        'config-install-extensions' => 'Zohsazprojramme enjeschloße',
@@ -11741,7 +11852,7 @@ Wann De mem Ronger- un widder Huhlaade fäädesh bes, kanns De '''[\$2 en Ding W
 Dat es och all op Änglesch:
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]', # Fuzzy
 );
 
 /** Kurdish (Latin script) (Kurdî (latînî)‎)
@@ -11781,6 +11892,7 @@ $messages['lad'] = array(
 
 /** Luxembourgish (Lëtzebuergesch)
  * @author Robby
+ * @author 아라
  */
 $messages['lb'] = array(
        'config-desc' => 'Den Installatiounsprogramm vu MediaWiki',
@@ -11788,12 +11900,12 @@ $messages['lb'] = array(
        'config-information' => 'Informatioun',
        'config-localsettings-upgrade' => "'''Opgepasst''': E Fichier <code>LocalSettings.php</code> gouf fonnt.
 Är Software kann aktualiséiert ginn, setzt w.e.g. de Wäert vum <code>\$wgUpgradeKey</code> an d'Këscht.
-Dir fannt en am LocalSettings.php.",
+Dir fannt en am <code>LocalSettings.php</code>.",
        'config-localsettings-key' => 'Aktualisatiounsschlëssel:',
        'config-localsettings-badkey' => 'De Schlëssel deen Dir aginn hutt ass net korrekt',
-       'config-localsettings-incomplete' => 'De Fichier LocalSettings.php schéngt net komplett ze sinn.
+       'config-localsettings-incomplete' => 'De Fichier <code>LocalSettings.php</code> schéngt net komplett ze sinn.
 D\'Variabel $1 ass net definéiert.
-Ännert w.e.g. de Fichier LocalSettings.php esou datt déi Variabel definéiert ass a klickt op "Virufueren".',
+Ännert w.e.g. de Fichier <code>LocalSettings.php</code> esou datt déi Variabel definéiert ass a klickt op "{{int:Config-continue}}".',
        'config-session-error' => 'Feeler beim Starte vun der Sessioun: $1',
        'config-no-session' => "D'Donnéeë vun ärer Sessioun si verluergaangen!
 Kuckt Är php.ini no a vergewëssert Iech datt <code>session.save_path</code>  op adequate REpertoire agestallt ass.",
@@ -11886,7 +11998,7 @@ Wann et de Kont net gëtt, a wann den Installatiouns-Kont genuch Rechter huet, g
        'config-type-sqlite' => 'SQLite',
        'config-type-oracle' => 'Oracle',
        'config-type-ibm_db2' => 'IBM DB2',
-       'config-support-ibm_db2' => '* $1 ass eng kommerziell Firma fir Datebanken',
+       'config-support-ibm_db2' => '* $1 ass eng kommerziell Firma fir Datebanken', # Fuzzy
        'config-header-mysql' => 'MySQL-Astellungen',
        'config-header-postgres' => 'PostgreSQL-Astellungen',
        'config-header-sqlite' => 'SQLite-Astellungen',
@@ -11906,7 +12018,7 @@ E gëtt fir den Numm vum SQLite Date-Fichier benotzt.',
        'config-upgrade-done-no-regenerate' => "D'Aktualisatioun ass ofgeschloss.
 
 Dir kënnt elo [$1 ufänken Är Wiki ze benotzen]",
-       'config-regenerate' => 'LocalSettings.php regeneréieren →',
+       'config-regenerate' => '<code>LocalSettings.php</code> regeneréieren →',
        'config-db-web-account' => 'Datebankkont fir den Accès iwwer de Web',
        'config-db-web-account-same' => 'Dee selwechte Kont wéi bei der Installatioun benotzen',
        'config-db-web-create' => 'De Kont uleeë wann et e net scho gëtt',
@@ -11944,7 +12056,7 @@ Dir kënnt elo déi Astellungen déi nach iwwreg sinn iwwersprangen an d'Wiki el
        'config-optional-continue' => 'Stellt mir méi Froen.',
        'config-optional-skip' => "Ech hunn es genuch, installéier just d'Wiki.",
        'config-profile' => 'Profil vun de Benotzerrechter:',
-       'config-profile-wiki' => 'Traditionell Wiki',
+       'config-profile-wiki' => 'Traditionell Wiki', # Fuzzy
        'config-profile-no-anon' => 'Uleeë vun engem Benotzerkont verlaangt',
        'config-profile-fishbowl' => 'Nëmmen autoriséiert Editeuren',
        'config-profile-private' => 'Privat Wiki',
@@ -11983,7 +12095,7 @@ Dir kënnt elo déi Astellungen déi nach iwwreg sinn iwwersprangen an d'Wiki el
        'config-install-sysop' => 'Administrateur Benotzerkont gëtt ugeluecht',
        'config-install-extension-tables' => "D'Tabelle fir déi aktivéiert Erweiderunge ginn ugeluecht",
        'config-install-mainpage-failed' => "D'Haaptsäit konnt net dragesat ginn: $1",
-       'config-download-localsettings' => 'LocalSettings.php eroflueden',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> eroflueden',
        'config-help' => 'Hëllef',
        'config-nofile' => 'De Fichier "$1" gouf net fonnt. Gouf e geläscht?',
        'mainpagetext' => "'''MediaWiki gouf installéiert.'''",
@@ -11992,7 +12104,7 @@ Dir kënnt elo déi Astellungen déi nach iwwreg sinn iwwersprangen an d'Wiki el
 == Starthëllefen ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Hëllef bei der Konfiguratioun]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki-FAQ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailinglëscht vun neie MediaWiki-Versiounen]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailinglëscht vun neie MediaWiki-Versiounen]", # Fuzzy
 );
 
 /** Lingua Franca Nova (Lingua Franca Nova)
@@ -12269,6 +12381,7 @@ $messages['min'] = array(
 
 /** Macedonian (македонски)
  * @author Bjankuloski06
+ * @author 아라
  */
 $messages['mk'] = array(
        'config-desc' => 'Инсталатор на МедијаВики',
@@ -12276,19 +12389,19 @@ $messages['mk'] = array(
        'config-information' => 'Информации',
        'config-localsettings-upgrade' => 'Востановена е податотека <code>LocalSettings.php</code>.
 За да ја надградите инсталцијава, внесете ја вредноста на <code>$wgUpgradeKey</code> во полето подолу.
-Тоа е го најдете во LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Утврдено е присуството на податотеката „LocalSettings.php“.
-За да ја надградите инсталацијата, пуштете ја „update.php“ наместо горенаведената.',
+Тоа е го најдете во <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Утврдено е присуството на податотеката „<code>LocalSettings.php</code>“.
+За да ја надградите инсталацијата, пуштете ја „<code>update.php</code>“ наместо горенаведената.',
        'config-localsettings-key' => 'Надградбен клуч:',
        'config-localsettings-badkey' => 'Клучот што го наведовте е погрешен',
        'config-upgrade-key-missing' => 'Востановена е постоечка инсталација на МедијаВики.
-За да ја надградите, вметнете го следниов ред на дното од вашата страница LocalSettings.php:
+За да ја надградите, вметнете го следниов ред на дното од вашата страница <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Постоечката страница LocalSettings.php е нецелосна.
+       'config-localsettings-incomplete' => 'Постоечката страница <code>LocalSettings.php</code> е нецелосна.
 Не е поставена променливата $1.
-Изменете ја страницата LocalSettings.php така што ќе ѝ зададете вредност на променливата, па стиснете на „Продолжи“.',
-       'config-localsettings-connection-error' => 'Се појави грешка при поврзувањето со базата користејќи ги поставките назначени во LocalSettings.php или AdminSettings.php. Исправете ги овие поставки и обидете се повторно.
+Изменете ја страницата <code>LocalSettings.php</code> така што ќе ѝ зададете вредност на променливата, па стиснете на „{{int:Config-continue}}“.',
+       'config-localsettings-connection-error' => 'Се појави грешка при поврзувањето со базата користејќи ги поставките назначени во <code>LocalSettings.php</code> или <code>AdminSettings.php</code>. Исправете ги овие поставки и обидете се повторно.
 
 $1',
        'config-session-error' => 'Грешка при започнување на сесијата: $1',
@@ -12421,7 +12534,7 @@ $1
 Надградете го на PHP 5.2.9 и libxml2 2.7.3 или нивни понови верзии! ПРЕКИНУВАМ ([//bugs.php.net/bug.php?id=45996 грешката е заведена во PHP]).',
        'config-using531' => 'МедијаВики не може да се користи со PHP $1 поради грешка кај упатните параметри за <code>__call()</code>.
 За да го решите проблемот, надградете го на PHP 5.3.2 или понова верзија, или пак користете го постариот PHP 5.3.0.',
-       'config-suhosin-max-value-length' => 'Suhosin е инсталиран и ја ограничува должината на параметарот GET на $1 bytes. Делот ResourceLoader на МедијаВики ќе ја заобиколува ова граница, но со тоа ќе се влоши делотворноста. Ако е воопшто можно, на suhosin.get.max_value_length треба да го наместите на 1024 или поевеќе во php.ini , и да му ја зададете истата вредност на $wgResourceLoaderMaxQueryLength во LocalSettings.php .',
+       'config-suhosin-max-value-length' => 'Suhosin е инсталиран и ја ограничува должината на параметарот GET на $1 бајти. Делот ResourceLoader на МедијаВики ќе ја заобиколува ова граница, но со тоа ќе се влоши делотворноста. Ако е воопшто можно, на <code>suhosin.get.max_value_length</code> треба да го наместите на 1024 или повеќе во <code>php.ini</code>, и да му ја зададете истата вредност на <code>$wgResourceLoaderMaxQueryLength</code> во <code>LocalSettings.php</code>.',
        'config-db-type' => 'Тип на база:',
        'config-db-host' => 'Домаќин на базата:',
        'config-db-host-help' => 'Ако вашата база е на друг опслужувач, тогаш тука внесете го името на домаќинот или IP-адресата.
@@ -12505,7 +12618,7 @@ $1
        'config-support-postgres' => '* $1 е популарен систем на бази на податоци со отворен код кој претставува алтернатива на MySQL ([http://www.php.net/manual/en/pgsql.installation.php како да составите PHP со поддршка за PostgreSQL]). Може сè уште да има некои грешки. па затоа не се препорачува за употреба во производна средина.',
        'config-support-sqlite' => '* $1 е лесен систем за бази на податоци кој е многу добро поддржан. ([http://www.php.net/manual/en/pdo.installation.php Како да составите PHP со поддршка за SQLite], користи PDO)',
        'config-support-oracle' => '* $1 е база на податоци на комерцијално претпријатие. ([http://www.php.net/manual/en/oci8.installation.php Како да составите PHP со поддршка за OCI8])',
-       'config-support-ibm_db2' => '* $1 is комерцијална база на податоциза фирми.',
+       'config-support-ibm_db2' => '* $1 е комерцијална база на податоциза фирми. ([http://www.php.net/manual/en/ibm-db2.installation.php Како да составите PHP со поддршка за IBM DB2])',
        'config-header-mysql' => 'Нагодувања на MySQL',
        'config-header-postgres' => 'Нагодувања на PostgreSQL',
        'config-header-sqlite' => 'Нагодувања на SQLite',
@@ -12572,8 +12685,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => 'Надградбата заврши.
 
 Сега можете да [$1 почнете да го користите викито].',
-       'config-regenerate' => 'Пресоздај LocalSettings.php →',
-       'config-show-table-status' => 'Барањето SHOW TABLE STATUS не успеа!',
+       'config-regenerate' => 'Пресоздај <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Барањето <code>SHOW TABLE STATUS</code> не успеа!',
        'config-unknown-collation' => "'''Предупредување:''' Базата корисни непрепознаена упатна споредба.",
        'config-db-web-account' => 'Сметка на базата за мрежен пристап',
        'config-db-web-help' => 'Одберете корисничко име и лозинка што ќе ги користи мрежниот опслужувач за поврзување со опслужувачот на базта на податоци во текот на редовната работа со викито.',
@@ -12802,7 +12915,7 @@ $3
 '''Напомена''': Ако ова не го направите сега, податотеката со поставки повеќе нема да биде на достапна.
 
 Откога ќе завршите со тоа, можете да '''[$2 влезете на вашето вики]'''.",
-       'config-download-localsettings' => 'Преземи го LocalSettings.php',
+       'config-download-localsettings' => 'Преземи го <code>LocalSettings.php</code>',
        'config-help' => 'помош',
        'config-nofile' => 'Податотеката „$1“ не е пронајдена. Да не е избришана?',
        'mainpagetext' => "'''МедијаВики е успешно инсталиран.'''",
@@ -12882,7 +12995,7 @@ $1
        'config-connection-error' => '$1.
 
 താഴെ നൽകിയിരിക്കുന്ന ഹോസ്റ്റ്, ഉപയോക്തൃനാമം, രഹസ്യവാക്ക് എന്നിവ പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക.',
-       'config-regenerate' => 'LocalSettings.php പുനഃസൃഷ്ടിക്കുക →',
+       'config-regenerate' => '<code>LocalSettings.php</code> പുനഃസൃഷ്ടിക്കുക →',
        'config-mysql-engine' => 'സ്റ്റോറേജ് എൻജിൻ:',
        'config-site-name' => 'വിക്കിയുടെ പേര്:',
        'config-site-name-help' => 'ഇത് ബ്രൗസറിന്റെ ടൈറ്റിൽ ബാറിലും മറ്റനേകം ഇടങ്ങളിലും പ്രദർശിപ്പിക്കപ്പെടും.',
@@ -12914,7 +13027,7 @@ $1
 ബാക്കിയുള്ളവ അവഗണിച്ച് വിക്കി ഇൻസ്റ്റോൾ ചെയ്യാവുന്നതാണ്.',
        'config-optional-continue' => 'കൂടുതൽ ചോദ്യങ്ങൾ ചോദിക്കൂ.',
        'config-optional-skip' => 'എനിക്ക് മടുത്തു, ഒന്ന് ഇൻസ്റ്റോൾ ചെയ്ത് തീർക്ക്.',
-       'config-profile-wiki' => 'പരമ്പരാഗത വിക്കി',
+       'config-profile-wiki' => 'പരമ്പരാഗത വിക്കി', # Fuzzy
        'config-profile-no-anon' => 'അംഗത്വ സൃഷ്ടി ചെയ്യേണ്ടതുണ്ട്',
        'config-profile-fishbowl' => 'അനുവാദമുള്ളവർ മാത്രം തിരുത്തുക',
        'config-profile-private' => 'സ്വകാര്യ വിക്കി',
@@ -12968,7 +13081,7 @@ $3
 == പ്രാരംഭസഹായികൾ ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings ക്രമീകരണങ്ങളുടെ പട്ടിക]
 * [//www.mediawiki.org/wiki/Manual:FAQ മീഡിയവിക്കി പതിവുചോദ്യങ്ങൾ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce മീഡിയവിക്കി പ്രകാശന മെയിലിങ് ലിസ്റ്റ്]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce മീഡിയവിക്കി പ്രകാശന മെയിലിങ് ലിസ്റ്റ്]', # Fuzzy
 );
 
 /** Mongolian (монгол)
@@ -13163,7 +13276,7 @@ Speċifika isem tal-utent differenti.',
 Jekk trid tista' taqbeż il-parti li jmiss tal-konfigurazzjoni u sempliċiment tinstalla l-wiki.",
        'config-optional-continue' => 'Staqsini aktar mistoqsijiet.',
        'config-optional-skip' => 'Xbajt diġà, installa l-wiki.',
-       'config-profile-wiki' => 'Wiki tradizzjonali',
+       'config-profile-wiki' => 'Wiki tradizzjonali', # Fuzzy
        'config-profile-no-anon' => 'Huwa obbligatorju l-ħolqien tal-kont',
        'config-profile-fishbowl' => 'Edituri awtorizzati biss',
        'config-profile-private' => 'Wiki privata',
@@ -13177,7 +13290,7 @@ Jekk trid tista' taqbeż il-parti li jmiss tal-konfigurazzjoni u sempliċiment t
        'config-upload-deleted-help' => "Agħżel direttorju fejn iżżomm fajls imħassra.
 Idealment, dan m'għandux ikun aċċessibbli mill-web.",
        'config-logo' => 'URL tal-logo:',
-       'config-download-localsettings' => 'Niżżel LocalSettings.php',
+       'config-download-localsettings' => 'Niżżel <code>LocalSettings.php</code>',
        'config-help' => 'għajnuna',
        'config-nofile' => 'Il-fajl "$1" ma setax jinstab. Dan ġie mħassar?',
        'mainpagetext' => "'''MediaWiki ġie installat b'suċċess.'''",
@@ -13240,6 +13353,7 @@ $messages['nan'] = array(
 /** Norwegian Bokmål (norsk (bokmål)‎)
  * @author Event
  * @author Nghtwlkr
+ * @author 아라
  */
 $messages['nb'] = array(
        'config-desc' => 'Installasjonsprogrammet for MediaWiki',
@@ -13247,19 +13361,19 @@ $messages['nb'] = array(
        'config-information' => 'Informasjon',
        'config-localsettings-upgrade' => 'En <code>LocalSettings.php</code>-fil har blitt oppdaget.
 For å oppgradere denne installasjonen, skriv inn verdien av <code>$wgUpgradeKey</code> i boksen nedenfor.
-Du finner denne i LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => "Filen ''LocalSettings.php'' er funnet.
+Du finner denne i <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => "Filen ''<code>LocalSettings.php</code>'' er funnet.
 For å oppgradere denne installasjonen, vennligst kjør ''update.php'' i stedet",
        'config-localsettings-key' => 'Oppgraderingsnøkkel:',
        'config-localsettings-badkey' => 'Nøkkelen du oppga er feil.',
        'config-upgrade-key-missing' => "En eksisterende installasjon av MediaWiki er funnet.
-For å oppgradere denne installasjonen, vær vennlig å legge til følgende linje helt til slutt i din ''LocalSettings.php''-fil:
+For å oppgradere denne installasjonen, vær vennlig å legge til følgende linje helt til slutt i din ''<code>LocalSettings.php</code>''-fil:
 
 $1",
-       'config-localsettings-incomplete' => "Den eksisterende ''LocalSettings.php'' ser ut til å være ufullstendig.
+       'config-localsettings-incomplete' => "Den eksisterende ''<code>LocalSettings.php</code>'' ser ut til å være ufullstendig.
 Variabelen $1 har ingen verdi.
-Vær vennlig å endre ''LocalSettings.php'' slik at variabelen får en verdi, og klikk ''Fortsett''.",
-       'config-localsettings-connection-error' => "Det ble funnet en feil ved tilknytning av databasen med innstillingene i ''LocalSettings.php'' eller ''AdminSettings.php''. Vær vennlig å rette opp disse innstillingene og prøv igjen.
+Vær vennlig å endre ''<code>LocalSettings.php</code>'' slik at variabelen får en verdi, og klikk ''{{int:Config-continue}}''.",
+       'config-localsettings-connection-error' => "Det ble funnet en feil ved tilknytning av databasen med innstillingene i ''<code>LocalSettings.php</code>'' eller ''<code>AdminSettings.php</code>''. Vær vennlig å rette opp disse innstillingene og prøv igjen.
 
 $1",
        'config-session-error' => 'Feil under oppstart av økt: $1',
@@ -13392,7 +13506,7 @@ Installasjon abortert.',
        'config-using531' => 'MediaWiki kan ikke brukes med PHP $1 på grunn av en feil med referanseparametere til <code>__call()</code>.
 Oppgrader til PHP 5.3.2 eller høyere, eller nedgrader til PHP 5.3.0 for å løse dette.
 Installasjonen avbrutt.',
-       'config-suhosin-max-value-length' => 'Suhosin er installert og begrenser GET-parameterlengder til $1 bytes. MediaWiki\'s ResourceLoader-komponent klarer å komme rundt denne begrensningen, med med redusert ytelse. På mulig bør du sette suhosin.get.max_value_length til minst 1024 i php.ini, og sette $wgResourceLoaderMaxQueryLength til samme verdi i LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'Suhosin er installert og begrenser GET-parameterlengder til $1 bytes. MediaWiki\'s ResourceLoader-komponent klarer å komme rundt denne begrensningen, med med redusert ytelse. På mulig bør du sette <code>suhosin.get.max_value_length</code> til minst 1024 i <code>php.ini</code>, og sette <code>$wgResourceLoaderMaxQueryLength</code> til samme verdi i LocalSettings.php.', # Fuzzy
        'config-db-type' => 'Databasetype:',
        'config-db-host' => 'Databasevert:',
        'config-db-host-help' => 'Hvis databasen kjører på en annen tjenermaskin, skriv inn vertsnavnet eller IP-adressen her.
@@ -13477,7 +13591,7 @@ Hvis du ikke ser databasesystemet du prøver å bruke i listen nedenfor, følg i
        'config-support-postgres' => '* $1 er et populært åpen kildekode-databasesystem som er et alternativ til MySQL ([http://www.php.net/manual/en/pgsql.installation.php hvordan kompilere PHP med PostgreSQL-støtte]). Det kan være noen små utestående feil og det anbefales ikke for bruk i et produksjonsmiljø.',
        'config-support-sqlite' => '* $1 er et lettvekts-databasesystem som er veldig godt støttet. ([http://www.php.net/manual/en/pdo.installation.php hvordan kompilere PHP med SQLite-støtte], bruker PDO)',
        'config-support-oracle' => '* $1 er en kommersiell bedriftsdatabase. ([http://www.php.net/manual/en/oci8.installation.php Hvordan kompilere PHP med OCI8-støtte])',
-       'config-support-ibm_db2' => '* $1 er en kommersiell bedriftsdatabase.',
+       'config-support-ibm_db2' => '* $1 er en kommersiell bedriftsdatabase.', # Fuzzy
        'config-header-mysql' => 'MySQL-innstillinger',
        'config-header-postgres' => 'PostgreSQL-innstillinger',
        'config-header-sqlite' => 'SQLite-innstillinger',
@@ -13544,8 +13658,8 @@ Dette er '''ikke anbefalt''' med mindre du har problemer med wikien din.",
        'config-upgrade-done-no-regenerate' => 'Oppgradering fullført.
 
 Du kan nå [$1 begynne å bruke wikien din].',
-       'config-regenerate' => 'Regenerer LocalSettings.php →',
-       'config-show-table-status' => 'SHOW TABLE STATUS etterspørselen mislyktes!',
+       'config-regenerate' => 'Regenerer <code>LocalSettings.php</code> →',
+       'config-show-table-status' => '<code>SHOW TABLE STATUS</code> etterspørselen mislyktes!',
        'config-unknown-collation' => "'''Advarsel:''' Databasen bruker en ukjent sortering.",
        'config-db-web-account' => 'Databasekonto for nettilgang',
        'config-db-web-help' => 'Velg brukernavnet og passordet som nettjeneren skal bruke for å koble til databasetjeneren under ordinær drift av wikien.',
@@ -13609,7 +13723,7 @@ Du kan hoppe over de resterende konfigurasjonene og installere wikien nå.',
        'config-optional-continue' => 'Spør meg flere spørsmål.',
        'config-optional-skip' => 'Jeg er lei, bare installer wikien.',
        'config-profile' => 'Brukerrettighetsprofil:',
-       'config-profile-wiki' => 'Tradisjonell wiki',
+       'config-profile-wiki' => 'Tradisjonell wiki', # Fuzzy
        'config-profile-no-anon' => 'Kontoopprettelse påkrevd',
        'config-profile-fishbowl' => 'Kun autoriserte bidragsytere',
        'config-profile-private' => 'Privat wiki',
@@ -13625,7 +13739,7 @@ En wiki med '''{{int:config-profile-no-anon}}''' tilbyr ekstra ansvarlighet, men
 '''{{int:config-profile-fishbowl}}'''-scenariet tillater godkjente brukere å redigere, mens publikum kan se sider, og også historikken.
 En '''{{int:config-profile-private}}''' tillater kun godkjente brukere å se sider, den samme gruppen som får lov til å redigere dem.
 
-Mer komplekse konfigurasjoner av brukerrettigheter er tilgjengelig etter installasjon, se det [//www.mediawiki.org/wiki/Manual:User_rights relevante manualavsnittet].",
+Mer komplekse konfigurasjoner av brukerrettigheter er tilgjengelig etter installasjon, se det [//www.mediawiki.org/wiki/Manual:User_rights relevante manualavsnittet].", # Fuzzy
        'config-license' => 'Opphavsrett og lisens:',
        'config-license-none' => 'Ingen lisensbunntekst',
        'config-license-cc-by-sa' => 'Creative Commons Navngivelse Del på samme vilkår',
@@ -13686,7 +13800,7 @@ For mer informasjon om denne funksjonen, inklusive instruksjoner om hvordan man
        'config-install-user-grant-failed' => 'Å gi tillatelse til brukeren «$1» mislyktes: $2',
        'config-install-tables' => 'Oppretter tabeller',
        'config-install-mainpage-failed' => 'Kunne ikke sette inn hovedside: $1',
-       'config-download-localsettings' => 'Last ned LocalSettings.php',
+       'config-download-localsettings' => 'Last ned <code>LocalSettings.php</code>',
        'config-help' => 'hjelp',
        'config-nofile' => 'Filen "$1" ble ikke funnet. Kan den være blitt slettet?',
        'mainpagetext' => "'''MediaWiki-programvaren er nå installert.'''",
@@ -13695,7 +13809,7 @@ For mer informasjon om denne funksjonen, inklusive instruksjoner om hvordan man
 ==Å starte==
 *[//www.mediawiki.org/wiki/Manual:Configuration_settings Oppsettsliste]
 *[//www.mediawiki.org/wiki/Manual:FAQ Ofte stilte spørsmål]
-*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki e-postliste]',
+*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki e-postliste]', # Fuzzy
 );
 
 /** Low German (Plattdüütsch)
@@ -13740,6 +13854,7 @@ $messages['ne'] = array(
  * @author SPQRobin
  * @author Siebrand
  * @author Tjcool007
+ * @author 아라
  */
 $messages['nl'] = array(
        'config-desc' => 'Het installatieprogramma voor MediaWiki',
@@ -13747,19 +13862,19 @@ $messages['nl'] = array(
        'config-information' => 'Gegevens',
        'config-localsettings-upgrade' => 'Er is een bestaand instellingenbestand <code>LocalSettings.php</code> gevonden.
 Voer de waarde van <code>$wgUpgradeKey</code> in in onderstaande invoerveld om deze installatie bij te werken.
-De instelling is terug te vinden in LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Het bestand LocalSettings.php is al aanwezig.
-Voer update.php uit om deze installatie bij te werken.',
+De instelling is terug te vinden in <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Het bestand <code>LocalSettings.php</code> is al aanwezig.
+Voer <code>update.php</code> uit om deze installatie bij te werken.',
        'config-localsettings-key' => 'Upgradesleutel:',
        'config-localsettings-badkey' => 'De sleutel die u hebt opgegeven is onjuist',
        'config-upgrade-key-missing' => 'Er is een bestaande installatie van MediaWiki aangetroffen.
-Plaats de volgende regel onderaan uw LocalSettings.php om deze installatie bij te werken:
+Plaats de volgende regel onderaan uw <code>LocalSettings.php</code> om deze installatie bij te werken:
 
 $1',
-       'config-localsettings-incomplete' => 'De bestaande inhoud van LocalSettings.php lijkt incompleet.
+       'config-localsettings-incomplete' => 'De bestaande inhoud van <code>LocalSettings.php</code> lijkt incompleet.
 De variabele $1 is niet ingesteld.
-Wijzig LocalSettings.php zodat deze variabele is ingesteld en klik op "Doorgaan".',
-       'config-localsettings-connection-error' => 'Er is een fout opgetreden tijdens het verbinden van de database met de instellingen uit LocalSettings.php of AdminSettings.php. Los het probleem met de instellingen op en probeer het daarna opnieuw.
+Wijzig <code>LocalSettings.php</code> zodat deze variabele is ingesteld en klik op "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Er is een fout opgetreden tijdens het verbinden van de database met de instellingen uit <code>LocalSettings.php</code> of <code>AdminSettings.php</code>. Los het probleem met de instellingen op en probeer het daarna opnieuw.
 
 $1',
        'config-session-error' => 'Fout bij het begin van de sessie: $1',
@@ -13894,7 +14009,9 @@ De installatie wordt afgebroken.',
        'config-using531' => 'PHP $1 is niet compatibel met MediaWiki vanwege een fout met betrekking tot referentieparameters met <code>__call()</code>.
 Werk uw PHP bij naar PHP 5.3.2 of hoger of werk bij naar de lagere versie PHP 5.3.0 om dit op te lossen.
 De installatie wordt afgebroken.',
-       'config-suhosin-max-value-length' => 'Suhosin is geïnstalleerd en beperkt de lengte van de GET-parameter tot $1 bytes. De ResourceLoader van MediaWiki omzeilt deze beperking, maar dat is slecht voor de prestaties. Als het mogelijk is, moet u de waarde "suhosin.get.max_value_length" in php.ini instellen op 1024 of hoger en $wgResourceLoaderMaxQueryLength in LocalSettings.php op dezelfde waarde instellen.',
+       'config-suhosin-max-value-length' => 'Suhosin is geïnstalleerd en beperkt de GET-parameter <code>length</code> tot $1 bytes.
+De ResourceLoader van MediaWiki omzeilt deze beperking, maar dat is slecht voor de prestaties.
+Als het mogelijk is, moet u de waarde "<code>suhosin.get.max_value_length</code>" in <code>php.ini</code> instellen op 1024 of hoger en <code>$wgResourceLoaderMaxQueryLength</code> in LocalSettings.php op dezelfde waarde instellen.',
        'config-db-type' => 'Databasetype:',
        'config-db-host' => 'Databasehost:',
        'config-db-host-help' => 'Als uw databaseserver een andere server is, voer dan de hostnaam of het IP-adres hier in.
@@ -13979,7 +14096,7 @@ Als u het databasesysteem dat u wilt gebruiken niet in de lijst terugvindt, volg
        'config-support-postgres' => '* $1 is een populair open source databasesysteem als alternatief voor MySQL ([http://www.php.net/manual/en/pgsql.installation.php hoe PHP gecompileerd moet zijn met ondersteuning voor PostgreSQL]). Het is mogelijk dat er een aantal bekende problemen zijn met MediaWiki in combinatie met deze database en daarom wordt PostgreSQL niet aanbevolen voor een productieomgeving.',
        'config-support-sqlite' => '* $1 is een zeer goed ondersteund lichtgewicht databasesysteem ([http://www.php.net/manual/en/pdo.installation.php hoe PHP gecompileerd zijn met ondersteuning voor SQLite]; gebruikt PDO)',
        'config-support-oracle' => '* $1 is een commerciële data voor grote bedrijven ([http://www.php.net/manual/en/oci8.installation.php PHP compileren met ondersteuning voor OCI8]).',
-       'config-support-ibm_db2' => '* $1 is een commerciële enterprisedatabase.',
+       'config-support-ibm_db2' => '* $1 is een commerciële enterprisedatabase. ([http://www.php.net/manual/en/ibm-db2.installation.php Hoe PHP compolieren met ondersteuning voor IBM DB2])',
        'config-header-mysql' => 'MySQL-instellingen',
        'config-header-postgres' => 'PostgreSQL-instellingen',
        'config-header-sqlite' => 'SQLite-instellingen',
@@ -14048,8 +14165,8 @@ Dit is '''niet aan te raden''' tenzij u problemen hebt met uw wiki.",
        'config-upgrade-done-no-regenerate' => 'Het bijwerken is afgerond.
 
 U kunt nu [$1 uw wiki gebruiken].',
-       'config-regenerate' => 'LocalSettings.php opnieuw aanmaken →',
-       'config-show-table-status' => 'Het uitvoeren van SHOW TABLE STATUS is mislukt!',
+       'config-regenerate' => '<code>LocalSettings.php</code> opnieuw aanmaken →',
+       'config-show-table-status' => 'Het uitvoeren van <code>SHOW TABLE STATUS</code> is mislukt!',
        'config-unknown-collation' => "'''Waarschuwing:''' de database gebruikt een collatie die niet wordt herkend.",
        'config-db-web-account' => 'Databasegebruiker voor webtoegang',
        'config-db-web-help' => 'Selecteer de gebruikersnaam en het wachtwoord die de webserver gebruikt om verbinding te maken met de databaseserver na de installatie.',
@@ -14132,13 +14249,13 @@ In MediaWiki is het eenvoudig om de recente wijzigingen te controleren en eventu
 Daarnaast vinden velen MediaWiki goed inzetbaar in vele andere rollen, en soms is het niet handig om helemaal \"op de wikimanier\" te werken.
 Daarom biedt dit installatieprogramma u de volgende keuzes voor de basisinstelling van gebruikersvrijheden:
 
-Een '''{{int:config-profile-wiki}}''' staat iedereen toe te bewerken, zonder zelfs aan te melden.
+Het profiel '''{{int:config-profile-wiki}}''' staat iedereen toe te bewerken, zonder zelfs aan te melden.
 Een wiki met '''{{int:config-profile-no-anon}}\" biedt extra verantwoordelijkheid, maar kan afschrikken toevallige gebruikers afschrikken.
 
 Het scenario '''{{int:config-profile-fishbowl}}''' laat gebruikers waarvoor dat is ingesteld bewerkt, maar andere gebruikers kunnen alleen pagina's bekijken, inclusief de bewerkingsgeschiedenis.
 In een '''{{int:config-profile-private}}''' kunnen alleen goedgekeurde gebruikers pagina's bekijken en bewerken.
 
-Meer complexe instellingen voor gebruikersrechten zijn te maken na de installatie; hierover is meer te lezen in de [//www.mediawiki.org/wiki/Manual:User_rights handleiding].", # Fuzzy
+Meer complexe instellingen voor gebruikersrechten zijn te maken na de installatie; hierover is meer te lezen in de [//www.mediawiki.org/wiki/Manual:User_rights handleiding].",
        'config-license' => 'Auteursrechten en licentie:',
        'config-license-none' => 'Geen licentie in de voettekst',
        'config-license-cc-by-sa' => 'Creative Commons Naamsvermelding-Gelijk delen',
@@ -14225,7 +14342,7 @@ Mogelijk moet u aanvullende instellingen maken, maar u kunt deze uitbreidingen n
        'config-install-alreadydone' => "'''Waarschuwing:''' het lijkt alsof u MediaWiki al hebt geïnstalleerd en probeert het programma opnieuw te installeren.
 Ga alstublieft door naar de volgende pagina.",
        'config-install-begin' => 'Als u nu op "{{int:config-continue}}" klikt, begint de installatie van MediaWiki.
-Als u nog wijzigingen wilt maken, klik dan op "Terug".', # Fuzzy
+Als u nog wijzigingen wilt maken, klik dan op "{{int:config-back}}".',
        'config-install-step-done' => 'afgerond',
        'config-install-step-failed' => 'mislukt',
        'config-install-extensions' => 'Inclusief uitbreidingen',
@@ -14282,7 +14399,7 @@ $3
 '''Let op''': als u dit niet nu doet, dan het is bestand als u later de installatieprocedure afsluit zonder het bestand te downloaden niet meer beschikbaar.
 
 Na het plaatsen van het bestand met instellingen kunt u '''[$2 uw wiki betreden]'''.",
-       'config-download-localsettings' => 'LocalSettings.php downloaden',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> downloaden',
        'config-help' => 'hulp',
        'config-nofile' => 'Het bestand "$1" is niet gevonden. Is het verwijderd?',
        'mainpagetext' => "'''De installatie van MediaWiki is geslaagd.'''",
@@ -14302,7 +14419,7 @@ Na het plaatsen van het bestand met instellingen kunt u '''[$2 uw wiki betreden]
 $messages['nl-informal'] = array(
        'config-localsettings-badkey' => 'De sleutel die je hebt opgegeven is onjuist',
        'config-upgrade-key-missing' => 'Er is een bestaande installatie van MediaWiki aangetroffen.
-Plaats de volgende regel onderaan je LocalSettings.php om deze installatie bij te werken:
+Plaats de volgende regel onderaan je <code>LocalSettings.php</code> om deze installatie bij te werken:
 
 $1',
        'config-session-expired' => 'Je sessiegegevens zijn verlopen.
@@ -14475,7 +14592,7 @@ Een wiki met '''{{int:config-profile-no-anon}}\" biedt extra verantwoordelijkhei
 Het scenario '''{{int:config-profile-fishbowl}}''' laat gebruikers waarvoor dat is ingesteld bewerkt, maar andere gebruikers kunnen alleen pagina's bekijken, inclusief de bewerkingsgeschiedenis.
 In een '''{{int:config-profile-private}}''' kunnen alleen goedgekeurde gebruikers pagina's bekijken en bewerken.
 
-Meer complexe instellingen voor gebruikersrechten zijn te maken na de installatie; hierover is meer te lezen in de [//www.mediawiki.org/wiki/Manual:User_rights handleiding].",
+Meer complexe instellingen voor gebruikersrechten zijn te maken na de installatie; hierover is meer te lezen in de [//www.mediawiki.org/wiki/Manual:User_rights handleiding].", # Fuzzy
        'config-license-help' => "In veel openbare wiki's zijn alle bijdragen beschikbaar onder een [http://freedomdefined.org/Definition vrije licentie].
 Dit helpt bij het creëren van een gevoel van gemeenschappelijk eigendom en stimuleert bijdragen op lange termijn.
 Dit is over het algemeen niet nodig is voor een particuliere of zakelijke wiki.
@@ -14507,7 +14624,7 @@ Mogelijk moet je aanvullende instellingen maken, maar je kunt deze uitbreidingen
        'config-install-alreadydone' => "'''Waarschuwing:''' het lijkt alsof je MediaWiki al hebt geïnstalleerd en probeert het programma opnieuw te installeren.
 Ga alsjeblieft door naar de volgende pagina.",
        'config-install-begin' => 'Als je nu op "{{int:config-continue}}" klikt, begint de installatie van MediaWiki.
-Als je nog wijzigingen wilt maken, klik dan op "Terug".',
+Als je nog wijzigingen wilt maken, klik dan op "Terug".', # Fuzzy
        'config-pg-no-plpgsql' => 'Je moet de taal PL/pgSQL installeren in de database $1',
        'config-pg-no-create-privs' => 'De gebruiker die je hebt opgegeven door de installatie heeft niet voldoende rechten om een gebruiker aan te maken.',
        'config-pg-not-in-role' => 'De gebruiker die je hebt opgegeven voor de webgebruiker bestaat al.
@@ -14679,6 +14796,7 @@ $messages['pdc'] = array(
  * @author Saper
  * @author Sp5uhe
  * @author Woytecr
+ * @author 아라
  */
 $messages['pl'] = array(
        'config-desc' => 'Instalator MediaWiki',
@@ -14686,19 +14804,19 @@ $messages['pl'] = array(
        'config-information' => 'Informacja',
        'config-localsettings-upgrade' => 'Plik <code>LocalSettings.php</code> istnieje.
 Aby oprogramowanie zostało zaktualizowane musisz wstawić wartość <code>$wgUpgradeKey</code> w poniższe pole.
-Odnajdziesz ją w LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Wykryto obecność pliku LocalSettings.php.
-Aktualizację należy wykonać poprzez uruchomienie update.php',
+Odnajdziesz ją w <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Wykryto obecność pliku <code>LocalSettings.php</code>.
+Aktualizację należy wykonać poprzez uruchomienie <code>update.php</code>',
        'config-localsettings-key' => 'Klucz aktualizacji',
        'config-localsettings-badkey' => 'Podany klucz jest nieprawidłowy',
        'config-upgrade-key-missing' => 'Wykryto zainstalowane wcześniej MediaWiki.
-Jeśli chcesz je zaktualizować dodaj na koniec pliku LocalSettings.php poniższą linię tekstu.
+Jeśli chcesz je zaktualizować dodaj na koniec pliku <code>LocalSettings.php</code> poniższą linię tekstu.
 
 $1',
-       'config-localsettings-incomplete' => 'Istniejący plik LocalSettings.php wygląda na niekompletny.
+       'config-localsettings-incomplete' => 'Istniejący plik <code>LocalSettings.php</code> wygląda na niekompletny.
 Brak wartości zmiennej $1.
-Zmień plik LocalSettings.php, tak by zawierał deklarację wartości tej zmiennej, a następnie kliknij „Dalej”.',
-       'config-localsettings-connection-error' => 'Wystąpił błąd podczas łączenia z bazą danych z wykorzystaniem danych z LocalSettings.php lub AdminSettings.php.
+Zmień plik <code>LocalSettings.php</code>, tak by zawierał deklarację wartości tej zmiennej, a następnie kliknij „{{int:Config-continue}}”.',
+       'config-localsettings-connection-error' => 'Wystąpił błąd podczas łączenia z bazą danych z wykorzystaniem danych z <code>LocalSettings.php</code> lub <code>AdminSettings.php</code>.
 Popraw ustawienia i spróbuj ponownie.
 
 $1',
@@ -14829,7 +14947,7 @@ Instalacja została przerwana.',
        'config-using531' => 'MediaWiki nie może być używane z PHP $1 z powodu błędu dotyczącego referencyjnych argumentów funkcji <code>__call()</code>.
 Uaktualnij do PHP 5.3.2 lub nowszego. Możesz również cofnąć wersję do PHP 5.3.0, aby naprawić ten błąd.
 Instalacja została przerwana.',
-       'config-suhosin-max-value-length' => 'Jest zainstalowany Suhosin i ogranicza długość parametru GET do $1  bajtów. Komponent ResourceLoader w MediaWiki  wykona obejście tego ograniczenia, ale kosztem wydajności. Jeśli to możliwe należy ustawić suhosin.get.max_value_length na 1024 lub wyższej w php.ini oraz ustawić $wgResourceLoaderMaxQueryLength w LocalSettings.php na tę samą wartość.',
+       'config-suhosin-max-value-length' => 'Jest zainstalowany Suhosin i ogranicza długość parametru GET do $1  bajtów. Komponent ResourceLoader w MediaWiki  wykona obejście tego ograniczenia, ale kosztem wydajności. Jeśli to możliwe należy ustawić <code>suhosin.get.max_value_length</code> na 1024 lub wyższej w <code>php.ini</code> oraz ustawić <code>$wgResourceLoaderMaxQueryLength</code> w LocalSettings.php na tę samą wartość.', # Fuzzy
        'config-db-type' => 'Typ bazy danych',
        'config-db-host' => 'Adres serwera bazy danych',
        'config-db-host-help' => 'Jeśli serwer bazy danych jest na innej maszynie, wprowadź jej nazwę domenową lub adres IP.
@@ -14911,7 +15029,7 @@ Poniżej wyświetlone są systemy baz danych gotowe do użycia. Jeżeli poniżej
        'config-support-postgres' => '* $1 jest popularnym systemem baz danych, często stosowanym zamiast MySQL  ([http://www.php.net/manual/en/pgsql.installation.php Zobacz, jak skompilować PHP ze wsparciem dla PostgreSQL]). Z powodu możliwości wystąpienia drobnych błędów, nie jest zalecana do wymagających wdrożeń.',
        'config-support-sqlite' => '* $1 jest niewielkim systemem bazy danych, z którym MediaWiki bardzo dobrze współpracuje. ([http://www.php.net/manual/en/pdo.installation.php Jak skompilować PHP ze wsparciem dla SQLite], korzystając z PDO)',
        'config-support-oracle' => '* $1 jest komercyjną profesjonalną bazą danych. ([http://www.php.net/manual/en/oci8.installation.php Jak skompilować PHP ze wsparciem dla OCI8])',
-       'config-support-ibm_db2' => '* $1 jest komercyjną zaawansowaną bazą danych.',
+       'config-support-ibm_db2' => '* $1 jest komercyjną zaawansowaną bazą danych.', # Fuzzy
        'config-header-mysql' => 'Ustawienia MySQL',
        'config-header-postgres' => 'Ustawienia PostgreSQL',
        'config-header-sqlite' => 'Ustawienia SQLite',
@@ -14978,8 +15096,8 @@ Jest to '''nie zalecane''', chyba że występują problemy z twoją wiki.",
        'config-upgrade-done-no-regenerate' => 'Aktualizacja zakończona.
 
 Możesz wreszcie [$1 zacząć korzystać ze swojej wiki].',
-       'config-regenerate' => 'Ponowne generowanie LocalSettings.php →',
-       'config-show-table-status' => 'Zapytanie „SHOW TABLE STATUS” nie powiodło się!',
+       'config-regenerate' => 'Ponowne generowanie <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Zapytanie „<code>SHOW TABLE STATUS</code>” nie powiodło się!',
        'config-unknown-collation' => "'''Uwaga''' – bazy danych używa nierozpoznanej metody porównywania.",
        'config-db-web-account' => 'Konto bazy danych dla dostępu przez WWW',
        'config-db-web-help' => 'Wybierz nazwę użytkownika i hasło, z których korzystać będzie serwer WWW do łączenia się z serwerem baz danych, podczas zwykłej pracy z wiki.',
@@ -15051,7 +15169,7 @@ Możesz pominąć pozostałe czynności konfiguracyjne i zainstalować wiki.',
        'config-optional-continue' => 'Zadaj mi więcej pytań.',
        'config-optional-skip' => 'Jestem już znudzony, po prostu zainstaluj wiki.',
        'config-profile' => 'Profil uprawnień użytkowników',
-       'config-profile-wiki' => 'Tradycyjne wiki',
+       'config-profile-wiki' => 'Tradycyjne wiki', # Fuzzy
        'config-profile-no-anon' => 'Wymagane utworzenie konta',
        'config-profile-fishbowl' => 'Wyłącznie zatwierdzeni edytorzy',
        'config-profile-private' => 'Prywatna wiki',
@@ -15066,7 +15184,7 @@ Wiki z '''{{int:config-profile-no-anon}}''' zawiera dodatkowe funkcje rozliczani
 Scenariusz '''{{int:config-profile-fishbowl}}''' umożliwia zatwierdzonym użytkownikom edycję, ale wyświetlanie stron jest powszechnie dostępne, włącznie z historią.
 Ustawienie '''{{int:config-profile-private}}'' ' pozwala na wyświetlanie stron tylko zatwierdzonym użytkownikom, ta sama grupa może edytować.
 
-Bardziej skomplikowane konfiguracje uprawnień użytkowników są dostępne po zakończeniu instalacji, zobacz [//www.mediawiki.org/wiki/Manual:User_rights odpowiednią część podręcznika].",
+Bardziej skomplikowane konfiguracje uprawnień użytkowników są dostępne po zakończeniu instalacji, zobacz [//www.mediawiki.org/wiki/Manual:User_rights odpowiednią część podręcznika].", # Fuzzy
        'config-license' => 'Prawa autorskie i licencja',
        'config-license-none' => 'Brak stopki z licencją',
        'config-license-cc-by-sa' => 'Creative Commons – za uznaniem autora, na tych samych zasadach',
@@ -15151,7 +15269,7 @@ Mogą one wymagać dodatkowych czynności konfiguracyjnych, ale można je teraz
        'config-install-alreadydone' => "'''Uwaga''' – wydaje się, że MediaWiki jest już zainstalowane, a obecnie próbujesz zainstalować je ponownie.
 Przejdź do następnej strony.",
        'config-install-begin' => 'Po naciśnięciu "{{int:config-continue}}", rozpocznie się instalacji MediaWiki.
-Jeśli nadal chcesz dokonać zmian, naciśnij wstecz.',
+Jeśli nadal chcesz dokonać zmian, naciśnij wstecz.', # Fuzzy
        'config-install-step-done' => 'gotowe',
        'config-install-step-failed' => 'nieudane',
        'config-install-extensions' => 'Włącznie z rozszerzeniami',
@@ -15206,7 +15324,7 @@ $3
 '''Uwaga''': Jeśli tego nie zrobisz tego teraz, wygenerowany plik konfiguracyjny nie będzie już dostępny po zakończeniu instalacji.
 
 Po załadowaniu pliku konfiguracyjnego możesz '''[ $2  wejść na wiki]'''.",
-       'config-download-localsettings' => 'Pobierz LocalSettings.php',
+       'config-download-localsettings' => 'Pobierz <code>LocalSettings.php</code>',
        'config-help' => 'pomoc',
        'config-nofile' => 'Nie udało się odnaleźć pliku "$1". Czy nie został usunięty?',
        'mainpagetext' => "'''Instalacja MediaWiki powiodła się.'''",
@@ -15215,13 +15333,14 @@ Po załadowaniu pliku konfiguracyjnego możesz '''[ $2  wejść na wiki]'''.",
 == Na początek ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Lista ustawień konfiguracyjnych]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki]', # Fuzzy
 );
 
 /** Piedmontese (Piemontèis)
  * @author Borichèt
  * @author Dragonòt
  * @author Krinkle
+ * @author 아라
  */
 $messages['pms'] = array(
        'config-desc' => "L'instalador për mediaWiki",
@@ -15230,18 +15349,18 @@ $messages['pms'] = array(
        'config-localsettings-upgrade' => "A l'é stàit trovà n'archivi <code>LocalSettings.php</code>.
 Për agiorné cost'anstalassion, ch'a anserissa ël valor ëd <code>\$wgUpgradeKey</code> ant la casela sì-sota.
 A la trovrà an LocalSetting.php.",
-       'config-localsettings-cli-upgrade' => "N'archivi LocalSettings.php a l'é stàit trovà.
-Për agiorné sta instalassion, për piasì fà anvece giré update.php",
+       'config-localsettings-cli-upgrade' => "N'archivi <code>LocalSettings.php</code> a l'é stàit trovà.
+Për agiorné sta instalassion, për piasì fà anvece giré <code>update.php</code>",
        'config-localsettings-key' => "Ciav d'agiornament:",
        'config-localsettings-badkey' => "La ciav ch'it l'has dàit a l'é pa giusta.",
        'config-upgrade-key-missing' => "A l'é stàita trovà n'istalassion esistenta ëd MediaWiki. 
-Për agiorné soa istalassion, për piasì ch'a buta la linia sì-sota al fond ëd sò LocalSettings.php:
+Për agiorné soa istalassion, për piasì ch'a buta la linia sì-sota al fond ëd sò <code>LocalSettings.php</code>:
 
 $1",
-       'config-localsettings-incomplete' => "L'esistent LocalSettings.php a smija esse ancomplet.
+       'config-localsettings-incomplete' => "L'esistent <code>LocalSettings.php</code> a smija esse ancomplet.
 La variàbil $1 a l'é nen ampostà.
-Për piasì, ch'a modìfica LocalSettings.php ëd fasson che costa variàbil a sia ampostà, e ch'a sgnaca «Anans».",
-       'config-localsettings-connection-error' => "A l'é ancapitaje n'eror an colegand-se a la base ëd dàit an dovrand j'ampostassion specificà an LocalSettings.php o AdminSettings.php. Për piasì, ch'a coregia cost'ampostassion e ch'a preuva torna.
+Për piasì, ch'a modìfica <code>LocalSettings.php</code> ëd fasson che costa variàbil a sia ampostà, e ch'a sgnaca «{{int:Config-continue}}».",
+       'config-localsettings-connection-error' => "A l'é ancapitaje n'eror an colegand-se a la base ëd dàit an dovrand j'ampostassion specificà an <code>LocalSettings.php</code> o <code>AdminSettings.php</code>. Për piasì, ch'a coregia cost'ampostassion e ch'a preuva torna.
 
 $1",
        'config-session-error' => 'Eror an fasend parte la session: $1',
@@ -15373,7 +15492,7 @@ Istalassion abortìa.",
        'config-using531' => "MediaWiki a peul pa esse dovrà con PHP $1 a motiv d'un bigat ch'a ìmplica ij paràmetr d'arferiment a <code>__call()</code>.
 Ch'a agiorna a PHP 5.3.2 o pi neuv, o ch'a torna andré a PHP 5.3.0 për arzòlve ës problema.
 Istalassion abortìa.",
-       'config-suhosin-max-value-length' => 'Suhosin a l\'é instalà e a lìmita la longheur dël paràmetr GET a $1 byte. Ël component ResourceLoader ëd MediaWiki a travajerà an rispetand ës lìmit, ma sòn a degraderà le prestassion. Se possìbil, a dovrìa amposté suhosin.get.max_value_lenght a 1024 o pi àut an php.ini, e amposté $wgResourceLoaderMaxQueryLength al midem valor an LocalSettings.php .',
+       'config-suhosin-max-value-length' => 'Suhosin a l\'é instalà e a lìmita la longheur dël paràmetr GET a $1 byte. Ël component ResourceLoader ëd MediaWiki a travajerà an rispetand ës lìmit, ma sòn a degraderà le prestassion. Se possìbil, a dovrìa amposté suhosin.get.max_value_lenght a 1024 o pi àut an <code>php.ini</code>, e amposté <code>$wgResourceLoaderMaxQueryLength</code> al midem valor an LocalSettings.php .', # Fuzzy
        'config-db-type' => 'Sòrt ëd base ëd dàit:',
        'config-db-host' => 'Ospitant ëd la base ëd dàit:',
        'config-db-host-help' => "Se sò servent ëd base ëd dàit a l'é su un servent diferent, ch'a anserissa ambelessì ël nòm dl'ospitant o l'adrëssa IP.
@@ -15454,7 +15573,7 @@ S'a vëd pa listà sì-sota ël sistema ëd base ëd dàit ch'a preuva a dovré,
        'config-support-postgres' => "* $1 e l'é un sistema ëd base ëd dàit popolar a sorgiss duverta com alternativa a MySQL ([http://www.php.net/manual/en/pgsql.installation.php com compilé PHP con ël manteniment ëd PostgreSQL]). A peulo ess-ie chèich cit bigat, e a l'é nen arcomandà ëd dovrelo an n'ambient ëd produssion.",
        'config-support-sqlite' => "* $1 e l'é un sistema ëd base ëd dàit leger che a l'é motobin bin mantnù ([http://www.php.net/manual/en/pdo.installation.php com compilé PHP con ël manteniment ëd SQLite], a deuvra PDO)",
        'config-support-oracle' => "* $1 a l'é na base ëd dàit comersial për j'amprèise. ([http://www.php.net/manual/en/oci8.installation.php Com compilé PHP con ël manteniment OCI8])",
-       'config-support-ibm_db2' => "* $1 a l'é na base ëd dàit d'asiendal comersial.",
+       'config-support-ibm_db2' => "* $1 a l'é na base ëd dàit d'asiendal comersial.", # Fuzzy
        'config-header-mysql' => 'Ampostassion MySQL',
        'config-header-postgres' => 'Ampostassion PostgreSQL',
        'config-header-sqlite' => 'Ampostassion SQLite',
@@ -15519,8 +15638,8 @@ Sòn a l'è '''pa arcomandà''' gavà ch'a rancontra dij problema con soa wiki."
        'config-upgrade-done-no-regenerate' => 'Agiornament complet.
 
 It peule adess [$1 ancaminé a dovré toa wiki].',
-       'config-regenerate' => 'Generé torna LocalSettings.php →',
-       'config-show-table-status' => 'Arcesta SHOW TABLE STATUS falìa!',
+       'config-regenerate' => 'Generé torna <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Arcesta <code>SHOW TABLE STATUS</code> falìa!',
        'config-unknown-collation' => "'''Avis:''' La base ëd dàit a deuvra na classificassion pa arconossùa.",
        'config-db-web-account' => "Cont dla base ëd dàit për l'acess a l'aragnà",
        'config-db-web-help' => "Ch'a selession-a lë stranòm d'utent e la ciav che ël servent ëd l'aragnà a dovrërà për coleghesse al servent dle base ëd dàit, durant j'operassion ordinarie dla wiki.",
@@ -15748,7 +15867,7 @@ $3
 '''Nòta''': S'a lo fa nen adess, cost archivi ëd configurassion generà a sarà pa disponìbil për chiel pi tard s'a chita l'instalassion sensa dëscarielo.
 
 Quand che a l'é stàit fàit, a peul '''[$2 intré an soa wiki]'''.",
-       'config-download-localsettings' => 'Dëscarié LocalSettings.php',
+       'config-download-localsettings' => 'Dëscarié <code>LocalSettings.php</code>',
        'config-help' => 'agiut',
        'config-nofile' => "L'archivi «$1» as treuva nen. A l'é stàit ëscancelà?",
        'mainpagetext' => "'''MediaWiki a l'é staita anstalà a la përfession.'''",
@@ -15817,7 +15936,7 @@ $messages['ps'] = array(
        'config-admin-password' => 'پټنوم:',
        'config-admin-password-confirm' => 'پټنوم يو ځل بيا:',
        'config-admin-email' => 'برېښليک پته:',
-       'config-profile-wiki' => 'دوديزه ويکي',
+       'config-profile-wiki' => 'دوديزه ويکي', # Fuzzy
        'config-license-pd' => 'ټولګړی شپول',
        'config-email-settings' => 'د برېښليک امستنې',
        'config-install-step-done' => 'ترسره شو',
@@ -15829,7 +15948,8 @@ $messages['ps'] = array(
 == پيلول ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings د امستنو د سازونې لړليک]
 * [//www.mediawiki.org/wiki/Manual:FAQ د ميډياويکي ډېرځليزې پوښتنې]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce د مېډياويکي د برېښليکونو لړليک]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce د مېډياويکي د برېښليکونو لړليک]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources خپلې ژبې لپاره MediaWiki ځايتابول]',
 );
 
 /** Portuguese (português)
@@ -15839,6 +15959,7 @@ $messages['ps'] = array(
  * @author Platonides
  * @author SandroHc
  * @author Waldir
+ * @author 아라
  */
 $messages['pt'] = array(
        'config-desc' => 'O instalador do MediaWiki',
@@ -15846,19 +15967,19 @@ $messages['pt'] = array(
        'config-information' => 'Informação',
        'config-localsettings-upgrade' => 'Foi detectado um ficheiro <code>LocalSettings.php</code>.
 Para actualizar esta instalação, por favor introduza o valor de <code>$wgUpgradeKey</code> na caixa abaixo.
-Encontra este valor no LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Foi detectada a existência de um ficheiro LocalSettings.php.
-Para actualizar esta instalação execute o update.php, por favor.',
+Encontra este valor no <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Foi detectada a existência de um ficheiro <code>LocalSettings.php</code>.
+Para actualizar esta instalação execute o <code>update.php</code>, por favor.',
        'config-localsettings-key' => 'Chave de actualização:',
        'config-localsettings-badkey' => 'A chave que forneceu está incorreta.',
        'config-upgrade-key-missing' => 'Foi detectada uma instalação existente do MediaWiki.
-Para actualizar esta instalação, por favor coloque a seguinte linha no final do seu LocalSettings.php:
+Para actualizar esta instalação, por favor coloque a seguinte linha no final do seu <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'O ficheiro LocalSettings.php existente parece estar incompleto.
+       'config-localsettings-incomplete' => 'O ficheiro <code>LocalSettings.php</code> existente parece estar incompleto.
 A variável $1 não está definida.
-Por favor defina esta variável no LocalSettings.php e clique "Continuar".',
-       'config-localsettings-connection-error' => 'Ocorreu um erro ao ligar à base de dados usando as configurações especificadas no LocalSettings.php ou AdminSettings.php. Por favor corrija essas configurações e tente novamente.
+Por favor defina esta variável no <code>LocalSettings.php</code> e clique "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Ocorreu um erro ao ligar à base de dados usando as configurações especificadas no <code>LocalSettings.php</code> ou <code>AdminSettings.php</code>. Por favor corrija essas configurações e tente novamente.
 
 $1',
        'config-session-error' => 'Erro ao iniciar a sessão: $1',
@@ -15990,7 +16111,7 @@ Instalação interrompida.',
        'config-using531' => 'O MediaWiki não pode ser usado com o PHP $1 devido a um problema que envolve parâmetros de referência para <code>__call()</code>.
 Para resolver este problema, actualize o PHP para a versão 5.3.2 ou posterior, ou reverta-o para a 5.3.0.
 Instalação interrompida.',
-       'config-suhosin-max-value-length' => 'O Suhosin está instalado e limita a $1 bytes o comprimento do parâmetro GET. O componente ResourceLoader do MediaWiki pode tornear este limite, mas prejudicando o desempenho. Se lhe for possível, deve atribuir o valor 1024 ou maior ao parâmetro suhosin.get.max_value_length no ficheiro php.ini, e definir o mesmo valor para $wgResourceLoaderMaxQueryLength no ficheiro LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'O Suhosin está instalado e limita a $1 bytes o comprimento do parâmetro GET. O componente ResourceLoader do MediaWiki pode tornear este limite, mas prejudicando o desempenho. Se lhe for possível, deve atribuir o valor 1024 ou maior ao parâmetro <code>suhosin.get.max_value_length</code> no ficheiro <code>php.ini</code>, e definir o mesmo valor para <code>$wgResourceLoaderMaxQueryLength</code> no ficheiro LocalSettings.php.', # Fuzzy
        'config-db-type' => 'Tipo da base de dados:',
        'config-db-host' => 'Servidor da base de dados:',
        'config-db-host-help' => 'Se a base de dados estiver num servidor separado, introduza aqui o nome ou o endereço IP desse servidor.
@@ -16074,7 +16195,7 @@ Se a plataforma que pretende usar não está listada abaixo, siga as instruçõe
        'config-support-postgres' => '* $1 é uma plataforma de base de dados comum, de fonte aberta, alternativa ao MySQL ([http://www.php.net/manual/en/pgsql.installation.php como compilar PHP com suporte PostgreSQL]). Poderão existir alguns pequenos problemas e não é recomendado o seu uso em ambientes de exploração/produção.',
        'config-support-sqlite' => '* $1 é uma plataforma de base de dados ligeira muito bem suportada. ([http://www.php.net/manual/en/pdo.installation.php Como compilar PHP com suporte SQLite], usa PDO)',
        'config-support-oracle' => '* $1 é uma base de dados de uma empresa comercial. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
-       'config-support-ibm_db2' => '* $1 é uma base de dados empresarial.',
+       'config-support-ibm_db2' => '* $1 é uma base de dados empresarial.', # Fuzzy
        'config-header-mysql' => 'Definições MySQL',
        'config-header-postgres' => 'Definições PostgreSQL',
        'config-header-sqlite' => 'Definições SQLite',
@@ -16141,8 +16262,8 @@ Esta operação '''não é recomendada''' a menos que esteja a ter problemas com
        'config-upgrade-done-no-regenerate' => 'Actualização terminada.
 
 Agora pode [$1 começar a usar a sua wiki].',
-       'config-regenerate' => 'Regenerar o LocalSettings.php →',
-       'config-show-table-status' => 'A consulta SHOW TABLE STATUS falhou!',
+       'config-regenerate' => 'Regenerar o <code>LocalSettings.php</code> →',
+       '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' => 'Seleccione 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.',
@@ -16215,7 +16336,7 @@ Agora pode saltar as configurações restantes 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-profile-wiki' => 'Wiki tradicional',
+       'config-profile-wiki' => 'Wiki tradicional', # Fuzzy
        'config-profile-no-anon' => 'Criação de conta exigida',
        'config-profile-fishbowl' => 'Somente utilizadores autorizados',
        'config-profile-private' => 'Wiki privada',
@@ -16231,7 +16352,7 @@ Uma wiki com '''{{int:config-profile-no-anon}}''' atribui mais responsabilidade,
 Um cenário '''{{int:config-profile-fishbowl}}''' permite que os utilizadores aprovados editem, mas que o público visione as páginas, incluindo o historial das mesmas.
 Uma '''{{int:config-profile-private}}''' só permite que os utilizadores aprovados visionem as páginas e as editem.
 
-Após a instalação, estarão disponíveis mais configurações de privilégios. Consulte [//www.mediawiki.org/wiki/Manual:User_rights a entrada relevante no Manual].",
+Após a instalação, estarão disponíveis mais configurações de privilégios. Consulte [//www.mediawiki.org/wiki/Manual:User_rights a entrada relevante no Manual].", # Fuzzy
        'config-license' => 'Direitos de autor e licença:',
        'config-license-none' => 'Sem rodapé com a licença',
        'config-license-cc-by-sa' => 'Creative Commons - Atribuição - Partilha nos Mesmos Termos',
@@ -16316,7 +16437,7 @@ Estas talvez necessitem de configurações adicionais, mas pode activá-las agor
        'config-install-alreadydone' => "'''Aviso:''' Parece que já instalou o MediaWiki e está a tentar instalá-lo novamente.
 Passe para a próxima página, por favor.",
        'config-install-begin' => 'Ao clicar "{{int:config-continue}}", vai iniciar a instalação do MediaWiki.
-Se quiser fazer mais alterações, clique Voltar.',
+Se quiser fazer mais alterações, clique Voltar.', # Fuzzy
        'config-install-step-done' => 'terminado',
        'config-install-step-failed' => 'falhou',
        'config-install-extensions' => 'A incluir as extensões',
@@ -16372,7 +16493,7 @@ $3
 '''Nota''': Se não fizer isto agora, o ficheiro que foi gerado deixará de estar disponível quando sair do processo de instalação.
 
 Depois de terminar o passo anterior, pode '''[$2 entrar na wiki]'''.",
-       'config-download-localsettings' => 'Download do LocalSettings.php',
+       'config-download-localsettings' => 'Download do <code>LocalSettings.php</code>',
        'config-help' => 'ajuda',
        'config-nofile' => 'Não foi possível encontrar o ficheiro "$1". Terá sido apagado?',
        'mainpagetext' => "'''MediaWiki instalado com sucesso.'''",
@@ -16382,7 +16503,7 @@ Depois de terminar o passo anterior, pode '''[$2 entrar na wiki]'''.",
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Lista de opções de configuração]
 * [//www.mediawiki.org/wiki/Manual:FAQ Perguntas e respostas frequentes sobre o MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Subscreva a lista de divulgação de novas versões do MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Subscreva a lista de divulgação de novas versões do MediaWiki]', # Fuzzy
 );
 
 /** Brazilian Portuguese (português do Brasil)
@@ -16397,13 +16518,13 @@ $messages['pt-br'] = array(
        'config-information' => 'Informações',
        'config-localsettings-upgrade' => 'Foi detectada a existência do arquivo <code>LocalSettings.php</code>.
 Para atualizar esta instalação, insira no box abaixo o valor de <code>$wgUpgradeKey</code>.
-Essa informação pode ser encontrada no arquivo LocalSettings.php',
-       'config-localsettings-cli-upgrade' => 'Foi detectada a existência do arquivo <code>LocalSettings.php</code>.
+Essa informação pode ser encontrada no arquivo <code>LocalSettings.php</code>',
+       'config-localsettings-cli-upgrade' => 'Foi detectada a existência do arquivo <code><code>LocalSettings.php</code></code>.
 Esta instalação deverá ser atualizada através do <code>update.php</code>',
        'config-localsettings-key' => 'Chave de atualização:',
        'config-localsettings-badkey' => 'A chave fornecida está incorreta.',
        'config-upgrade-key-missing' => 'Foi detectada uma instalação existente do MediaWiki.
-Para atualizar esta instalação, por favor, coloque a seguinte linha na parte inferior do seu LocalSettings.php:
+Para atualizar esta instalação, por favor, coloque a seguinte linha na parte inferior do seu <code>LocalSettings.php</code>:
 
 $ 1', # Fuzzy
        'config-session-error' => 'Erro ao iniciar a sessão: $1',
@@ -16477,7 +16598,7 @@ Se você não pretende usar um logotipo, deixe este campo em branco.', # Fuzzy
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Lista de opções de configuração]
 * [//www.mediawiki.org/wiki/Manual:FAQ FAQ do MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de discussão com avisos de novas versões do MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de discussão com avisos de novas versões do MediaWiki]', # Fuzzy
 );
 
 /** Quechua (Runa Simi)
@@ -16580,7 +16701,7 @@ Verificați gazda, numele de utilizator și parola și reîncercați.',
        'config-upgrade-done-no-regenerate' => 'Actualizare completă.
 
 Acum puteți [$1 începe să vă folosiți wikiul].',
-       'config-regenerate' => 'Regenerare LocalSettings.php →',
+       'config-regenerate' => 'Regenerare <code>LocalSettings.php</code> →',
        'config-unknown-collation' => 'AVERTISMENT: Baza de date folosește o colaționare nerecunoscută.',
        'config-db-web-account' => 'Contul bazei de date pentru accesul web.',
        'config-db-web-create' => 'Creați contul dacă nu există deja',
@@ -16611,7 +16732,7 @@ Puteți sări peste configurarea rămasă și să instalați wikiul chiar acum.'
        'config-optional-continue' => 'Adresează-mi mai multe întrebări.',
        'config-optional-skip' => 'Sunt deja plictisit, doar instalează wikiul.',
        'config-profile' => 'Profilul drepturilor de utilizator:',
-       'config-profile-wiki' => 'Wiki tradițional',
+       'config-profile-wiki' => 'Wiki tradițional', # Fuzzy
        'config-profile-no-anon' => 'Crearea de cont este necesară',
        'config-profile-fishbowl' => 'Doar editorii autorizați',
        'config-profile-private' => 'Wiki privat',
@@ -16647,7 +16768,7 @@ Puteți sări peste configurarea rămasă și să instalați wikiul chiar acum.'
        'config-install-keys' => 'Se generează cheile secrete',
        'config-install-sysop' => 'Se creează contul de administrator',
        'config-install-mainpage-failed' => 'Nu s-a putut insera pagina principală: $1',
-       'config-download-localsettings' => 'Descarcă LocalSettings.php',
+       'config-download-localsettings' => 'Descarcă <code>LocalSettings.php</code>',
        'config-help' => 'ajutor',
        'mainpagetext' => "'''Programul Wiki a fost instalat cu succes.'''",
        'mainpagedocfooter' => 'Consultați [//meta.wikimedia.org/wiki/Help:Contents Ghidul utilizatorului (en)] pentru informații despre utilizarea software-ului wiki.
@@ -16678,6 +16799,7 @@ $messages['roa-tara'] = array(
        'config-type-postgres' => 'PostgreSQL',
        'config-type-sqlite' => 'SQLite',
        'config-type-oracle' => 'Oracle',
+       'config-admin-email' => 'Indirizze e-mail:',
        'config-install-step-done' => 'fatte',
        'config-install-step-failed' => 'fallite',
        'config-install-extensions' => "'Ngludenne le estenziune",
@@ -16707,6 +16829,7 @@ $messages['roa-tara'] = array(
  * @author Yuriy Apostol
  * @author Александр Сигачёв
  * @author Сrower
+ * @author 아라
  */
 $messages['ru'] = array(
        'config-desc' => 'Инсталлятор MediaWiki',
@@ -16714,19 +16837,19 @@ $messages['ru'] = array(
        'config-information' => 'Информация',
        'config-localsettings-upgrade' => 'Обнаружен файл <code>LocalSettings.php</code>.
 Для обновления этой установки, пожалуйста, введите значение <code>$wgUpgradeKey</code>.
-Его можно найти в файле LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Обнаружен файл LocalSettings.php.
-Для обновления этой установки, пожалуйста, запустите update.php',
+Его можно найти в файле <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Обнаружен файл <code>LocalSettings.php</code>.
+Для обновления этой установки, пожалуйста, запустите <code>update.php</code>',
        'config-localsettings-key' => 'Ключ обновления:',
        'config-localsettings-badkey' => 'Вы указали неправильный ключ',
        'config-upgrade-key-missing' => 'Обнаружена существующая установленная копия MediaWiki.
-Чтобы обновить обнаруженную установку, пожалуйста, добавьте следующую строку в конец вашего файла LocalSettings.php:
+Чтобы обновить обнаруженную установку, пожалуйста, добавьте следующую строку в конец вашего файла <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Похоже, что существующий файл LocalSettings.php не является полными.
+       'config-localsettings-incomplete' => 'Похоже, что существующий файл <code>LocalSettings.php</code> не является полными.
 Не установлена переменная $1.
-Пожалуйста, измените LocalSettings.php так, чтобы значение этой переменной было задано, затем нажмите «Продолжить».',
-       'config-localsettings-connection-error' => 'Произошла ошибка при подключении к базе данных с помощью настроек, указанных в LocalSettings.php или AdminSettings.php. Пожалуйста, исправьте эти настройки и повторите попытку.
+Пожалуйста, измените <code>LocalSettings.php</code> так, чтобы значение этой переменной было задано, затем нажмите «{{int:Config-continue}}».',
+       'config-localsettings-connection-error' => 'Произошла ошибка при подключении к базе данных с помощью настроек, указанных в <code>LocalSettings.php</code> или <code>AdminSettings.php</code>. Пожалуйста, исправьте эти настройки и повторите попытку.
 
 $1',
        'config-session-error' => 'Ошибка при запуске сессии: $1',
@@ -16857,7 +16980,7 @@ MediaWiki требует поддержки UTF-8 для корректной р
        'config-using531' => 'PHP $1 не совместим с MediaWiki из-за ошибки с параметрами-ссылками при вызовах <code>__call()</code>.
 Обновитесь до PHP 5.3.2 и выше, или откатитесь до PHP 5.3.0, чтобы избежать этой проблемы.
 Установка прервана.',
-       'config-suhosin-max-value-length' => 'Suhosin установлен и ограничивает длину параметра GET до $1 байт. Компонент MediaWiki ResourceLoader будет обходить это ограничение, но это снизит производительность. Если это возможно, следует установить suhosin.get.max_value_length 1024 или выше в php.ini, а также установить для $wgResourceLoaderMaxQueryLength такое же значение в LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'Suhosin установлен и ограничивает длину параметра GET до $1 байт. Компонент MediaWiki ResourceLoader будет обходить это ограничение, но это снизит производительность. Если это возможно, следует установить <code>suhosin.get.max_value_length</code> 1024 или выше в <code>php.ini</code>, а также установить для <code>$wgResourceLoaderMaxQueryLength</code> такое же значение в LocalSettings.php.', # Fuzzy
        'config-db-type' => 'Тип базы данных:',
        'config-db-host' => 'Хост базы данных:',
        'config-db-host-help' => 'Если сервер базы данных находится на другом сервере, введите здесь его имя хоста или IP-адрес.
@@ -16943,7 +17066,7 @@ $1
        'config-support-postgres' => '* $1 — популярная открытая СУБД, альтернатива MySQL ([http://www.php.net/manual/en/pgsql.installation.php инструкция, как собрать PHP с поддержкой PostgreSQL]). Могут встречаться небольшие неисправленные ошибки, не рекомендуется для использования в рабочей системе.',
        'config-support-sqlite' => '* $1 — это легковесная система баз данных, имеющая очень хорошую поддержку. ([http://www.php.net/manual/en/pdo.installation.php инструкция, как собрать PHP с поддержкой SQLite], работающей посредством PDO)',
        'config-support-oracle' => '* $1 — это коммерческая база данных масштаба предприятия. ([http://www.php.net/manual/en/oci8.installation.php Как собрать PHP с поддержкой OCI8])',
-       'config-support-ibm_db2' => '$1 — коммерческая база данных масштаба предприятия.',
+       'config-support-ibm_db2' => '$1 — коммерческая база данных масштаба предприятия.', # Fuzzy
        'config-header-mysql' => 'Настройки MySQL',
        'config-header-postgres' => 'Настройки PostgreSQL',
        'config-header-sqlite' => 'Настройки SQLite',
@@ -17010,8 +17133,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => 'Обновление завершено.
 
 Теперь вы можете [$1 начать работу с вики].',
-       'config-regenerate' => 'Создать LocalSettings.php заново →',
-       'config-show-table-status' => 'Запрос «SHOW TABLE STATUS» не выполнен!',
+       'config-regenerate' => 'Создать <code>LocalSettings.php</code> заново →',
+       'config-show-table-status' => 'Запрос «<code>SHOW TABLE STATUS</code>» не выполнен!',
        'config-unknown-collation' => "'''Внимание:''' База данных использует нераспознанные правила сортировки.",
        'config-db-web-account' => 'Учётная запись для доступа к базе данных из веб-сервера',
        'config-db-web-help' => 'Выберите имя пользователя и пароль, которые веб-сервер будет использовать для подключения к серверу базы данных при обычной работе вики.',
@@ -17082,7 +17205,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => 'Произвести тонкую настройку',
        'config-optional-skip' => 'Хватит, установить вики',
        'config-profile' => 'Профиль прав прользователей:',
-       'config-profile-wiki' => 'ТÑ\80адиÑ\86ионная вики',
+       'config-profile-wiki' => 'Ð\9eÑ\82кÑ\80Ñ\8bÑ\82ая вики',
        'config-profile-no-anon' => 'Требуется создание учётной записи',
        'config-profile-fishbowl' => 'Только для авторизованных редакторов',
        'config-profile-private' => 'Закрытая вики',
@@ -17092,7 +17215,7 @@ chmod a+w $3</pre>',
 Однако, движок MediaWiki можно использовать и иными способами, и не далеко не всех удаётся убедить в преимуществах открытой вики-работы.
 Так что в вас есть выбор.
 
\9aонÑ\84игÑ\83Ñ\80аÑ\86иÑ\8f '''«{{int:config-profile-wiki}}»''' позволяет всем править страницы даже не регистрируясь на сайте. Конфигурация '''{{int:config-profile-no-anon}}''' обеспечивает дополнительный учёт, но может отсечь случайных участников.
\9cоделÑ\8c '''«{{int:config-profile-wiki}}»''' позволяет всем править страницы даже не регистрируясь на сайте. Конфигурация '''{{int:config-profile-no-anon}}''' обеспечивает дополнительный учёт, но может отсечь случайных участников.
 
 Сценарий '''«{{int:config-profile-fishbowl}}»''' разрешает редактирование только определённым участникам, но общедоступным остаётся просмотр страниц, в том числе просмотр истории изменения. В режиме '''«{{int:config-profile-private}}»''' просмотр страниц разрешён только определённым пользователям, какая-то их часть может иметь также права на редактирование.
 
@@ -17180,7 +17303,7 @@ GFDL может быть использована, но она сложна дл
        'config-install-alreadydone' => "'''Предупреждение:''' Вы, кажется, уже устанавливали MediaWiki и пытаетесь произвести повторную установку.
 Пожалуйста, перейдите на следующую страницу.",
        'config-install-begin' => 'Нажав «{{int:config-continue}}», вы начнёте установку MediaWiki.
-Если вы хотите внести изменения, нажмите «Назад».',
+Если вы хотите внести изменения, нажмите «{{int:config-back}}».',
        'config-install-step-done' => 'выполнено',
        'config-install-step-failed' => 'не удалось',
        'config-install-extensions' => 'В том числе расширения',
@@ -17236,7 +17359,7 @@ $3
 '''Примечание''': Если вы не сделаете этого сейчас, то сгенерированный файл конфигурации не будет доступен вам в дальнейшем, если вы выйдете из установки, не скачивая его.
 
 По окончании действий, описанных выше, вы сможете '''[$2 войти в вашу вики]'''.",
-       'config-download-localsettings' => 'Загрузить LocalSettings.php',
+       'config-download-localsettings' => 'Загрузить <code>LocalSettings.php</code>',
        'config-help' => 'справка',
        'config-nofile' => 'Файл "$1" не удается найти. Он был удален?',
        'mainpagetext' => "'''Вики-движок «MediaWiki» успешно установлен.'''",
@@ -17422,7 +17545,7 @@ $messages['si'] = array(
        'config-missing-db-name' => '"දත්ත සංචිත නාමය" සඳහා ඔබ විසින් අගයක් දිය යුතු වේ',
        'config-missing-db-host' => '"දත්ත සංචිත ධාරකය" සඳහා ඔබ විසින් අගයක් දිය යුතු වේ',
        'config-missing-db-server-oracle' => '"දත්ත සංචිත TNS" සඳහා ඔබ විසින් අගයක් දිය යුතු වේ',
-       'config-regenerate' => 'නැවත ජනිත කරන්න LocalSettings.php →',
+       'config-regenerate' => 'නැවත ජනිත කරන්න <code>LocalSettings.php</code> →',
        'config-db-web-account' => 'ජාල ප්‍රවේශනය සඳහා දත්ත සංචිත ගිණුම',
        'config-mysql-engine' => 'ආචයන එන්ජිම:',
        'config-mysql-innodb' => 'InnoDB',
@@ -17449,7 +17572,7 @@ $messages['si'] = array(
        'config-optional-continue' => 'මගෙන් තව ප්‍රශ්ණ අහන්න.',
        'config-optional-skip' => 'මම දැනටමත් කම්මැලි වී ඇත, විකිය ස්ථාපනය කරන්න.',
        'config-profile' => 'පරිශීලක හිමිකම් පැතිකඩ:',
-       'config-profile-wiki' => 'සාම්ප්‍රදායික විකිය',
+       'config-profile-wiki' => 'සාම්ප්‍රදායික විකිය', # Fuzzy
        'config-profile-no-anon' => 'ගිණුම් තැනීම අවශ්‍යයි',
        'config-profile-fishbowl' => 'අවසරලත් සංස්කාරකවරුන් පමණි',
        'config-profile-private' => 'පුද්ගලික විකිය',
@@ -17496,7 +17619,7 @@ $messages['si'] = array(
        'config-install-sysop' => 'පරිපාලක පරිශීලක ගිණුම තනමින්',
        'config-install-mainpage' => 'සාමාන්‍ය අන්තර්ගතය සමඟින් ප්‍රධාන පිටුව තනමින්',
        'config-install-mainpage-failed' => 'ප්‍රධාන පිටුව ඇතුල් කල නොහැක: $1',
-       'config-download-localsettings' => 'LocalSettings.php බාගන්න',
+       'config-download-localsettings' => '<code>LocalSettings.php</code> බාගන්න',
        'config-help' => 'උදව්',
        'config-nofile' => '"$1" ගොනුව සොයාගත නොහැක. එක මැකිලා ගියාවත්ද?',
        'mainpagetext' => "'''මීඩියාවිකි සාර්ථක ලෙස ස්ථාපනය කරන ලදි.'''",
@@ -17517,7 +17640,7 @@ $messages['sk'] = array(
        'config-back' => '← Späť',
        'config-continue' => 'Pokračovať →',
        'config-page-language' => 'Jazyk',
-       'config-download-localsettings' => 'Stiahnuť LocalSettings.php',
+       'config-download-localsettings' => 'Stiahnuť <code>LocalSettings.php</code>',
        'config-nofile' => 'Súbor "$1" sa nenašiel. Bol zmazaný?',
        'mainpagetext' => "'''Softvér MediaWiki bol úspešne nainštalovaný.'''",
        'mainpagedocfooter' => 'Informácie ako používať wiki softvér nájdete v [//meta.wikimedia.org/wiki/Help:Contents Používateľskej príručke].
@@ -17526,7 +17649,7 @@ $messages['sk'] = array(
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Zoznam konfiguračných nastavení]
 * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce mailing list nových verzií MediaWiki]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce mailing list nových verzií MediaWiki]', # Fuzzy
 );
 
 /** Slovenian (slovenščina)
@@ -17537,12 +17660,12 @@ $messages['sl'] = array(
        'config-desc' => 'Namestitveni program za MediaWiki',
        'config-title' => 'Namestitev MediaWiki $1',
        'config-information' => 'Informacije',
-       'config-localsettings-cli-upgrade' => 'Zaznana je bila datoteka LocalSettings.php.
-Za nadgradnjo te namestitve zaženite update.php',
+       'config-localsettings-cli-upgrade' => 'Zaznana je bila datoteka <code>LocalSettings.php</code>.
+Za nadgradnjo te namestitve zaženite <code>update.php</code>',
        'config-localsettings-key' => 'Nadgraditveni ključ:',
        'config-localsettings-badkey' => 'Naveden ključ je napačen.',
        'config-upgrade-key-missing' => 'Zaznana je bila obstoječa namestitev MediaWiki.
-Za nadgradnjo te namestitve vstavite naslednjo vrstico na dno vaše LocalSettings.php:
+Za nadgradnjo te namestitve vstavite naslednjo vrstico na dno vaše <code>LocalSettings.php</code>:
 
 $1',
        'config-session-error' => 'Napaka pri začenjanju seje: $1',
@@ -17653,8 +17776,8 @@ Preverite mapo podatkov in ime zbirke podatkov spodaj ter poskusite znova.',
        'config-upgrade-done-no-regenerate' => 'Nadgradnja je končana.
 
 Sedaj lahko [$1 začnete uporabljati vaš wiki].',
-       'config-regenerate' => 'Ponovno ustvari LocalSettings.php →',
-       'config-show-table-status' => 'Poizvedba SHOW TABLE STATUS ni uspela!',
+       'config-regenerate' => 'Ponovno ustvari <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Poizvedba <code>SHOW TABLE STATUS</code> ni uspela!',
        'config-unknown-collation' => "'''Opozorilo:''' Zbirke podatkov uporablja neprepoznano razvrščanje znakov.",
        'config-db-web-account' => 'Račun zbirke podatkov za spletni dostop',
        'config-db-web-account-same' => 'Uporabi enak račun kot za namestitev',
@@ -17699,7 +17822,7 @@ Sedaj lahko preskočite preostalo konfiguriranje in zdaj namestite wiki.',
        'config-optional-continue' => 'Zastavi mi več vprašanj.',
        'config-optional-skip' => 'Se že dolgočasim; samo namesti wiki.',
        'config-profile' => 'Profil uporabniških pravic:',
-       'config-profile-wiki' => 'Klasičen wiki',
+       'config-profile-wiki' => 'Odprti wiki',
        'config-profile-no-anon' => 'Zahtevano je ustvarjanje računa',
        'config-profile-fishbowl' => 'Samo pooblaščeni urejevalci',
        'config-profile-private' => 'Zasebni wiki',
@@ -17738,11 +17861,11 @@ Vnesite ime dovoljenja ročno.',
        'config-install-pg-schema-not-exist' => 'Shema PostgreSQL ne obstaja.',
        'config-install-user-alreadyexists' => 'Uporabnik »$1« že obstaja',
        'config-install-tables' => 'Ustvarjanje tabel',
-       'config-download-localsettings' => 'Prenesi LocalSettings.php',
+       'config-download-localsettings' => 'Prenesi <code>LocalSettings.php</code>',
        'config-help' => 'pomoč',
        'mainpagetext' => "'''Programje MediaWiki je bilo uspešno nameščeno.'''",
        'mainpagedocfooter' => 'Za uporabo in pomoč pri nastavitvi, prosimo, preglejte [//meta.wikimedia.org/wiki/MediaWiki_localisation dokumentacijo za prilagajanje vmesnika]
-in [//meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Uporabniški priročnik].',
+in [//meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide Uporabniški priročnik].', # Fuzzy
 );
 
 /** Lower Silesian (Schläsch)
@@ -18082,7 +18205,7 @@ $3
 '''OBS''': Om du inte gör detta nu, kommer denna genererade konfigurationsfil inte vara tillgänglig för dig senare om du avslutar installationen utan att ladda ned den.
 
 När det är klart, kan du '''[$2 gå in på din wiki]'''.",
-       'config-download-localsettings' => 'Ladda ned LocalSettings.php',
+       'config-download-localsettings' => 'Ladda ned <code>LocalSettings.php</code>',
        'config-help' => 'hjälp',
        'config-nofile' => 'Filen "$1" kunde inte hittas. Har den tagits bort?',
        'mainpagetext' => "'''MediaWiki har installerats utan problem.'''",
@@ -18192,7 +18315,7 @@ $messages['ta'] = array(
        'config-optional-continue' => 'என்னை இன்னும் அதிகமாக வினவு.',
        'config-optional-skip' => 'நான் ஏற்கனவே சோர்வடைந்துள்ளேன், விக்கியை மட்டும் உருவாக்கு.',
        'config-profile' => 'பயனர் உரிமைகள் சுயவிவரம்:',
-       'config-profile-wiki' => 'பாரம்பரிய விக்கி',
+       'config-profile-wiki' => 'பாரம்பரிய விக்கி', # Fuzzy
        'config-profile-no-anon' => 'கணக்கு உருவாக்குதல் அவசியம்',
        'config-profile-private' => 'தனியார் விக்கி',
        'config-license' => 'பதிப்புரிமை மற்றும் உரிமம்:',
@@ -18213,7 +18336,7 @@ $messages['ta'] = array(
        'config-install-tables' => 'வரிசைப் பட்டியல்களை உருவாக்குகிறது',
        'config-install-mainpage' => 'இயல்புநிலை உள்ளடக்கத்துடன் முதற்பக்கத்தை உருவாக்குகிறது',
        'config-install-extension-tables' => 'செயற்படுத்தப்பட்ட நீட்சிகளுக்கு வரிசைப் பட்டியல்களை உருவாக்குகிறது',
-       'config-download-localsettings' => 'LocalSettings.phpஐத் தரவிறக்கவும்',
+       'config-download-localsettings' => '<code>LocalSettings.php</code>ஐத் தரவிறக்கவும்',
        'config-help' => 'உதவி',
        'mainpagetext' => "'''விக்கி மென்பொருள் வெற்றிகரமாக உள்ளிடப்பட்டது.'''",
        'mainpagedocfooter' => 'விக்கி மென்பொருளைப் பயன்படுத்துவது தொடர்பாக [//meta.wikimedia.org/wiki/Help:Contents பயனர் வழிகாட்டியைப்] பார்க்க.
@@ -18222,7 +18345,7 @@ $messages['ta'] = array(
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings அமைப்புக்களை மாற்றம் செய்தல்]
 * [//www.mediawiki.org/wiki/Manual:FAQ மிடியாவிக்கி பொதுவான கேள்விகள்]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce மீடியாவிக்கி வெளியீடு மின்னஞ்சல் பட்டியல்]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce மீடியாவிக்கி வெளியீடு மின்னஞ்சல் பட்டியல்]', # Fuzzy
 );
 
 /** Tulu (ತುಳು)
@@ -18367,6 +18490,7 @@ $messages['tk'] = array(
 /** Tagalog (Tagalog)
  * @author AnakngAraw
  * @author Sky Harbor
+ * @author 아라
  */
 $messages['tl'] = array(
        'config-desc' => 'Ang tagapagluklok para sa MediaWiki',
@@ -18374,20 +18498,20 @@ $messages['tl'] = array(
        'config-information' => 'Kabatiran',
        'config-localsettings-upgrade' => 'Napansin ang isang talaksang <code>LocalSettings.php</code>.
 Upang maitaas ang uri ng pagluluklok na ito, paki ipasok ang halaga ng <code>$wgUpgradeKey</code> sa loob ng kahong nasa ibaba.
-Matatagpuan mo ito sa loob ng LocalSettings.php.',
-       'config-localsettings-cli-upgrade' => 'Napansin ang isang talaksan ng LocalSettings.php.
-Upang isapanahon ang pagtatalagang ito, mangyaring patakbuhin sa halip ang update.php',
+Matatagpuan mo ito sa loob ng <code>LocalSettings.php</code>.',
+       'config-localsettings-cli-upgrade' => 'Napansin ang isang talaksan ng <code>LocalSettings.php</code>.
+Upang isapanahon ang pagtatalagang ito, mangyaring patakbuhin sa halip ang <code>update.php</code>',
        'config-localsettings-key' => 'Susi ng pagsasapanahon:',
        'config-localsettings-badkey' => 'Hindi tama ang susing ibinigay mo.',
        'config-upgrade-key-missing' => 'Napansin ang isang umiiral na pagtatalaga ng MediaWiki.
-Upang isapanahon ang katalagahang ito, mangyaring ilagay ang sumusunod na guhit sa ilalim ng iyong LocalSettings.php:
+Upang isapanahon ang katalagahang ito, mangyaring ilagay ang sumusunod na guhit sa ilalim ng iyong <code>LocalSettings.php</code>:
 
 $1',
-       'config-localsettings-incomplete' => 'Lumilitaw na hindi pa buo ang umiiral na LocalSettings.php.
+       'config-localsettings-incomplete' => 'Lumilitaw na hindi pa buo ang umiiral na <code>LocalSettings.php</code>.
 Ang pabagu-bagong $1 ay hindi nakatakda.
-Mangyaring baguhin ang  LocalSettings.php upang ang maitakda ang pagpapabagu-bagong ito, at pindutin ang "Magpatuloy".',
-       'config-localsettings-connection-error' => 'Isang kamalian ang nakatagpo noong kumakabit sa kalipunan ng dato na ginagamit ang tinukoy na mga katakdaan sa loob ng LocalSettings.php o
-AdminSettings.php. Paki kumpunihin ang mga katakdaang ito at subukang muli.
+Mangyaring baguhin ang  <code>LocalSettings.php</code> upang ang maitakda ang pagpapabagu-bagong ito, at pindutin ang "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Isang kamalian ang nakatagpo noong kumakabit sa kalipunan ng dato na ginagamit ang tinukoy na mga katakdaan sa loob ng <code>LocalSettings.php</code> o
+<code>AdminSettings.php</code>. Paki kumpunihin ang mga katakdaang ito at subukang muli.
 
 $1',
        'config-session-error' => 'Kamalian sa pagsisimula ng sesyon: $1',
@@ -18516,7 +18640,7 @@ Pinigilan ang pag-iinstala.",
        'config-brokenlibxml' => "Ang sistema mo ay mayroong isang pagsasama ng mga bersiyon ng PHP at libxml2 na maaaring masurot at maaaring makapagsanhi ng pagkasira ng datong nakakubli sa loob ng MediaWiki at iba pang mga aplikasyon ng sangkasaputan.
 Magtaas ng uri upang maging PHP 5.2.9 o mas lalong huli at libxml2 2.7.3 o mas lalong huli ([//bugs.php.net/bug.php?id=45996 isinalansan ang surot o ''bug'' na mayroong PHP]). Binigo ang pagluluklok.",
        'config-using531' => 'Hindi maaaring gamitin ang MediaWiki na kapiling ang PHP na $1 dahil sa isang surot na kinasasangkutan ng mga parametrong pangsangguni sa <code>__call()</code>. Magtaas ng uri upang maging PHP 5.3.2 o mas mataas, o magbaba ng uri upang maging PHP 5.3.0 upang malutas ito. Binigo ang pagluluklok.',
-       'config-suhosin-max-value-length' => 'Nakaluklok ang Suhosin at hinahanggahan ang haba ng parametro ng GET sa $1 mga byte. Ang sangkap na ResourceLoader ng MediaWiki ay gagana sa paligid ng hangganang ito, subalit pasasamain nito ang pagganap. Kung talagang maaari, dapat mong itakda ang suhosin.get.max_value_length upang maging 1024 o mas mataas sa loob ng php.ini, at itakda ang $wgResourceLoaderMaxQueryLength sa katulad na halaga sa loob ng LocalSettings.php.',
+       'config-suhosin-max-value-length' => 'Nakaluklok ang Suhosin at hinahanggahan ang haba ng parametro ng GET sa $1 mga byte. Ang sangkap na ResourceLoader ng MediaWiki ay gagana sa paligid ng hangganang ito, subalit pasasamain nito ang pagganap. Kung talagang maaari, dapat mong itakda ang <code>suhosin.get.max_value_length</code> upang maging 1024 o mas mataas sa loob ng <code>php.ini</code>, at itakda ang <code>$wgResourceLoaderMaxQueryLength</code> sa katulad na halaga sa loob ng LocalSettings.php.', # Fuzzy
        'config-db-type' => 'Uri ng kalipunan ng datos:',
        'config-db-host' => 'Tagapagpasinaya ng kalipunan ng datos:',
        'config-db-host-help' => 'Kung ang iyong tagapaghain ng kalipunan ng dato ay nasa ibabaw ng isang ibang tagapaghain, ipasok ang pangalan ng tagapagpasinaya o tirahan ng IP dito.
@@ -18601,7 +18725,7 @@ Kung hindi mo makita ang sistema ng kalipunan ng dato na sinusubukan mong gamiti
        'config-support-postgres' => '* Ang $1 ay isang bantog na sistema ng kalipunan ng dato na bukas ang pinagmulan na panghalili sa MySQL ([http://www.php.net/manual/en/pgsql.installation.php paano magtipon ng PHP na mayroong suporta ng PostgreSQL]). Maaaring mayroong ilang hindi pangunahing mga surot na natitira pa, at hindi iminumungkahi para gamitin sa loob ng isang kapaligiran ng produksiyon.',
        'config-support-sqlite' => 'Ang $1 ay isang magaan ang timbang na sistema ng kalipunan ng dato na sinusuportahan nang napaka mainam. ([http://www.php.net/manual/en/pdo.installation.php Paano magtipon ng PHP na mayroong suporta ng SQLite], gumagamit ng PDO)',
        'config-support-oracle' => '* Ang $1 ay isang kalipunan ng dato ng kasigasigang pangkalakal. ([http://www.php.net/manual/en/oci8.installation.php Paano magtipunan ng PHP na mayroong suporta ng OCI8])',
-       'config-support-ibm_db2' => '* Ang $1 ay isang kalipunan ng dato ng kasigasigang pangkalakal.',
+       'config-support-ibm_db2' => '* Ang $1 ay isang kalipunan ng dato ng kasigasigang pangkalakal.', # Fuzzy
        'config-header-mysql' => 'Mga katakdaan ng MySQL',
        'config-header-postgres' => 'Mga katakdaan ng PostgreSQL',
        'config-header-sqlite' => 'Mga katakdaan ng SQLite',
@@ -18668,8 +18792,8 @@ Kung nais mong muling likhain ang iyong talaksang <code>LocalSettings.php</code>
        'config-upgrade-done-no-regenerate' => 'Buo na ang pagsasapanahon.
 
 Maaari ka na ngayong [$1 magsimula sa paggamit ng wiki mo].',
-       'config-regenerate' => 'Muling likhain ang LocalSettings.php →',
-       'config-show-table-status' => 'Nabigo ang pagtatanong na IPAKITA ANG KALAGAYAN NG TALAHANAYAN!',
+       'config-regenerate' => 'Muling likhain ang <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Nabigo ang pagtatanong na IPAKITA ANG KALAGAYAN NG TALAHANAYAN!', # Fuzzy
        'config-unknown-collation' => "'''Babala:''' Ang kalipunan ng dato ay gumagagamit ng hindi nakikilalang pag-iipon.",
        'config-db-web-account' => 'Akawnt ng kalipunan ng dato para sa pagpunta sa web',
        'config-db-web-help' => 'Piliin ang pangalan ng tagagamit at hudyat na gagamitin ng tagapaghain ng web upang umugnay sa tagapaghain ng kalipunan ng dato, habang nasa pangkaraniwang pagtakbo ng wiki.',
@@ -18739,7 +18863,7 @@ Maaari mo ngayong laktawan ang natitira pang pag-aayos at iluklok na ang wiki ng
        'config-optional-continue' => 'Magtanong sa akin ng marami pang mga tanong.',
        'config-optional-skip' => 'Naiinip na ako, basta iluklok na lang ang wiki.',
        'config-profile' => 'Balangkas ng mga karapatan ng tagagamit:',
-       'config-profile-wiki' => 'Tradisyonal na wiki',
+       'config-profile-wiki' => 'Tradisyonal na wiki', # Fuzzy
        'config-profile-no-anon' => 'Kailangan ang paglikha ng akawnt',
        'config-profile-fishbowl' => 'Pinahintulutang mga patnugot lamang',
        'config-profile-private' => 'Pribadong wiki',
@@ -18755,7 +18879,7 @@ Ang isang wiki na mayroong '''{{int:config-profile-no-anon}}''' ay nagbibigay ng
 Ang tagpo na '''{{int:config-profile-fishbowl}}''' ay nagpapahintulot lamang sa pinayagang mga tagagamit na makatingin ng mga pahina, na kapiling ang pangkat na pinayagang  makapamatnugot.
 Ang isang '''{{int:config-profile-private}}''' ay nagpapahintulot lamang sa pinayagang mga tagagamit na makatingin ng mga pahina, na kapiling ang pangkat na pinayagang makapamatnugot.
 
-Ang mas masasalimuot na mga kaayusan ng mga karapatan ng tagagamit ay makukuha pagkaraan ng pagluluklok, tingnan ang [//www.mediawiki.org/wiki/Manual:User_rights may kaugnayang kinamay na lahok].",
+Ang mas masasalimuot na mga kaayusan ng mga karapatan ng tagagamit ay makukuha pagkaraan ng pagluluklok, tingnan ang [//www.mediawiki.org/wiki/Manual:User_rights may kaugnayang kinamay na lahok].", # Fuzzy
        'config-license' => 'Karapatang-ari at lisensiya:',
        'config-license-none' => 'Walang talababa ng lisensiya',
        'config-license-cc-by-sa' => 'Malikhaing Pangkaraniwang Pagtukoy Pamamahaging Magkatulad',
@@ -18840,7 +18964,7 @@ Maaaring mangailangan ang mga ito ng karagdagang kaayusan, subalit mapapagana mo
        'config-install-alreadydone' => "'''Babala:''' Tila nailuklok mo na ang MediaWiki at tinatangka mong iluklok ito ulit.
 Paki magpatuloy sa susunod na pahina.",
        'config-install-begin' => 'Sa pamamagitan ng pagpindot sa "{{int:config-continue}}", sisimulan mo ang pagluluklok ng MediaWiki.
-Kung nais mo paring gumawa ng mga pagbabago, paki pindutin ang bumalik.',
+Kung nais mo paring gumawa ng mga pagbabago, paki pindutin ang bumalik.', # Fuzzy
        'config-install-step-done' => 'nagawa na',
        'config-install-step-failed' => 'nabigo',
        'config-install-extensions' => 'Isinasama ang mga karugtong',
@@ -18896,7 +19020,7 @@ $3
 '''Paunawa''': Kapag hindi mo ito ginawa ngayon, ang nagawang talaksang ito ng pagkakaayos ay hindi mo na makukuha mamaya kapag lumabas ka mula sa pagluluklok na hindi ikinakarga itong paibaba.
 
 Kapag nagawa na iyan, maaari ka nang '''[$2 pumasok sa wiki mo]'''.",
-       'config-download-localsettings' => 'Ikargang paibaba ang LocalSettings.php',
+       'config-download-localsettings' => 'Ikargang paibaba ang <code>LocalSettings.php</code>',
        'config-help' => 'saklolo',
        'config-nofile' => 'Hindi matagpuan ang talaksang "$1". Binura na ba ito?',
        'mainpagetext' => "'''Matagumpay na ininstala ang MediaWiki.'''",
@@ -18906,7 +19030,7 @@ Kapag nagawa na iyan, maaari ka nang '''[$2 pumasok sa wiki mo]'''.",
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Tala ng mga nakatakdang kumpigurasyon]
 * [//www.mediawiki.org/wiki/Manual:FAQ Mga malimit itanong sa MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Tala ng mga pinadadalhan ng liham ng MediaWiki]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Tala ng mga pinadadalhan ng liham ng MediaWiki]", # Fuzzy
 );
 
 /** толышә зывон (толышә зывон)
@@ -18982,6 +19106,7 @@ $messages['ug-arab'] = array(
  * @author Diemon.ukr
  * @author Ата
  * @author Тест
+ * @author 아라
  */
 $messages['uk'] = array(
        'config-desc' => 'Інсталятор MediaWiki',
@@ -18990,17 +19115,17 @@ $messages['uk'] = array(
        'config-localsettings-upgrade' => "'''Увага''': було виявлено файл <code>LocalSettings.php</code>.
 Ваше програмне забезпечення може бути оновлено.
 Будь-ласка, перемістіть файл <code>LocalSettings.php</code> в іншу безпечну директорію, а потім знову запустіть програму установки.",
-       'config-localsettings-cli-upgrade' => 'Виявлено файл LocalSettings.php.
-Щоб оновити наявну установку, запустіть update.php',
+       'config-localsettings-cli-upgrade' => 'Виявлено файл <code>LocalSettings.php</code>.
+Щоб оновити наявну установку, запустіть <code>update.php</code>',
        'config-localsettings-key' => 'Ключ оновлення:',
        'config-localsettings-badkey' => 'Ви вказали неправильний ключ.',
        'config-upgrade-key-missing' => 'Виявлено наявну установку MediaWiki.
-Для оновлення цієї установки, будь ласка, вставте такий рядок в кінець вашого LocalSettings.php:
+Для оновлення цієї установки, будь ласка, вставте такий рядок в кінець вашого <code>LocalSettings.php</code>:
 $1',
-       'config-localsettings-incomplete' => 'Існуючий файл LocalSettings.php виявився неповним.
+       'config-localsettings-incomplete' => 'Існуючий файл <code>LocalSettings.php</code> виявився неповним.
 Не вказано змінну $1.
-Будь ласка, змініть LocalSettings.php так, щоб цю змінну було задано, і натисніть "Продовжити".',
-       'config-localsettings-connection-error' => 'Сталася помилка при підключення до бази даних з допомогою налаштувань на сторінці LocalSettings.php чи AdminSettings.php. Будь ласка, виплавте ці налаштування і спробуйте знову.
+Будь ласка, змініть <code>LocalSettings.php</code> так, щоб цю змінну було задано, і натисніть "{{int:Config-continue}}".',
+       'config-localsettings-connection-error' => 'Сталася помилка при підключення до бази даних з допомогою налаштувань на сторінці <code>LocalSettings.php</code> чи <code>AdminSettings.php</code>. Будь ласка, виплавте ці налаштування і спробуйте знову.
 
 $1',
        'config-session-error' => 'Помилка початку сесії: $1',
@@ -19131,7 +19256,7 @@ MediaWiki вимагає підтримку UTF-8 для коректної ро
        'config-using531' => 'MediaWiki не можна використовувати разом з PHP $1 через помилку з параметрами-посиланнями <code>__call()</code>.
 Оновіть PHP до версії 5.3.2 і вище або відкотіть до PHP 5.3.0 щоб уникнути цієї проблеми.
 Встановлення скасовано.',
-       'config-suhosin-max-value-length' => 'Suhosin встановлено і обмежує довжину параметра GET до $1 байтів. Компонент MediaWiki ResourceLoader буде обходити це обмеження, однак це зменшить продуктивність. Якщо це можливо, Вам варто встановити значення suhosin.get.max_value_length 1024 і більше у php.ini і встановити таке ж значення $wgResourceLoaderMaxQueryLength у LocalSettings.php .',
+       'config-suhosin-max-value-length' => 'Suhosin встановлено і обмежує довжину параметра GET до $1 байтів. Компонент MediaWiki ResourceLoader буде обходити це обмеження, однак це зменшить продуктивність. Якщо це можливо, Вам варто встановити значення <code>suhosin.get.max_value_length</code> 1024 і більше у <code>php.ini</code> і встановити таке ж значення <code>$wgResourceLoaderMaxQueryLength</code> у LocalSettings.php .', # Fuzzy
        'config-db-type' => 'Тип бази даних:',
        'config-db-host' => 'Хост бази даних:',
        'config-db-host-help' => 'Якщо сервер бази даних знаходиться на іншому сервері, введіть тут ім\'я хосту і IP адресу.
@@ -19212,7 +19337,7 @@ $1
        'config-support-postgres' => '* $1 — популярна відкрита СУБД, альтернатива MySQL ([http://www.php.net/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]). Можуть зустрічатись деякі невеликі невиправлені помилки, не рекомендується використовувати у робочій системі.',
        'config-support-sqlite' => '* $1 — легка система баз даних, яка дуже добре підтримується. ([http://www.php.net/manual/en/pdo.installation.php Як зібрати PHP з допомогою SQLite], що використовує PDO)',
        'config-support-oracle' => '* $1 — комерційна база даних масштабу підприємства. ([http://www.php.net/manual/en/oci8.installation.php Як зібрати PHP з підтримкою OCI8])',
-       'config-support-ibm_db2' => '* $1 — комерційна база даних масштабу підприємства.',
+       'config-support-ibm_db2' => '* $1 — комерційна база даних масштабу підприємства.', # Fuzzy
        'config-header-mysql' => 'Налаштування MySQL',
        'config-header-postgres' => 'Налаштування PostgreSQL',
        'config-header-sqlite' => 'Налаштування SQLite',
@@ -19279,8 +19404,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => 'Оновлення завершено.
 
 Ви можете зараз [$1 починати використовувати свою вікі].',
-       'config-regenerate' => 'Повторно згенерувати LocalSettings.php →',
-       'config-show-table-status' => 'Запит SHOW TABLE STATUS не виконано!',
+       'config-regenerate' => 'Повторно згенерувати <code>LocalSettings.php</code> →',
+       'config-show-table-status' => 'Запит <code>SHOW TABLE STATUS</code> не виконано!',
        'config-unknown-collation' => "'''Увага:''' База даних використовує нерозпізнане сортування.",
        'config-db-web-account' => 'Обліковий запис бази даних для інтернет-доступу',
        'config-db-web-help' => "Оберіть ім'я користувача і пароль, які веб-сервер буде використовувати для з'єднання із сервером бази даних під час звичайної роботи вікі.",
@@ -19352,7 +19477,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => 'Запитуйте ще.',
        'config-optional-skip' => 'Це вже втомлює, просто встановити вікі.',
        'config-profile' => 'Профіль прав користувача:',
-       'config-profile-wiki' => 'Традиційна вікі',
+       'config-profile-wiki' => 'Традиційна вікі', # Fuzzy
        'config-profile-no-anon' => 'Необхідно створити обліковий запис',
        'config-profile-fishbowl' => 'Тільки для авторизованих редакторів',
        'config-profile-private' => 'Приватна вікі',
@@ -19367,7 +19492,7 @@ chmod a+w $3</pre>',
 Спосіб \"'''{{int:config-profile-fishbowl}}'''\" дозволяє редагувати підтвердженим користувачам, а переглядати сторінки і історію можуть усі.
 '''{{int:config-profile-private}}''' дозволяє переглядати сторінки і редагувати лише підтвердженим користувачам.
 
-Детальніші конфігурації прав користувачів доступні після встановлення, див. [//www.mediawiki.org/wiki/Manual:User_rights відповідний розділ посібника].",
+Детальніші конфігурації прав користувачів доступні після встановлення, див. [//www.mediawiki.org/wiki/Manual:User_rights відповідний розділ посібника].", # Fuzzy
        'config-license' => 'Авторські права і ліцензія:',
        'config-license-none' => 'Без ліцензії у нижньому колонтитулі',
        'config-license-cc-by-sa' => 'Creative Commons Attribution Share Alike',
@@ -19449,7 +19574,7 @@ GFDL — допустима ліцензія, але у ній важко роз
        'config-install-alreadydone' => "'''Увага:''' Здається, Ви вже встановлювали MediaWiki і зараз намагаєтесь встановити її знову.
 Будь ласка, перейдіть на наступну сторінку.",
        'config-install-begin' => 'Натискаючи "{{int:config-continue}}", Ви розпочинаєте встановлення MediaWiki.
-Якщо Ви все ще хочете внести зміни, натисніть "Назад".',
+Якщо Ви все ще хочете внести зміни, натисніть "Назад".', # Fuzzy
        'config-install-step-done' => 'виконано',
        'config-install-step-failed' => 'не вдалося',
        'config-install-extensions' => 'У тому числі розширення',
@@ -19504,7 +19629,7 @@ $3
 '''Примітка''': Якщо Ви не зробите цього зараз, цей файл не буде доступним пізніше, коли Ви вийдете з встановлення, не скачавши його.
 
 Після виконання дій, описаних вище, Ви зможете '''[$2 увійти у свою вікі]'''.",
-       'config-download-localsettings' => 'Завантажити LocalSettings.php',
+       'config-download-localsettings' => 'Завантажити <code>LocalSettings.php</code>',
        'config-help' => 'допомога',
        'config-nofile' => 'Файл "$1" не знайдено. Його видалено?',
        'mainpagetext' => 'Програмне забезпечення «MediaWiki» успішно встановлене.',
@@ -19762,21 +19887,23 @@ $messages['zea'] = array(
  * @author PhiLiP
  * @author Xiaomingyan
  * @author Yfdyh000
+ * @author 乌拉跨氪
  * @author 阿pp
+ * @author 아라
  */
 $messages['zh-hans'] = array(
        'config-desc' => 'MediaWiki安装程序',
        'config-title' => 'MediaWiki $1配置',
        'config-information' => '信息',
-       'config-localsettings-upgrade' => '已检测到<code>LocalSettings.php</code>文件。要升级该配置,请在下面的框中输入<code>$wgUpgradeKey</code>的值。您可以在LocalSettings.php中找到它。',
-       'config-localsettings-cli-upgrade' => '已检测到LocalSettings.php文件。要升级该配置,请直接运行update.php。',
+       'config-localsettings-upgrade' => '已检测到<code>LocalSettings.php</code>文件。要升级该配置,请在下面的框中输入<code>$wgUpgradeKey</code>的值。您可以在<code>LocalSettings.php</code>中找到它。',
+       'config-localsettings-cli-upgrade' => '已检测到<code>LocalSettings.php</code>文件。要升级该配置,请直接运行<code>update.php</code>。',
        'config-localsettings-key' => '升级密钥:',
        'config-localsettings-badkey' => '您提供的密钥不正确。',
-       'config-upgrade-key-missing' => '检测到MediaWiki的配置已经存在。若要升级该配置,请将下面一行文本添加到LocalSettings.php的底部:
+       'config-upgrade-key-missing' => '检测到MediaWiki的配置已经存在。若要升级该配置,请将下面一行文本添加到<code>LocalSettings.php</code>的底部:
 
 $1',
-       'config-localsettings-incomplete' => '当前的LocalSettings.php可能并不完整,因为变量$1没有设置。请在LocalSettings.php设置该变量,并单击“继续”。',
-       'config-localsettings-connection-error' => '在使用LocalSettings.php或AdminSettings.php中指定的设置连接数据库时发生错误。请修复相应设置并重试。
+       'config-localsettings-incomplete' => '当前的<code>LocalSettings.php</code>可能并不完整,因为变量$1没有设置。请在<code>LocalSettings.php</code>设置该变量,并单击“{{int:Config-continue}}”。',
+       'config-localsettings-connection-error' => '在使用<code>LocalSettings.php</code>或<code>AdminSettings.php</code>中指定的设置连接数据库时发生错误。请修复相应设置并重试。
 
 $1',
        'config-session-error' => '启动会话出错:$1',
@@ -19873,7 +20000,7 @@ Object caching is not enabled.",
        'config-no-cli-uploads-check' => "'''警告''':在CLI安装过程中,没有对您的默认上传目录(<code>$1</code>)进行执行任意脚本的漏洞检查。",
        'config-brokenlibxml' => '您的系统安装的PHP和libxml2版本组合存在故障,并可能在MediaWiki和其他web应用程序中造成隐藏的数据损坏。请将PHP升级到5.2.9或以上,libxml2升级到2.7.3或以上([//bugs.php.net/bug.php?id=45996 PHP的故障报告])。安装已中断。',
        'config-using531' => '由于函数<code>__call()</code>的引用参数存在故障,PHP $1和MediaWiki无法兼容。请升级到PHP 5.3.2或更高版本,或降级到PHP 5.3.0以修复该问题。安装已中断。',
-       'config-suhosin-max-value-length' => 'Suhosin已经安装并将GET请求的参数长度限制在$1字节。MediaWiki的ResourceLoader部件可以在此限制下正常工作,但其性能会被降低。如果可能,请在php.ini中将suhosin.get.max_value_length设为1024或更高值,并在LocalSettings.php中将$wgResourceLoaderMaxQueryLength设为同一值。',
+       'config-suhosin-max-value-length' => 'Suhosin已经安装并将GET请求的参数长度限制在$1字节。MediaWiki的ResourceLoader部件可以在此限制下正常工作,但其性能会被降低。如果可能,请在<code>php.ini</code>中将<code>suhosin.get.max_value_length</code>设为1024或更高值,并在LocalSettings.php中将<code>$wgResourceLoaderMaxQueryLength</code>设为同一值。', # Fuzzy
        'config-db-type' => '数据库类型:',
        'config-db-host' => '数据库主机:',
        'config-db-host-help' => '如果您的数据库在别的服务器上,请在这里输入它的域名或IP地址。
@@ -19946,7 +20073,7 @@ $1
        'config-support-postgres' => '* $1是一种流行的开源数据库系统,可作为MySQL的替代([http://www.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])。本程序中可能依然存在一些小而明显的错误,因此并不建议在生产环境中使用该数据库系统。',
        'config-support-sqlite' => '* $1是一种轻量级的数据库系统,能被良好地支持。([http://www.php.net/manual/en/pdo.installation.php 如何将对SQLite的支持编译进PHP中],须使用PDO)',
        'config-support-oracle' => '* $1是一种商用企业级的数据库。([http://www.php.net/manual/en/oci8.installation.php 如何将对OCI8的支持编译进PHP中])',
-       'config-support-ibm_db2' => '* $1是一种商用企业级数据库。',
+       'config-support-ibm_db2' => '* $1是一种商用企业级数据库。([http://www.php.net/manual/en/ibm-db2.installation.php 如何编译支持IBM DB2的PHP])',
        'config-header-mysql' => 'MySQL设置',
        'config-header-postgres' => 'PostgreSQL设置',
        'config-header-sqlite' => 'SQLite设置',
@@ -19999,8 +20126,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => '升级完成。
 
 现在您可以[$1 开始使用您的wiki]了。',
-       'config-regenerate' => '重新生成LocalSettings.php →',
-       'config-show-table-status' => 'SHOW TABLE STATUS语句执行失败!',
+       'config-regenerate' => '重新生成<code>LocalSettings.php</code> →',
+       'config-show-table-status' => '<code>SHOW TABLE STATUS</code>语句执行失败!',
        'config-unknown-collation' => "'''警告:'''数据库使用了无法识别的整理。",
        'config-db-web-account' => '供网页访问使用的数据库帐号',
        'config-db-web-help' => '请指定在wiki执行普通操作时,网页服务器用于连接数据库服务器的用户名和密码。',
@@ -20060,7 +20187,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => '多问我一些问题吧。',
        'config-optional-skip' => '我已经不耐烦了,赶紧安装我的wiki。',
        'config-profile' => '用户权限配置:',
-       'config-profile-wiki' => '传统wiki',
+       'config-profile-wiki' => '开放的wiki',
        'config-profile-no-anon' => '需要注册帐号',
        'config-profile-fishbowl' => '编辑受限',
        'config-profile-private' => '非公开wiki',
@@ -20137,7 +20264,7 @@ GNU自由文档许可证是维基百科曾经使用过的许可证,并迄今
 
 您可能要对它们进行额外的配置,但您现在可以启用它们。',
        'config-install-alreadydone' => "'''警告:'''您似乎已经安装了MediaWiki,并试图重新安装它。请前往下一个页面。",
-       'config-install-begin' => '点击“{{int:config-continue}}”后,您将开始安装MediaWiki。如果您还想对配置作一些修改,请点击后退。',
+       'config-install-begin' => '点击“{{int:config-continue}}”后,您将开始安装MediaWiki。如果您还想对配置作一些修改,请点击“{{int:config-back}}”。',
        'config-install-step-done' => '完成',
        'config-install-step-failed' => '失败',
        'config-install-extensions' => '正在启用扩展',
@@ -20188,7 +20315,7 @@ $3
 '''注意''':如果您现在不完成本步骤,而是没有下载便退出了安装过程,此后您将无法获得自动生成的配置文件。
 
 当本步骤完成后,您可以 '''[$2 进入您的wiki]'''。",
-       'config-download-localsettings' => '下载LocalSettings.php',
+       'config-download-localsettings' => '下载<code>LocalSettings.php</code>',
        'config-help' => '帮助',
        'config-nofile' => '找不到文件“$1”。它是否已被删除?',
        'mainpagetext' => "'''已成功安装MediaWiki。'''",
@@ -20197,7 +20324,8 @@ $3
 == 入门 ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki配置设置列表]
 * [//www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表]', # Fuzzy
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources 本地化MediaWiki到您的语言]',
 );
 
 /** Traditional Chinese (中文(繁體)‎)
  * @author Liangent
  * @author Mark85296341
  * @author Simon Shek
+ * @author 아라
  */
 $messages['zh-hant'] = array(
        'config-desc' => 'MediaWiki安裝程序',
        'config-title' => 'MediaWiki $1配置',
        'config-information' => '資訊',
-       'config-localsettings-upgrade' => '已檢測到<code>LocalSettings.php</code>文件。要升級該配置,請在下面的框中輸入<code>$wgUpgradeKey</code>的值。您可以在LocalSettings.php中找到它。',
-       'config-localsettings-cli-upgrade' => '已檢測到LocalSettings.php文件。要升級該配置,請直接執行update.php。',
+       'config-localsettings-upgrade' => '已檢測到<code>LocalSettings.php</code>文件。要升級該配置,請在下面的框中輸入<code>$wgUpgradeKey</code>的值。您可以在<code>LocalSettings.php</code>中找到它。',
+       'config-localsettings-cli-upgrade' => '已檢測到<code>LocalSettings.php</code>文件。要升級該配置,請直接執行<code>update.php</code>。',
        'config-localsettings-key' => '升級密鑰:',
        'config-localsettings-badkey' => '您提供的密鑰不正確。',
-       'config-upgrade-key-missing' => '檢測到MediaWiki的配置已經存在。若要升級該配置,請將下面一行文本添加到LocalSettings.php的底部:
+       'config-upgrade-key-missing' => '檢測到MediaWiki的配置已經存在。若要升級該配置,請將下面一行文本添加到<code>LocalSettings.php</code>的底部:
 
 $1',
-       'config-localsettings-incomplete' => '當前的LocalSettings.php可能並不完整,因為變量$1沒有設置。請在LocalSettings.php設置該變量,並單擊“繼續”。',
-       'config-localsettings-connection-error' => '在使用LocalSettings.php或AdminSettings.php中指定的設置連接數據庫時發生錯誤。請修復相應設置並重試。
+       'config-localsettings-incomplete' => '當前的<code>LocalSettings.php</code>可能並不完整,因為變量$1沒有設置。請在<code>LocalSettings.php</code>設置該變量,並單擊“{{int:Config-continue}}”。',
+       'config-localsettings-connection-error' => '在使用<code>LocalSettings.php</code>或<code>AdminSettings.php</code>中指定的設置連接數據庫時發生錯誤。請修復相應設置並重試。
 
 $1',
        'config-session-error' => '啟動會話出錯:$1',
@@ -20315,7 +20444,7 @@ Object caching is not enabled.",
        'config-no-cli-uploads-check' => "'''警告''':在CLI安裝過程中,沒有對您的默認上傳目錄(<code>$1</code>)進行執行任意腳本的漏洞檢查。",
        'config-brokenlibxml' => '您的系統安裝的PHP和libxml2版本組合存在故障,並可能在MediaWiki和其他web應用程序中造成隱藏的數據損壞。請將PHP升級到5.2.9或以上,libxml2升級到2.7.3或以上([//bugs.php.net/bug.php?id=45996 PHP的故障報告])。安裝已中斷。',
        'config-using531' => '由於函數<code>__call()</code>的引用參數存在故障,PHP $1和MediaWiki無法兼容。請升級到PHP 5.3.2或更高版本,或降級到PHP 5.3.0以修復該問題。安裝已中斷。',
-       'config-suhosin-max-value-length' => 'Suhosin已經安裝並將GET請求的參數長度限制在$1字節。MediaWiki的ResourceLoader部件可以在此限制下正常工作,但其性能會被降低。如果可能,請在php.ini中將suhosin.get.max_value_length設為1024或更高值,並在LocalSettings.php中將$wgResourceLoaderMaxQueryLength設為同一值。',
+       'config-suhosin-max-value-length' => 'Suhosin已經安裝並將GET請求的參數長度限制在$1字節。MediaWiki的ResourceLoader部件可以在此限制下正常工作,但其性能會被降低。如果可能,請在<code>php.ini</code>中將<code>suhosin.get.max_value_length</code>設為1024或更高值,並在LocalSettings.php中將<code>$wgResourceLoaderMaxQueryLength</code>設為同一值。', # Fuzzy
        'config-db-type' => '資料庫類型:',
        'config-db-host' => '資料庫主機:',
        'config-db-host-help' => '如果您的數據庫在別的服務器上,請在這裡輸入它的域名或IP地址。
@@ -20388,7 +20517,7 @@ $1
        'config-support-postgres' => '* $1是一種流行的開源數據庫系統,可作為MySQL的替代([http://www.php.net/manual/en/pgsql.installation.php 如何將對PostgreSQL的支持編譯進PHP中])。本程序中可能依然存在一些小而明顯的錯誤,因此並不建議在生產環境中使用該數據庫系統。',
        'config-support-sqlite' => '* $1是一種輕量級的數據庫系統,能被良好地支持。([http://www.php.net/manual/en/pdo.installation.php 如何將對SQLite的支持編譯進PHP中],須使用PDO)',
        'config-support-oracle' => '* $1是一種商用企業級的數據庫。([http://www.php.net/manual/en/oci8.installation.php 如何將對OCI8的支持編譯進PHP中])',
-       'config-support-ibm_db2' => '* $1是一種商用企業級數據庫。',
+       'config-support-ibm_db2' => '* $1是一種商用企業級數據庫。', # Fuzzy
        'config-header-mysql' => 'MySQL 的設定',
        'config-header-postgres' => 'PostgreSQL設置',
        'config-header-sqlite' => 'SQLite 的設定',
@@ -20441,8 +20570,8 @@ chmod a+w $3</pre>',
        'config-upgrade-done-no-regenerate' => '升級完成。
 
 現在您可以[$1 開始使用您的wiki]了。',
-       'config-regenerate' => '重新生成LocalSettings.php →',
-       'config-show-table-status' => '查詢SHOW TABLE STATUS失敗!',
+       'config-regenerate' => '重新生成<code>LocalSettings.php</code> →',
+       'config-show-table-status' => '查詢<code>SHOW TABLE STATUS</code>失敗!',
        'config-unknown-collation' => "'''警告:'''數據庫使用了無法識別的整理。",
        'config-db-web-account' => '供網頁訪問使用的數據庫帳號',
        'config-db-web-help' => '請指定在wiki執行普通操作時,網頁服務器用於連接數據庫服務器的用戶名和密碼。',
@@ -20502,7 +20631,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => '多問我一些問題吧。',
        'config-optional-skip' => '我已經不耐煩了,趕緊安裝我的wiki。',
        'config-profile' => '用戶權限配置:',
-       'config-profile-wiki' => '傳統wiki',
+       'config-profile-wiki' => '傳統wiki', # Fuzzy
        'config-profile-no-anon' => '需要註冊帳號',
        'config-profile-fishbowl' => '編輯受限',
        'config-profile-private' => '非公開wiki',
@@ -20514,7 +20643,7 @@ chmod a+w $3</pre>',
 
 '''{{int:config-profile-fishbowl}}'''模式只允許獲批准的用戶編輯,但對公眾開放頁面瀏覽(包括歷史記錄)。'''{{int:config-profile-private}}'''則只允許獲批准的用戶瀏覽、編輯頁面。
 
-安裝完成後,您還可以對用戶權限進行更多、更複雜的配置,參見[//www.mediawiki.org/wiki/Manual:User_rights 相關的使用手冊]。",
+安裝完成後,您還可以對用戶權限進行更多、更複雜的配置,參見[//www.mediawiki.org/wiki/Manual:User_rights 相關的使用手冊]。", # Fuzzy
        'config-license' => '版權和許可證:',
        'config-license-none' => '頁腳無許可證',
        'config-license-cc-by-sa' => '知識共享署名-相同方式分享',
@@ -20579,7 +20708,7 @@ GNU自由文檔許可證是維基百科曾經使用過的許可證,並迄今
 
 您可能要對它們進行額外的配置,但您現在可以啟用它們。',
        'config-install-alreadydone' => "'''警告:'''您似乎已經安裝了MediaWiki,並試圖重新安裝它。請前往下一個頁面。",
-       'config-install-begin' => '點擊“{{int:config-continue}}”後,您將開始安裝MediaWiki。如果您還想對配置作一些修改,請點擊後退。',
+       'config-install-begin' => '點擊“{{int:config-continue}}”後,您將開始安裝MediaWiki。如果您還想對配置作一些修改,請點擊後退。', # Fuzzy
        'config-install-step-done' => '完成',
        'config-install-step-failed' => '失敗',
        'config-install-extensions' => '正在啟用擴展',
@@ -20630,7 +20759,7 @@ $3
 '''注意''':如果您現在不完成本步驟,而是沒有下載便退出了安裝過程,此後您將無法獲得自動生成的配置文件。
 
 當本步驟完成後,您可以 '''[$2 進入您的wiki]'''。",
-       'config-download-localsettings' => '下載LocalSettings.php',
+       'config-download-localsettings' => '下載<code>LocalSettings.php</code>',
        'config-help' => '說明',
        'mainpagetext' => "'''已成功安裝MediaWiki。'''",
        'mainpagedocfooter' => '請參閱[//meta.wikimedia.org/wiki/Help:Contents 用戶手冊]以獲得使用此wiki軟體的訊息!
index c673f6f..325f894 100644 (file)
@@ -313,19 +313,19 @@ abstract class Installer {
         * output format such as HTML or text before being sent to the user.
         * @param $msg
         */
-       public abstract function showMessage( $msg /*, ... */ );
+       abstract public function showMessage( $msg /*, ... */ );
 
        /**
         * Same as showMessage(), but for displaying errors
         * @param $msg
         */
-       public abstract function showError( $msg /*, ... */ );
+       abstract public function showError( $msg /*, ... */ );
 
        /**
         * Show a message to the installing user by using a Status object
         * @param $status Status
         */
-       public abstract function showStatusMessage( Status $status );
+       abstract public function showStatusMessage( Status $status );
 
        /**
         * Constructor, always call this from child classes.
@@ -488,7 +488,7 @@ abstract class Installer {
                if( !$_lsExists ) {
                        return false;
                }
-               unset($_lsExists);
+               unset( $_lsExists );
 
                require( "$IP/includes/DefaultSettings.php" );
                require( "$IP/LocalSettings.php" );
@@ -927,7 +927,7 @@ abstract class Installer {
         * Helper function to be called from envCheckServer()
         * @return String
         */
-       protected abstract function envGetDefaultServer();
+       abstract protected function envGetDefaultServer();
 
        /**
         * Environment check for setting $IP and $wgScriptPath.
@@ -1073,18 +1073,18 @@ abstract class Installer {
         * @return string
         */
        protected function unicodeChar( $c ) {
-               $c = hexdec($c);
-               if ($c <= 0x7F) {
-                       return chr($c);
-               } elseif ($c <= 0x7FF) {
-                       return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F);
-               } elseif ($c <= 0xFFFF) {
-                       return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F)
-                               . chr(0x80 | $c & 0x3F);
-               } elseif ($c <= 0x10FFFF) {
-                       return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F)
-                               . chr(0x80 | $c >> 6 & 0x3F)
-                               . chr(0x80 | $c & 0x3F);
+               $c = hexdec( $c );
+               if ( $c <= 0x7F ) {
+                       return chr( $c );
+               } elseif ( $c <= 0x7FF ) {
+                       return chr( 0xC0 | $c >> 6 ) . chr( 0x80 | $c & 0x3F );
+               } elseif ( $c <= 0xFFFF ) {
+                       return chr( 0xE0 | $c >> 12 ) . chr( 0x80 | $c >> 6 & 0x3F )
+                               . chr( 0x80 | $c & 0x3F );
+               } elseif ( $c <= 0x10FFFF ) {
+                       return chr( 0xF0 | $c >> 18 ) . chr( 0x80 | $c >> 12 & 0x3F )
+                               . chr( 0x80 | $c >> 6 & 0x3F )
+                               . chr( 0x80 | $c & 0x3F );
                } else {
                        return false;
                }
@@ -1105,8 +1105,8 @@ abstract class Installer {
                 * Note that we use the hex representation to create the code
                 * points in order to avoid any Unicode-destroying during transit.
                 */
-               $not_normal_c = $this->unicodeChar("FA6C");
-               $normal_c = $this->unicodeChar("242EE");
+               $not_normal_c = $this->unicodeChar( "FA6C" );
+               $normal_c = $this->unicodeChar( "242EE" );
 
                $useNormalizer = 'php';
                $needsUpdate = false;
index f66f15f..4eb2d39 100644 (file)
@@ -107,7 +107,7 @@ class MysqlInstaller extends DatabaseInstaller {
                }
                if ( !strlen( $newValues['wgDBname'] ) ) {
                        $status->fatal( 'config-missing-db-name' );
-               } elseif ( !preg_match( '/^[a-z0-9_-]+$/i', $newValues['wgDBname'] ) ) {
+               } elseif ( !preg_match( '/^[a-z0-9+_-]+$/i', $newValues['wgDBname'] ) ) {
                        $status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] );
                }
                if ( !preg_match( '/^[a-z0-9_-]*$/i', $newValues['wgDBprefix'] ) ) {
@@ -516,7 +516,8 @@ class MysqlInstaller extends DatabaseInstaller {
                }
 
                if( $tryToCreate ) {
-                       $createHostList = array($server,
+                       $createHostList = array(
+                               $server,
                                'localhost',
                                'localhost.localdomain',
                                '%'
index fd7b48b..6a2d50f 100644 (file)
@@ -330,7 +330,7 @@ class MysqlUpdater extends DatabaseUpdater {
                }
 
                if( $this->applyPatch( 'patch-fix-il_from.sql', false, "Fixing ancient broken imagelinks table." ) ) {
-                       $this->output("NOTE: you will have to run maintenance/refreshLinks.php after this." );
+                       $this->output( "NOTE: you will have to run maintenance/refreshLinks.php after this." );
                }
        }
 
index 845816e..4c72a8f 100644 (file)
@@ -119,7 +119,7 @@ class OracleInstaller extends DatabaseInstaller {
                                        return $status;
                                }
                                if ( !$this->getVar( '_CreateDBAccount' ) ) {
-                                       $status->fatal('config-db-sys-create-oracle');
+                                       $status->fatal( 'config-db-sys-create-oracle' );
                                }
                        } else {
                                return $status;
@@ -241,7 +241,7 @@ class OracleInstaller extends DatabaseInstaller {
                        $status->fatal( 'config-db-sys-user-exists-oracle', $this->getVar( 'wgDBuser' ) );
                }
 
-               if ($status->isOK()) {
+               if ( $status->isOK() ) {
                        // user created or already existing, switching back to a normal connection
                        // as the new user has all needed privileges to setup the rest of the schema
                        // i will be using that user as _InstallUser from this point on
index 8f43a6d..cafe8cd 100644 (file)
@@ -163,7 +163,7 @@ class OracleUpdater extends DatabaseUpdater {
         * converted to NULL in Oracle
         */
        protected function doRemoveNotNullEmptyDefaults() {
-               $meta = $this->db->fieldInfo( 'categorylinks' , 'cl_sortkey_prefix' );
+               $meta = $this->db->fieldInfo( 'categorylinks', 'cl_sortkey_prefix' );
                if ( $meta->isNullable() ) {
                        return;
                }
@@ -171,7 +171,7 @@ class OracleUpdater extends DatabaseUpdater {
        }
 
        protected function doRemoveNotNullEmptyDefaults2() {
-               $meta = $this->db->fieldInfo( 'ipblocks' , 'ipb_by_text' );
+               $meta = $this->db->fieldInfo( 'ipblocks', 'ipb_by_text' );
                if ( $meta->isNullable() ) {
                        return;
                }
index 5cb851e..0a4b5e6 100644 (file)
@@ -90,6 +90,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addTable', 'uploadstash',       'patch-uploadstash.sql' ),
                        array( 'addTable', 'user_former_groups','patch-user_former_groups.sql' ),
                        array( 'addTable', 'external_user',     'patch-external_user.sql' ),
+                       array( 'addTable', 'sites',             'patch-sites.sql' ),
 
                        # Needed before new field
                        array( 'convertArchive2' ),
@@ -155,6 +156,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgField', 'uploadstash',   'us_chunk_inx',         "INTEGER NULL" ),
                        array( 'addPgField', 'job',           'job_timestamp',        "TIMESTAMPTZ" ),
                        array( 'addPgField', 'job',           'job_random',           "INTEGER NOT NULL DEFAULT 0" ),
+                       array( 'addPgField', 'job',           'job_attempts',         "INTEGER NOT NULL DEFAULT 0" ),
                        array( 'addPgField', 'job',           'job_token',            "TEXT NOT NULL DEFAULT ''" ),
                        array( 'addPgField', 'job',           'job_token_timestamp',  "TIMESTAMPTZ" ),
                        array( 'addPgField', 'job',           'job_sha1',             "TEXT NOT NULL DEFAULT ''" ),
@@ -234,65 +236,66 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgIndex', 'job',           'job_timestamp_idx',      '(job_timestamp)' ),
                        array( 'addPgIndex', 'job',           'job_sha1',               '(job_sha1)' ),
                        array( 'addPgIndex', 'job',           'job_cmd_token',          '(job_cmd, job_token, job_random)' ),
+                       array( 'addPgIndex', 'job',           'job_cmd_token_id',       '(job_cmd, job_token, job_id)' ),
                        array( 'addPgIndex', 'filearchive',   'fa_sha1',                '(fa_sha1)' ),
 
                        array( 'checkIndex', 'pagelink_unique', array(
-                               array('pl_from', 'int4_ops', 'btree', 0),
-                               array('pl_namespace', 'int2_ops', 'btree', 0),
-                               array('pl_title', 'text_ops', 'btree', 0),
+                               array( 'pl_from', 'int4_ops', 'btree', 0 ),
+                               array( 'pl_namespace', 'int2_ops', 'btree', 0 ),
+                               array( 'pl_title', 'text_ops', 'btree', 0 ),
                        ),
                        'CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title)' ),
                        array( 'checkIndex', 'cl_sortkey', array(
-                               array('cl_to', 'text_ops', 'btree', 0),
-                               array('cl_sortkey', 'text_ops', 'btree', 0),
-                               array('cl_from', 'int4_ops', 'btree', 0),
+                               array( 'cl_to', 'text_ops', 'btree', 0 ),
+                               array( 'cl_sortkey', 'text_ops', 'btree', 0 ),
+                               array( 'cl_from', 'int4_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX cl_sortkey ON "categorylinks" USING "btree" ("cl_to", "cl_sortkey", "cl_from")' ),
                        array( 'checkIndex', 'logging_times', array(
-                               array('log_timestamp', 'timestamptz_ops', 'btree', 0),
+                               array( 'log_timestamp', 'timestamptz_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "logging_times" ON "logging" USING "btree" ("log_timestamp")' ),
                        array( 'dropIndex', 'oldimage', 'oi_name' ),
                        array( 'checkIndex', 'oi_name_archive_name', array(
-                               array('oi_name', 'text_ops', 'btree', 0),
-                               array('oi_archive_name', 'text_ops', 'btree', 0),
+                               array( 'oi_name', 'text_ops', 'btree', 0 ),
+                               array( 'oi_archive_name', 'text_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "oi_name_archive_name" ON "oldimage" USING "btree" ("oi_name", "oi_archive_name")' ),
                        array( 'checkIndex', 'oi_name_timestamp', array(
-                               array('oi_name', 'text_ops', 'btree', 0),
-                               array('oi_timestamp', 'timestamptz_ops', 'btree', 0),
+                               array( 'oi_name', 'text_ops', 'btree', 0 ),
+                               array( 'oi_timestamp', 'timestamptz_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "oi_name_timestamp" ON "oldimage" USING "btree" ("oi_name", "oi_timestamp")' ),
                        array( 'checkIndex', 'page_main_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_main_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 0)' ),
                        array( 'checkIndex', 'page_mediawiki_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_mediawiki_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 8)' ),
                        array( 'checkIndex', 'page_project_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_project_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 4)' ),
                        array( 'checkIndex', 'page_talk_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_talk_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 1)' ),
                        array( 'checkIndex', 'page_user_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_user_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 2)' ),
                        array( 'checkIndex', 'page_utalk_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_utalk_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 3)' ),
                        array( 'checkIndex', 'ts2_page_text', array(
-                               array('textvector', 'tsvector_ops', 'gist', 0),
+                               array( 'textvector', 'tsvector_ops', 'gist', 0 ),
                        ),
                        'CREATE INDEX "ts2_page_text" ON "pagecontent" USING "gist" ("textvector")' ),
                        array( 'checkIndex', 'ts2_page_title', array(
-                               array('titlevector', 'tsvector_ops', 'gist', 0),
+                               array( 'titlevector', 'tsvector_ops', 'gist', 0 ),
                        ),
                        'CREATE INDEX "ts2_page_title" ON "page" USING "gist" ("titlevector")' ),
 
@@ -301,10 +304,10 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'checkRevUserFkey' ),
                        array( 'dropIndex', 'ipblocks', 'ipb_address'),
                        array( 'checkIndex', 'ipb_address_unique', array(
-                               array('ipb_address', 'text_ops', 'btree', 0),
-                               array('ipb_user',    'int4_ops', 'btree', 0),
-                               array('ipb_auto',    'int2_ops', 'btree', 0),
-                               array('ipb_anon_only', 'int2_ops', 'btree', 0),
+                               array( 'ipb_address', 'text_ops', 'btree', 0 ),
+                               array( 'ipb_user',    'int4_ops', 'btree', 0 ),
+                               array( 'ipb_auto',    'int2_ops', 'btree', 0 ),
+                               array( 'ipb_anon_only', 'int2_ops', 'btree', 0 ),
                        ),
                        'CREATE UNIQUE INDEX ipb_address_unique ON ipblocks (ipb_address,ipb_user,ipb_auto,ipb_anon_only)' ),
 
@@ -507,7 +510,7 @@ END;
                        $this->output( "Creating sequence $ns\n" );
                        $this->db->query( "CREATE SEQUENCE $ns" );
                        if( $pkey !== false ) {
-                               $this->setDefault( $table,  $pkey, '"nextval"(\'"' . $ns . '"\'::"regclass")' );
+                               $this->setDefault( $table, $pkey, '"nextval"(\'"' . $ns . '"\'::"regclass")' );
                        }
                }
        }
@@ -535,11 +538,34 @@ END;
                }
        }
 
-       protected function renameIndex( $table, $old, $new ) {
-               if ( $this->db->indexExists( $table, $old ) ) {
-                       $this->output( "Renaming index $old to $new\n" );
-                       $this->db->query( "ALTER INDEX $old RENAME TO $new" );
+       protected function renameIndex(
+               $table, $old, $new, $skipBothIndexExistWarning = false, $a = false, $b = false
+       ) {
+               // First requirement: the table must exist
+               if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
+                       $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
+                       return;
+               }
+
+               // Second requirement: the new index must be missing
+               if ( $this->db->indexExists( $table, $new, __METHOD__ ) ) {
+                       $this->output( "...index $new already set on $table table.\n" );
+                       if ( !$skipBothIndexExistWarning
+                               && $this->db->indexExists( $table, $old, __METHOD__ ) )
+                       {
+                               $this->output( "...WARNING: $old still exists, despite it has been renamed into $new (which also exists).\n" .
+                                       "            $old should be manually removed if not needed anymore.\n" );
+                       }
+                       return;
                }
+
+               // Third requirement: the old index must exist
+               if ( !$this->db->indexExists( $table, $old, __METHOD__ ) ) {
+                       $this->output( "...skipping: index $old doesn't exist.\n" );
+                       return;
+               }
+
+               $this->db->query( "ALTER INDEX $old RENAME TO $new" );
        }
 
        protected function addPgField( $table, $field, $type ) {
index 4892770..c080871 100644 (file)
@@ -426,7 +426,7 @@ class WebInstaller extends Installer {
                $url = preg_replace( '/\?.*$/', '', $url );
 
                if ( $query ) {
-                       $url .= '?' . wfArrayToCGI( $query );
+                       $url .= '?' . wfArrayToCgi( $query );
                }
 
                return $url;
@@ -933,7 +933,7 @@ class WebInstaller extends Installer {
         * @return string
         */
        public function getRadioSet( $params ) {
-               if ( !isset( $params['controlName']  ) ) {
+               if ( !isset( $params['controlName'] ) ) {
                        $params['controlName'] = 'config_' . $params['var'];
                }
 
@@ -1079,7 +1079,7 @@ class WebInstaller extends Installer {
                ) );
                $anchor = Html::rawElement( 'a',
                        array( 'href' => $this->getURL( array( 'localsettings' => 1 ) ) ),
-                       $img . ' ' . wfMessage( 'config-download-localsettings' )->escaped() );
+                       $img . ' ' . wfMessage( 'config-download-localsettings' )->parse() );
                return Html::rawElement( 'div', array( 'class' => 'config-download-link' ), $anchor );
        }
 
@@ -1096,7 +1096,7 @@ class WebInstaller extends Installer {
                } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
                        $path = $_SERVER['SCRIPT_NAME'];
                }
-               if ($path !== false) {
+               if ( $path !== false ) {
                        $uri = preg_replace( '{^(.*)/(mw-)?config.*$}', '$1', $path );
                        $this->setVar( 'wgScriptPath', $uri );
                } else {
index f3166c2..42f451f 100644 (file)
@@ -219,7 +219,7 @@ class WebInstallerOutput {
                $dbTypes = $this->parent->getDBTypes();
 
                $this->parent->request->response()->header( 'Content-Type: text/html; charset=utf-8' );
-               if (!$this->allowFrames) {
+               if ( !$this->allowFrames ) {
                        $this->parent->request->response()->header( 'X-Frame-Options: DENY' );
                }
                if ( $this->redirectTarget ) {
@@ -239,7 +239,7 @@ class WebInstallerOutput {
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <title><?php $this->outputTitle(); ?></title>
        <?php echo $this->getCssUrl() . "\n"; ?>
-       <?php echo Html::inlineScript(  "var dbTypes = " . Xml::encodeJsVar( $dbTypes ) ) . "\n"; ?>
+       <?php echo Html::inlineScript( "var dbTypes = " . Xml::encodeJsVar( $dbTypes ) ) . "\n"; ?>
        <?php echo $this->getJQuery() . "\n"; ?>
        <?php echo Html::linkedScript( '../skins/common/config.js' ) . "\n"; ?>
 </head>
index f1340d7..e126c23 100644 (file)
@@ -36,7 +36,7 @@ abstract class WebInstallerPage {
         */
        public $parent;
 
-       public abstract function execute();
+       abstract public function execute();
 
        /**
         * Constructor.
@@ -369,7 +369,7 @@ class WebInstaller_ExistingWiki extends WebInstallerPage {
 
                // Set the relevant variables from LocalSettings.php
                $requiredVars = array( 'wgDBtype' );
-               $status = $this->importVariables( $requiredVars , $vars );
+               $status = $this->importVariables( $requiredVars, $vars );
                $installer = $this->parent->getDBInstaller();
                $status->merge( $this->importVariables( $installer->getGlobalNames(), $vars ) );
                if ( !$status->isOK() ) {
@@ -645,7 +645,7 @@ class WebInstaller_Name extends WebInstallerPage {
                        $this->parent->getTextBox( array(
                                'var' => 'wgSitename',
                                'label' => 'config-site-name',
-                         'help' => $this->parent->getHelpBox( 'config-site-name-help' )
+                               'help' => $this->parent->getHelpBox( 'config-site-name-help' )
                        ) ) .
                        $this->parent->getRadioSet( array(
                                'var' => '_NamespaceType',
@@ -955,7 +955,7 @@ class WebInstaller_Options extends WebInstallerPage {
 
                // We'll hide/show this on demand when the value changes, see config.js.
                $cacheval = $this->getVar( 'wgMainCacheType' );
-               if (!$cacheval) {
+               if ( !$cacheval ) {
                        // We need to set a default here; but don't hardcode it
                        // or we lose it every time we reload the page for validation
                        // or going back!
@@ -1002,7 +1002,7 @@ class WebInstaller_Options extends WebInstallerPage {
                $styleUrl = $server . dirname( dirname( $this->parent->getUrl() ) ) .
                        '/skins/common/config-cc.css';
                $iframeUrl = 'http://creativecommons.org/license/?' .
-                       wfArrayToCGI( array(
+                       wfArrayToCgi( array(
                                'partner' => 'MediaWiki',
                                'exit_url' => $exitUrl,
                                'lang' => $this->getVar( '_UserLang' ),
@@ -1025,7 +1025,7 @@ class WebInstaller_Options extends WebInstallerPage {
                } else {
                        $iframeAttribs['src'] = $this->getCCPartnerUrl();
                }
-               $wrapperStyle = ($this->getVar('_LicenseCode') == 'cc-choose') ? '' : 'display: none';
+               $wrapperStyle = ($this->getVar( '_LicenseCode' ) == 'cc-choose') ? '' : 'display: none';
 
                return
                        "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\" style=\"$wrapperStyle\">\n" .
@@ -1155,12 +1155,12 @@ class WebInstaller_Install extends WebInstallerPage {
                        return 'continue';
                } elseif( $this->parent->request->wasPosted() ) {
                        $this->startForm();
-                       $this->addHTML("<ul>");
+                       $this->addHTML( "<ul>" );
                        $results = $this->parent->performInstallation(
-                               array( $this, 'startStage'),
+                               array( $this, 'startStage' ),
                                array( $this, 'endStage' )
                        );
-                       $this->addHTML("</ul>");
+                       $this->addHTML( "</ul>" );
                        // PerformInstallation bails on a fatal, so make sure the last item
                        // completed before giving 'next.' Likewise, only provide back on failure
                        $lastStep = end( $results );
@@ -1176,7 +1176,7 @@ class WebInstaller_Install extends WebInstallerPage {
        }
 
        public function startStage( $step ) {
-               $this->addHTML( "<li>" . wfMessage( "config-install-$step" )->escaped() . wfMessage( 'ellipsis')->escaped() );
+               $this->addHTML( "<li>" . wfMessage( "config-install-$step" )->escaped() . wfMessage( 'ellipsis' )->escaped() );
                if ( $step == 'extension-tables' ) {
                        $this->startLiveBox();
                }
@@ -1259,7 +1259,7 @@ class WebInstaller_Restart extends WebInstallerPage {
 
 abstract class WebInstaller_Document extends WebInstallerPage {
 
-       protected abstract function getFileName();
+       abstract protected function getFileName();
 
        public  function execute() {
                $text = $this->getFileContents();
@@ -1287,8 +1287,8 @@ class WebInstaller_ReleaseNotes extends WebInstaller_Document {
        protected function getFileName() {
                global $wgVersion;
 
-               if(preg_match( '/^(\d+)\.(\d+).*/i', $wgVersion, $result ) ) {
-                       throw new MWException('Variable $wgVersion has an invalid value.');
+               if( !preg_match( '/^(\d+)\.(\d+).*/i', $wgVersion, $result ) ) {
+                       throw new MWException( 'Variable $wgVersion has an invalid value.' );
                }
 
                return 'RELEASE-NOTES-' . $result[1] . '.' . $result[2];
@@ -1302,4 +1302,3 @@ class WebInstaller_UpgradeDoc extends WebInstaller_Document {
 class WebInstaller_Copying extends WebInstaller_Document {
        protected function getFileName() { return 'COPYING'; }
 }
-
index 849eb86..4003fa8 100644 (file)
@@ -50,7 +50,7 @@ class Interwiki {
         * @param string $prefix Interwiki prefix to use
         * @return bool Whether it exists
         */
-       static public function isValidInterwiki( $prefix ) {
+       public static function isValidInterwiki( $prefix ) {
                $result = self::fetch( $prefix );
                return (bool)$result;
        }
@@ -61,7 +61,7 @@ class Interwiki {
         * @param string $prefix Interwiki prefix to use
         * @return Interwiki|null|bool
         */
-       static public function fetch( $prefix ) {
+       public static function fetch( $prefix ) {
                global $wgContLang;
                if ( $prefix == '' ) {
                        return null;
index 927ca4e..9ec58c9 100644 (file)
@@ -39,6 +39,9 @@ abstract class Job {
                $removeDuplicates,
                $error;
 
+       /** @var Array Additional queue metadata */
+       public $metadata = array();
+
        /*-------------------------------------------------------------------------
         * Abstract functions
         *------------------------------------------------------------------------*/
@@ -80,6 +83,7 @@ abstract class Job {
         * removed later on, when the first one is popped.
         *
         * @param $jobs array of Job objects
+        * @return bool
         * @deprecated 1.21
         */
        public static function batchInsert( $jobs ) {
@@ -94,6 +98,7 @@ abstract class Job {
         * large batches of jobs can cause slave lag.
         *
         * @param $jobs array of Job objects
+        * @return bool
         * @deprecated 1.21
         */
        public static function safeBatchInsert( $jobs ) {
@@ -172,12 +177,19 @@ abstract class Job {
        }
 
        /**
-        * @return bool
+        * @return bool Whether only one of each identical set of jobs should be run
         */
        public function ignoreDuplicates() {
                return $this->removeDuplicates;
        }
 
+       /**
+        * @return bool Whether this job can be retried on failure by job runners
+        */
+       public function allowRetries() {
+               return true;
+       }
+
        /**
         * Subclasses may need to override this to make duplication detection work
         *
@@ -242,6 +254,16 @@ abstract class Job {
                                if ( $paramString != '' ) {
                                        $paramString .= ' ';
                                }
+                               if ( is_array( $value ) ) {
+                                       $value = "array(" . count( $value ) . ")";
+                               } elseif ( is_object( $value ) && !method_exists( $value, '__toString' ) ) {
+                                       $value = "object(" . get_class( $value ) . ")";
+                               }
+                               $value = (string)$value;
+                               if ( mb_strlen( $value ) > 1024 ) {
+                                       $value = "string(" . mb_strlen( $value ) . ")";
+                               }
+
                                $paramString .= "$key=$value";
                        }
                }
index 17f6648..4996a9e 100644 (file)
@@ -33,6 +33,7 @@ abstract class JobQueue {
        protected $type; // string; job type
        protected $order; // string; job priority for pop()
        protected $claimTTL; // integer; seconds
+       protected $maxTries; // integer; maximum number of times to try a job
 
        const QoS_Atomic = 1; // integer; "all-or-nothing" job insertions
 
@@ -44,6 +45,7 @@ abstract class JobQueue {
                $this->type     = $params['type'];
                $this->order    = isset( $params['order'] ) ? $params['order'] : 'random';
                $this->claimTTL = isset( $params['claimTTL'] ) ? $params['claimTTL'] : 0;
+               $this->maxTries = isset( $params['maxTries'] ) ? $params['maxTries'] : 3;
        }
 
        /**
@@ -60,8 +62,12 @@ abstract class JobQueue {
         *                by timestamp, allowing for some jobs to be popped off out of order.
         *                If "random" is used, pop() will pick jobs in random order. This might be
         *                useful for improving concurrency depending on the queue storage medium.
+        *                Note that "random" really means "don't care", so it may actually be FIFO
+        *                or only weakly random (e.g. pop() takes one of the first X jobs randomly).
         *   - claimTTL : If supported, the queue will recycle jobs that have been popped
-        *                but not acknowledged as completed after this many seconds.
+        *                but not acknowledged as completed after this many seconds. Recycling
+        *                of jobs simple means re-inserting them into the queue. Jobs can be
+        *                attempted up to three times before being discarded.
         *
         * Queue classes should throw an exception if they do not support the options given.
         *
@@ -100,6 +106,7 @@ abstract class JobQueue {
         * Queue classes should use caching if they are any slower without memcached.
         *
         * @return bool
+        * @throws MWException
         */
        final public function isEmpty() {
                wfProfileIn( __METHOD__ );
@@ -119,6 +126,7 @@ abstract class JobQueue {
         * Queue classes should use caching if they are any slower without memcached.
         *
         * @return integer
+        * @throws MWException
         */
        final public function getSize() {
                wfProfileIn( __METHOD__ );
@@ -138,6 +146,7 @@ abstract class JobQueue {
         * Queue classes should use caching if they are any slower without memcached.
         *
         * @return integer
+        * @throws MWException
         */
        final public function getAcquiredCount() {
                wfProfileIn( __METHOD__ );
@@ -155,33 +164,37 @@ abstract class JobQueue {
        /**
         * Push a single jobs into the queue.
         * This does not require $wgJobClasses to be set for the given job type.
+        * Outside callers should use JobQueueGroup::push() instead of this function.
         *
         * @param $jobs Job|Array
         * @param $flags integer Bitfield (supports JobQueue::QoS_Atomic)
-        * @throws MWException
         * @return bool Returns false on failure
+        * @throws MWException
         */
        final public function push( $jobs, $flags = 0 ) {
-               $jobs = is_array( $jobs ) ? $jobs : array( $jobs );
-
-               return $this->batchPush( $jobs, $flags );
+               return $this->batchPush( is_array( $jobs ) ? $jobs : array( $jobs ), $flags );
        }
 
        /**
         * Push a batch of jobs into the queue.
         * This does not require $wgJobClasses to be set for the given job type.
+        * Outside callers should use JobQueueGroup::push() instead of this function.
         *
         * @param $jobs array List of Jobs
         * @param $flags integer Bitfield (supports JobQueue::QoS_Atomic)
-        * @throws MWException
         * @return bool Returns false on failure
+        * @throws MWException
         */
        final public function batchPush( array $jobs, $flags = 0 ) {
+               if ( !count( $jobs ) ) {
+                       return true; // nothing to do
+               }
                foreach ( $jobs as $job ) {
                        if ( $job->getType() !== $this->type ) {
                                throw new MWException( "Got '{$job->getType()}' job; expected '{$this->type}'." );
                        }
                }
+
                wfProfileIn( __METHOD__ );
                $ok = $this->doBatchPush( $jobs, $flags );
                wfProfileOut( __METHOD__ );
@@ -197,10 +210,21 @@ abstract class JobQueue {
        /**
         * Pop a job off of the queue.
         * This requires $wgJobClasses to be set for the given job type.
+        * Outside callers should use JobQueueGroup::pop() instead of this function.
         *
-        * @return Job|bool Returns false on failure
+        * @return Job|bool Returns false if there are no jobs
+        * @throws MWException
         */
        final public function pop() {
+               global $wgJobClasses;
+
+               if ( $this->wiki !== wfWikiID() ) {
+                       throw new MWException( "Cannot pop '{$this->type}' job off foreign wiki queue." );
+               } elseif ( !isset( $wgJobClasses[$this->type] ) ) {
+                       // Do not pop jobs if there is no class for the queue type
+                       throw new MWException( "Unrecognized job type '{$this->type}'." );
+               }
+
                wfProfileIn( __METHOD__ );
                $job = $this->doPop();
                wfProfileOut( __METHOD__ );
@@ -217,10 +241,11 @@ abstract class JobQueue {
         * Acknowledge that a job was completed.
         *
         * This does nothing for certain queue classes or if "claimTTL" is not set.
+        * Outside callers should use JobQueueGroup::ack() instead of this function.
         *
         * @param $job Job
-        * @throws MWException
         * @return bool
+        * @throws MWException
         */
        final public function ack( Job $job ) {
                if ( $job->getType() !== $this->type ) {
@@ -266,8 +291,8 @@ abstract class JobQueue {
         * This does nothing for certain queue classes.
         *
         * @param $job Job
-        * @throws MWException
         * @return bool
+        * @throws MWException
         */
        final public function deduplicateRootJob( Job $job ) {
                if ( $job->getType() !== $this->type ) {
@@ -294,6 +319,7 @@ abstract class JobQueue {
         * This does nothing for certain queue classes.
         *
         * @return void
+        * @throws MWException
         */
        final public function waitForBackups() {
                wfProfileIn( __METHOD__ );
@@ -306,4 +332,60 @@ abstract class JobQueue {
         * @return void
         */
        protected function doWaitForBackups() {}
+
+       /**
+        * Return a map of task names to task definition maps.
+        * A "task" is a fast periodic queue maintenance action.
+        * Mutually exclusive tasks must implement their own locking in the callback.
+        *
+        * Each task value is an associative array with:
+        *   - name     : the name of the task
+        *   - callback : a PHP callable that performs the task
+        *   - period   : the period in seconds corresponding to the task frequency
+        *
+        * @return Array
+        */
+       final public function getPeriodicTasks() {
+               $tasks = $this->doGetPeriodicTasks();
+               foreach ( $tasks as $name => &$def ) {
+                       $def['name'] = $name;
+               }
+               return $tasks;
+       }
+
+       /**
+        * @see JobQueue::getPeriodicTasks()
+        * @return Array
+        */
+       protected function doGetPeriodicTasks() {
+               return array();
+       }
+
+       /**
+        * Clear any process and persistent caches
+        *
+        * @return void
+        */
+       final public function flushCaches() {
+               wfProfileIn( __METHOD__ );
+               $this->doFlushCaches();
+               wfProfileOut( __METHOD__ );
+       }
+
+       /**
+        * @see JobQueue::flushCaches()
+        * @return void
+        */
+       protected function doFlushCaches() {}
+
+       /**
+        * Namespace the queue with a key to isolate it for testing
+        *
+        * @param $key string
+        * @return void
+        * @throws MWException
+        */
+       public function setTestingPrefix( $key ) {
+               throw new MWException( "Queue namespacing not supported for this queue type." );
+       }
 }
diff --git a/includes/job/JobQueueAggregator.php b/includes/job/JobQueueAggregator.php
new file mode 100644 (file)
index 0000000..3dba3c5
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Job queue aggregator code.
+ *
+ * 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
+ */
+
+/**
+ * Class to handle tracking information about all queues
+ *
+ * @ingroup JobQueue
+ * @since 1.21
+ */
+abstract class JobQueueAggregator {
+       /** @var JobQueueAggregator */
+       protected static $instance = null;
+
+       /**
+        * @param array $params
+        */
+       protected function __construct( array $params ) {}
+
+       /**
+        * @return JobQueueAggregator
+        */
+       final public static function singleton() {
+               global $wgJobQueueAggregator;
+
+               if ( !isset( self::$instance ) ) {
+                       $class = $wgJobQueueAggregator['class'];
+                       $obj = new $class( $wgJobQueueAggregator );
+                       if ( !( $obj instanceof JobQueueAggregator ) ) {
+                               throw new MWException( "Class '$class' is not a JobQueueAggregator class." );
+                       }
+                       self::$instance = $obj;
+               }
+
+               return self::$instance;
+       }
+
+       /**
+        * Destroy the singleton instance
+        *
+        * @return void
+        */
+       final public static function destroySingleton() {
+               self::$instance = null;
+       }
+
+       /**
+        * Mark a queue as being empty
+        *
+        * @param string $wiki
+        * @param string $type
+        * @return bool Success
+        */
+       final public function notifyQueueEmpty( $wiki, $type ) {
+               wfProfileIn( __METHOD__ );
+               $ok = $this->doNotifyQueueEmpty( $wiki, $type );
+               wfProfileOut( __METHOD__ );
+               return $ok;
+       }
+
+       /**
+        * @see JobQueueAggregator::notifyQueueEmpty()
+        */
+       abstract protected function doNotifyQueueEmpty( $wiki, $type );
+
+       /**
+        * Mark a queue as being non-empty
+        *
+        * @param string $wiki
+        * @param string $type
+        * @return bool Success
+        */
+       final public function notifyQueueNonEmpty( $wiki, $type ) {
+               wfProfileIn( __METHOD__ );
+               $ok = $this->doNotifyQueueNonEmpty( $wiki, $type );
+               wfProfileOut( __METHOD__ );
+               return $ok;
+       }
+
+       /**
+        * @see JobQueueAggregator::notifyQueueNonEmpty()
+        */
+       abstract protected function doNotifyQueueNonEmpty( $wiki, $type );
+
+       /**
+        * Get the list of all of the queues with jobs
+        *
+        * @return Array (job type => (list of wiki IDs))
+        */
+       final public function getAllReadyWikiQueues() {
+               wfProfileIn( __METHOD__ );
+               $res = $this->doGetAllReadyWikiQueues();
+               wfProfileOut( __METHOD__ );
+               return $res;
+       }
+
+       /**
+        * @see JobQueueAggregator::getAllReadyWikiQueues()
+        */
+       abstract protected function doGetAllReadyWikiQueues();
+
+       /**
+        * Get all databases that have a pending job.
+        * This poll all the queues and is this expensive.
+        *
+        * @return Array (job type => (list of wiki IDs))
+        */
+       protected function findPendingWikiQueues() {
+               global $wgLocalDatabases;
+
+               $pendingDBs = array(); // (job type => (db list))
+               foreach ( $wgLocalDatabases as $db ) {
+                       foreach ( JobQueueGroup::singleton( $db )->getQueuesWithJobs() as $type ) {
+                               $pendingDBs[$type][] = $db;
+                       }
+               }
+
+               return $pendingDBs;
+       }
+}
diff --git a/includes/job/JobQueueAggregatorMemc.php b/includes/job/JobQueueAggregatorMemc.php
new file mode 100644 (file)
index 0000000..4b82cf9
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Job queue aggregator code that uses BagOStuff.
+ *
+ * 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
+ */
+
+/**
+ * Class to handle tracking information about all queues using BagOStuff
+ *
+ * @ingroup JobQueue
+ * @since 1.21
+ */
+class JobQueueAggregatorMemc extends JobQueueAggregator {
+       /** @var BagOStuff */
+       protected $cache;
+
+       protected $cacheTTL; // integer; seconds
+
+       /**
+        * @params include:
+        *   - objectCache : Name of an object cache registered in $wgObjectCaches.
+        *                   This defaults to the one specified by $wgMainCacheType.
+        *   - cacheTTL    : Seconds to cache the aggregate data before regenerating.
+        * @param array $params
+        */
+       protected function __construct( array $params ) {
+               parent::__construct( $params );
+               $this->cache = isset( $params['objectCache'] )
+                       ? wfGetCache( $params['objectCache'] )
+                       : wfGetMainCache();
+               $this->cacheTTL = isset( $params['cacheTTL'] ) ? $params['cacheTTL'] : 180; // 3 min
+       }
+
+       /**
+        * @see JobQueueAggregator::doNotifyQueueEmpty()
+        */
+       protected function doNotifyQueueEmpty( $wiki, $type ) {
+               $key = $this->getReadyQueueCacheKey();
+               // Delist the queue from the "ready queue" list
+               if ( $this->cache->add( "$key:lock", 1, 60 ) ) { // lock
+                       $curInfo = $this->cache->get( $key );
+                       if ( is_array( $curInfo ) && isset( $curInfo['pendingDBs'][$type] ) ) {
+                               if ( in_array( $wiki, $curInfo['pendingDBs'][$type] ) ) {
+                                       $curInfo['pendingDBs'][$type] = array_diff(
+                                               $curInfo['pendingDBs'][$type], array( $wiki ) );
+                                       $this->cache->set( $key, $curInfo );
+                               }
+                       }
+                       $this->cache->delete( "$key:lock" ); // unlock
+               }
+               return true;
+       }
+
+       /**
+        * @see JobQueueAggregator::doNotifyQueueNonEmpty()
+        */
+       protected function doNotifyQueueNonEmpty( $wiki, $type ) {
+               return true; // updated periodically
+       }
+
+       /**
+        * @see JobQueueAggregator::doAllGetReadyWikiQueues()
+        */
+       protected function doGetAllReadyWikiQueues() {
+               $key = $this->getReadyQueueCacheKey();
+               // If the cache entry wasn't present, is stale, or in .1% of cases otherwise,
+               // regenerate the cache. Use any available stale cache if another process is
+               // currently regenerating the pending DB information.
+               $pendingDbInfo = $this->cache->get( $key );
+               if ( !is_array( $pendingDbInfo )
+                       || ( time() - $pendingDbInfo['timestamp'] ) > $this->cacheTTL
+                       || mt_rand( 0, 999 ) == 0
+               ) {
+                       if ( $this->cache->add( "$key:rebuild", 1, 1800 ) ) { // lock
+                               $pendingDbInfo = array(
+                                       'pendingDBs' => $this->findPendingWikiQueues(),
+                                       'timestamp'  => time()
+                               );
+                               for ( $attempts=1; $attempts <= 25; ++$attempts ) {
+                                       if ( $this->cache->add( "$key:lock", 1, 60 ) ) { // lock
+                                               $this->cache->set( $key, $pendingDbInfo );
+                                               $this->cache->delete( "$key:lock" ); // unlock
+                                               break;
+                                       }
+                               }
+                               $this->cache->delete( "$key:rebuild" ); // unlock
+                       }
+               }
+               return is_array( $pendingDbInfo )
+                       ? $pendingDbInfo['pendingDBs']
+                       : array(); // cache is both empty and locked
+       }
+
+       /**
+        * @return string
+        */
+       private function getReadyQueueCacheKey() {
+               return "jobqueue:aggregator:ready-queues:v1"; // global
+       }
+}
diff --git a/includes/job/JobQueueAggregatorRedis.php b/includes/job/JobQueueAggregatorRedis.php
new file mode 100644 (file)
index 0000000..74e9171
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Job queue aggregator code that uses PhpRedis.
+ *
+ * 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
+ */
+
+/**
+ * Class to handle tracking information about all queues using PhpRedis
+ *
+ * @ingroup JobQueue
+ * @since 1.21
+ */
+class JobQueueAggregatorRedis extends JobQueueAggregator {
+       /** @var RedisConnectionPool */
+       protected $redisPool;
+
+       /**
+        * @params include:
+        *   - redisConfig : An array of parameters to RedisConnectionPool::__construct().
+        *   - redisServer : A hostname/port combination or the absolute path of a UNIX socket.
+        *                   If a hostname is specified but no port, the standard port number
+        *                   6379 will be used. Required.
+        * @param array $params
+        */
+       protected function __construct( array $params ) {
+               parent::__construct( $params );
+               $this->server = $params['redisServer'];
+               $this->redisPool = RedisConnectionPool::singleton( $params['redisConfig'] );
+       }
+
+       /**
+        * @see JobQueueAggregator::doNotifyQueueEmpty()
+        */
+       protected function doNotifyQueueEmpty( $wiki, $type ) {
+               $conn = $this->getConnection();
+               if ( !$conn ) {
+                       return false;
+               }
+               try {
+                       $conn->hDel( $this->getReadyQueueKey(), $this->encQueueName( $type, $wiki ) );
+                       return true;
+               } catch ( RedisException $e ) {
+                       $this->handleException( $conn, $e );
+                       return false;
+               }
+       }
+
+       /**
+        * @see JobQueueAggregator::doNotifyQueueNonEmpty()
+        */
+       protected function doNotifyQueueNonEmpty( $wiki, $type ) {
+               $conn = $this->getConnection();
+               if ( !$conn ) {
+                       return false;
+               }
+               try {
+                       $conn->hSet( $this->getReadyQueueKey(), $this->encQueueName( $type, $wiki ), time() );
+                       return true;
+               } catch ( RedisException $e ) {
+                       $this->handleException( $conn, $e );
+                       return false;
+               }
+       }
+
+       /**
+        * @see JobQueueAggregator::doAllGetReadyWikiQueues()
+        */
+       protected function doGetAllReadyWikiQueues() {
+               $conn = $this->getConnection();
+               if ( !$conn ) {
+                       return array();
+               }
+               try {
+                       $conn->multi( Redis::PIPELINE );
+                       $conn->exists( $this->getReadyQueueKey() );
+                       $conn->hGetAll( $this->getReadyQueueKey() );
+                       list( $exists, $map ) = $conn->exec();
+
+                       if ( $exists ) { // cache hit
+                               $pendingDBs = array(); // (type => list of wikis)
+                               foreach ( $map as $key => $time ) {
+                                       list( $type, $wiki ) = $this->dencQueueName( $key );
+                                       $pendingDBs[$type][] = $wiki;
+                               }
+                       } else { // cache miss
+                               $pendingDBs = $this->findPendingWikiQueues(); // (type => list of wikis)
+
+                               $now = time();
+                               $map = array();
+                               foreach ( $pendingDBs as $type => $wikis ) {
+                                       foreach ( $wikis as $wiki ) {
+                                               $map[$this->encQueueName( $type, $wiki )] = $now;
+                                       }
+                               }
+                               $conn->hMSet( $this->getReadyQueueKey(), $map );
+                       }
+
+                       return $pendingDBs;
+               } catch ( RedisException $e ) {
+                       $this->handleException( $conn, $e );
+                       return array();
+               }
+       }
+
+       /**
+        * Get a connection to the server that handles all sub-queues for this queue
+        *
+        * @return Array (server name, Redis instance)
+        * @throws MWException
+        */
+       protected function getConnection() {
+               return $this->redisPool->getConnection( $this->server );
+       }
+
+       /**
+        * @param RedisConnRef $conn
+        * @param RedisException $e
+        * @return void
+        */
+       protected function handleException( RedisConnRef $conn, $e ) {
+               $this->redisPool->handleException( $this->server, $conn, $e );
+       }
+
+       /**
+        * @return string
+        */
+       private function getReadyQueueKey() {
+               return "jobqueue:aggregator:h-ready-queues:v1"; // global
+       }
+
+       /**
+        * @param string $type
+        * @param string $wiki
+        * @return string
+        */
+       private function encQueueName( $type, $wiki ) {
+               return rawurlencode( $type ) . '/' . rawurlencode( $wiki );
+       }
+
+       /**
+        * @param string $name
+        * @return string
+        */
+       private function dencQueueName( $name ) {
+               list( $type, $wiki ) = explode( '/', $name, 2 );
+               return array( rawurldecode( $type ), rawurldecode( $wiki ) );
+       }
+}
index 1c9c8a7..fd64895 100644 (file)
  * @since 1.21
  */
 class JobQueueDB extends JobQueue {
+       const ROOTJOB_TTL     = 1209600; // integer; seconds to remember root jobs (14 days)
        const CACHE_TTL_SHORT = 30; // integer; seconds to cache info without re-validating
        const CACHE_TTL_LONG  = 300; // integer; seconds to cache info that is kept up to date
        const MAX_AGE_PRUNE   = 604800; // integer; seconds a job can live once claimed
-       const MAX_ATTEMPTS    = 3; // integer; number of times to try a job
        const MAX_JOB_RANDOM  = 2147483647; // integer; 2^31 - 1, used for job_random
        const MAX_OFFSET      = 255; // integer; maximum number of rows to skip
 
@@ -106,6 +106,10 @@ class JobQueueDB extends JobQueue {
        protected function doGetAcquiredCount() {
                global $wgMemc;
 
+               if ( $this->claimTTL <= 0 ) {
+                       return 0; // no acknowledgements
+               }
+
                $key = $this->getCacheKey( 'acquiredcount' );
 
                $count = $wgMemc->get( $key );
@@ -115,7 +119,7 @@ class JobQueueDB extends JobQueue {
 
                list( $dbr, $scope ) = $this->getSlaveDB();
                $count = (int)$dbr->selectField( 'job', 'COUNT(*)',
-                       array( 'job_cmd' => $this->type, "job_token !={$dbr->addQuotes('')}" ),
+                       array( 'job_cmd' => $this->type, "job_token != {$dbr->addQuotes( '' )}" ),
                        __METHOD__
                );
                $wgMemc->set( $key, $count, self::CACHE_TTL_SHORT );
@@ -146,12 +150,11 @@ class JobQueueDB extends JobQueue {
                                }
                        }
 
+                       $key = $this->getCacheKey( 'empty' );
                        $atomic = ( $flags & self::QoS_Atomic );
-                       $key    = $this->getCacheKey( 'empty' );
-                       $ttl    = self::CACHE_TTL_LONG;
 
                        $dbw->onTransactionIdle(
-                               function() use ( $dbw, $rowSet, $rowList, $atomic, $key, $ttl, $scope
+                               function() use ( $dbw, $rowSet, $rowList, $atomic, $key, $scope
                        ) {
                                global $wgMemc;
 
@@ -193,7 +196,7 @@ class JobQueueDB extends JobQueue {
                                        $dbw->commit( __METHOD__ );
                                }
 
-                               $wgMemc->set( $key, 'false', $ttl ); // queue is not empty
+                               $wgMemc->set( $key, 'false', JobQueueDB::CACHE_TTL_LONG );
                        } );
                }
 
@@ -216,10 +219,6 @@ class JobQueueDB extends JobQueue {
 
                $uuid = wfRandomString( 32 ); // pop attempt
                $job = false; // job popped off
-               // Occasionally recycle jobs back into the queue that have been claimed too long
-               if ( mt_rand( 0, 99 ) == 0 ) {
-                       $this->recycleStaleJobs();
-               }
                do { // retry when our row is invalid or deleted as a duplicate
                        // Try to reserve a row in the DB...
                        if ( in_array( $this->order, array( 'fifo', 'timestamp' ) ) ) {
@@ -402,8 +401,10 @@ class JobQueueDB extends JobQueue {
         *
         * @return integer Number of jobs recycled/deleted
         */
-       protected function recycleStaleJobs() {
-               $now   = time();
+       public function recycleAndDeleteStaleJobs() {
+               global $wgMemc;
+
+               $now = time();
                list( $dbw, $scope ) = $this->getMasterDB();
                $count = 0; // affected rows
 
@@ -422,7 +423,7 @@ class JobQueueDB extends JobQueue {
                                        'job_cmd' => $this->type,
                                        "job_token != {$dbw->addQuotes( '' )}", // was acquired
                                        "job_token_timestamp < {$dbw->addQuotes( $claimCutoff )}", // stale
-                                       "job_attempts < {$dbw->addQuotes( self::MAX_ATTEMPTS )}" ), // retries left
+                                       "job_attempts < {$dbw->addQuotes( $this->maxTries )}" ), // retries left
                                __METHOD__
                        );
                        $ids = array_map( function( $o ) { return $o->job_id; }, iterator_to_array( $res ) );
@@ -440,6 +441,7 @@ class JobQueueDB extends JobQueue {
                                );
                                $count += $dbw->affectedRows();
                                wfIncrStats( 'job-recycle', $dbw->affectedRows() );
+                               $wgMemc->set( $this->getCacheKey( 'empty' ), 'false', self::CACHE_TTL_LONG );
                        }
                }
 
@@ -451,7 +453,7 @@ class JobQueueDB extends JobQueue {
                        "job_token_timestamp < {$dbw->addQuotes( $pruneCutoff )}" // stale
                );
                if ( $this->claimTTL > 0 ) { // only prune jobs attempted too many times...
-                       $conds[] = "job_attempts >= {$dbw->addQuotes( self::MAX_ATTEMPTS )}";
+                       $conds[] = "job_attempts >= {$dbw->addQuotes( $this->maxTries )}";
                }
                // Get the IDs of jobs that are considered stale and should be removed. Selecting
                // the IDs first means that the UPDATE can be done by primary key (less deadlocks).
@@ -517,7 +519,7 @@ class JobQueueDB extends JobQueue {
                        }
 
                        // Update the timestamp of the last root job started at the location...
-                       return $wgMemc->set( $key, $params['rootJobTimestamp'], 14*86400 ); // 2 weeks
+                       return $wgMemc->set( $key, $params['rootJobTimestamp'], JobQueueDB::ROOTJOB_TTL );
                } );
 
                return true;
@@ -555,6 +557,29 @@ class JobQueueDB extends JobQueue {
                wfWaitForSlaves();
        }
 
+       /**
+        * @return Array
+        */
+       protected function doGetPeriodicTasks() {
+               return array(
+                       'recycleAndDeleteStaleJobs' => array(
+                               'callback' => array( $this, 'recycleAndDeleteStaleJobs' ),
+                               'period'   => ceil( $this->claimTTL / 2 )
+                       )
+               );
+       }
+
+       /**
+        * @return void
+        */
+       protected function doFlushCaches() {
+               global $wgMemc;
+
+               foreach ( array( 'empty', 'size', 'acquiredcount' ) as $type ) {
+                       $wgMemc->delete( $this->getCacheKey( $type ) );
+               }
+       }
+
        /**
         * @return Array (DatabaseBase, ScopedCallback)
         */
index cf0215b..23a5494 100644 (file)
@@ -39,16 +39,18 @@ class JobQueueGroup {
        const TYPE_DEFAULT = 1; // integer; jobs popped by default
        const TYPE_ANY     = 2; // integer; any job
 
-       const USE_CACHE = 1; // integer; use process cache
+       const USE_CACHE = 1; // integer; use process or persistent cache
 
        const PROC_CACHE_TTL = 15; // integer; seconds
 
+       const CACHE_VERSION = 1; // integer; cache version
+
        /**
         * @param $wiki string Wiki ID
         */
        protected function __construct( $wiki ) {
                $this->wiki = $wiki;
-               $this->cache = new ProcessCacheLRU( 1 );
+               $this->cache = new ProcessCacheLRU( 10 );
        }
 
        /**
@@ -73,8 +75,10 @@ class JobQueueGroup {
        }
 
        /**
+        * Get the job queue object for a given queue type
+        *
         * @param $type string
-        * @return JobQueue Job queue object for a given queue type
+        * @return JobQueue
         */
        public function get( $type ) {
                global $wgJobTypeConf;
@@ -91,7 +95,9 @@ class JobQueueGroup {
 
        /**
         * Insert jobs into the respective queues of with the belong.
-        * This inserts the jobs into the queue specified by $wgJobTypeConf.
+        *
+        * This inserts the jobs into the queue specified by $wgJobTypeConf
+        * and updates the aggregate job queue information cache as needed.
         *
         * @param $jobs Job|array A single Job or a list of Jobs
         * @throws MWException
@@ -111,7 +117,9 @@ class JobQueueGroup {
 
                $ok = true;
                foreach ( $jobsByType as $type => $jobs ) {
-                       if ( !$this->get( $type )->push( $jobs ) ) {
+                       if ( $this->get( $type )->push( $jobs ) ) {
+                               JobQueueAggregator::singleton()->notifyQueueNonEmpty( $this->wiki, $type );
+                       } else {
                                $ok = false;
                        }
                }
@@ -129,35 +137,47 @@ class JobQueueGroup {
        /**
         * Pop a job off one of the job queues
         *
-        * @param $queueType integer JobQueueGroup::TYPE_* constant
+        * This pops a job off a queue as specified by $wgJobTypeConf and
+        * updates the aggregate job queue information cache as needed.
+        *
+        * @param $qtype integer|string JobQueueGroup::TYPE_DEFAULT or type string
         * @param $flags integer Bitfield of JobQueueGroup::USE_* constants
         * @return Job|bool Returns false on failure
         */
-       public function pop( $queueType = self::TYPE_DEFAULT, $flags = 0 ) {
-               if ( $flags & self::USE_CACHE ) {
-                       if ( !$this->cache->has( 'queues-ready', 'list', self::PROC_CACHE_TTL ) ) {
-                               $this->cache->set( 'queues-ready', 'list', $this->getQueuesWithJobs() );
+       public function pop( $qtype = self::TYPE_DEFAULT, $flags = 0 ) {
+               if ( is_string( $qtype ) ) { // specific job type
+                       $job = $this->get( $qtype )->pop();
+                       if ( !$job ) {
+                               JobQueueAggregator::singleton()->notifyQueueEmpty( $this->wiki, $qtype );
+                       }
+                       return $job;
+               } else { // any job in the "default" jobs types
+                       if ( $flags & self::USE_CACHE ) {
+                               if ( !$this->cache->has( 'queues-ready', 'list', self::PROC_CACHE_TTL ) ) {
+                                       $this->cache->set( 'queues-ready', 'list', $this->getQueuesWithJobs() );
+                               }
+                               $types = $this->cache->get( 'queues-ready', 'list' );
+                       } else {
+                               $types = $this->getQueuesWithJobs();
                        }
-                       $types = $this->cache->get( 'queues-ready', 'list' );
-               } else {
-                       $types = $this->getQueuesWithJobs();
-               }
 
-               if ( $queueType == self::TYPE_DEFAULT ) {
-                       $types = array_intersect( $types, $this->getDefaultQueueTypes() );
-               }
-               shuffle( $types ); // avoid starvation
+                       if ( $qtype == self::TYPE_DEFAULT ) {
+                               $types = array_intersect( $types, $this->getDefaultQueueTypes() );
+                       }
+                       shuffle( $types ); // avoid starvation
 
-               foreach ( $types as $type ) { // for each queue...
-                       $job = $this->get( $type )->pop();
-                       if ( $job ) { // found
-                               return $job;
-                       } else { // not found
-                               $this->cache->clear( 'queues-ready' );
+                       foreach ( $types as $type ) { // for each queue...
+                               $job = $this->get( $type )->pop();
+                               if ( $job ) { // found
+                                       return $job;
+                               } else { // not found
+                                       JobQueueAggregator::singleton()->notifyQueueEmpty( $this->wiki, $type );
+                                       $this->cache->clear( 'queues-ready' );
+                               }
                        }
-               }
 
-               return false; // no jobs found
+                       return false; // no jobs found
+               }
        }
 
        /**
@@ -187,9 +207,7 @@ class JobQueueGroup {
         * @return array List of strings
         */
        public function getQueueTypes() {
-               global $wgJobClasses;
-
-               return array_keys( $wgJobClasses );
+               return array_keys( $this->getCachedConfigVar( 'wgJobClasses' ) );
        }
 
        /**
@@ -204,6 +222,8 @@ class JobQueueGroup {
        }
 
        /**
+        * Get the list of job types that have non-empty queues
+        *
         * @return Array List of job types that have non-empty queues
         */
        public function getQueuesWithJobs() {
@@ -217,15 +237,79 @@ class JobQueueGroup {
        }
 
        /**
-        * @return Array List of default job types that have non-empty queues
+        * Execute any due periodic queue maintenance tasks for all queues.
+        *
+        * A task is "due" if the time ellapsed since the last run is greater than
+        * the defined run period. Concurrent calls to this function will cause tasks
+        * to be attempted twice, so they may need their own methods of mutual exclusion.
+        *
+        * @return integer Number of tasks run
         */
-       public function getDefaultQueuesWithJobs() {
-               $types = array();
-               foreach ( $this->getDefaultQueueTypes() as $type ) {
-                       if ( !$this->get( $type )->isEmpty() ) {
-                               $types[] = $type;
+       public function executeReadyPeriodicTasks() {
+               global $wgMemc;
+
+               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+               $key = wfForeignMemcKey( $db, $prefix, 'jobqueuegroup', 'taskruns', 'v1' );
+               $lastRuns = $wgMemc->get( $key ); // (queue => task => UNIX timestamp)
+
+               $count = 0;
+               $tasksRun = array(); // (queue => task => UNIX timestamp)
+               foreach ( $this->getQueueTypes() as $type ) {
+                       $queue = $this->get( $type );
+                       foreach ( $queue->getPeriodicTasks() as $task => $definition ) {
+                               if ( $definition['period'] <= 0 ) {
+                                       continue; // disabled
+                               } elseif ( !isset( $lastRuns[$type][$task] )
+                                       || $lastRuns[$type][$task] < ( time() - $definition['period'] ) )
+                               {
+                                       if ( call_user_func( $definition['callback'] ) !== null ) {
+                                               $tasksRun[$type][$task] = time();
+                                               ++$count;
+                                       }
+                               }
+                       }
+               }
+
+               $wgMemc->merge( $key, function( $cache, $key, $lastRuns ) use ( $tasksRun ) {
+                       if ( is_array( $lastRuns ) ) {
+                               foreach ( $tasksRun as $type => $tasks ) {
+                                       foreach ( $tasks as $task => $timestamp ) {
+                                               if ( !isset( $lastRuns[$type][$task] )
+                                                       || $timestamp > $lastRuns[$type][$task] )
+                                               {
+                                                       $lastRuns[$type][$task] = $timestamp;
+                                               }
+                                       }
+                               }
+                       } else {
+                               $lastRuns = $tasksRun;
+                       }
+                       return $lastRuns;
+               } );
+
+               return $count;
+       }
+
+       /**
+        * @param $name string
+        * @return mixed
+        */
+       private function getCachedConfigVar( $name ) {
+               global $wgConf, $wgMemc;
+
+               if ( $this->wiki === wfWikiID() ) {
+                       return $GLOBALS[$name]; // common case
+               } else {
+                       list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+                       $key = wfForeignMemcKey( $db, $prefix, 'configvalue', $name );
+                       $value = $wgMemc->get( $key ); // ('v' => ...) or false
+                       if ( is_array( $value ) ) {
+                               return $value['v'];
+                       } else {
+                               $value = $wgConf->getConfig( $this->wiki, $name );
+                               $wgMemc->set( $key, array( 'v' => $value ), 86400 + mt_rand( 0, 86400 ) );
+                               return $value;
                        }
                }
-               return $types;
        }
 }
diff --git a/includes/job/JobQueueRedis.php b/includes/job/JobQueueRedis.php
new file mode 100644 (file)
index 0000000..2ce47bb
--- /dev/null
@@ -0,0 +1,617 @@
+<?php
+/**
+ * Redis-backed job queue code.
+ *
+ * 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
+ */
+
+/**
+ * Class to handle job queues stored in Redis
+ *
+ * @ingroup JobQueue
+ * @since 1.21
+ */
+class JobQueueRedis extends JobQueue {
+       /** @var RedisConnectionPool */
+       protected $redisPool;
+
+       protected $server; // string; server address
+
+       const ROOTJOB_TTL   = 1209600; // integer; seconds to remember root jobs (14 days)
+       const MAX_AGE_PRUNE = 604800; // integer; seconds a job can live once claimed (7 days)
+
+       protected $key; // string; key to prefix the queue keys with (used for testing)
+
+       /**
+        * @params include:
+        *   - redisConfig : An array of parameters to RedisConnectionPool::__construct().
+        *   - redisServer : A hostname/port combination or the absolute path of a UNIX socket.
+        *                   If a hostname is specified but no port, the standard port number
+        *                   6379 will be used. Required.
+        * @param array $params
+        */
+       public function __construct( array $params ) {
+               parent::__construct( $params );
+               $this->server = $params['redisServer'];
+               $this->redisPool = RedisConnectionPool::singleton( $params['redisConfig'] );
+       }
+
+       /**
+        * @see JobQueue::doIsEmpty()
+        * @return bool
+        * @throws MWException
+        */
+       protected function doIsEmpty() {
+               $conn = $this->getConnection();
+               try {
+                       return ( $conn->lSize( $this->getQueueKey( 'l-unclaimed' ) ) == 0 );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * @see JobQueue::doGetSize()
+        * @return integer
+        * @throws MWException
+        */
+       protected function doGetSize() {
+               $conn = $this->getConnection();
+               try {
+                       return $conn->lSize( $this->getQueueKey( 'l-unclaimed' ) );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * @see JobQueue::doGetAcquiredCount()
+        * @return integer
+        * @throws MWException
+        */
+       protected function doGetAcquiredCount() {
+               if ( $this->claimTTL <= 0 ) {
+                       return 0; // no acknowledgements
+               }
+               $conn = $this->getConnection();
+               try {
+                       return $conn->lSize( $this->getQueueKey( 'l-claimed' ) );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * @see JobQueue::doBatchPush()
+        * @param array $jobs
+        * @param $flags
+        * @return bool
+        * @throws MWException
+        */
+       protected function doBatchPush( array $jobs, $flags ) {
+               if ( !count( $jobs ) ) {
+                       return true;
+               }
+
+               // Convert the jobs into a list of field maps
+               $items = array(); // (uid => job fields map)
+               foreach ( $jobs as $job ) {
+                       $item = $this->getNewJobFields( $job );
+                       $items[$item['uid']] = $item;
+               }
+
+               $dedupUids = array(); // list of uids to check for duplicates
+               foreach ( $items as $item ) {
+                       if ( $this->isHashUid( $item['uid'] ) ) { // hash identifier => de-duplicate
+                               $dedupUids[] = $item['uid'];
+                       }
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       // Find which of these jobs are duplicates of unclaimed jobs in the queue...
+                       if ( count( $dedupUids ) ) {
+                               $conn->multi( Redis::PIPELINE );
+                               foreach ( $dedupUids as $uid ) { // check if job data exists
+                                       $conn->exists( $this->prefixWithQueueKey( 'data', $uid ) );
+                               }
+                               if ( $this->claimTTL > 0 ) { // check which jobs were claimed
+                                       foreach ( $dedupUids as $uid ) {
+                                               $conn->hExists( $this->prefixWithQueueKey( 'h-meta', $uid ), 'ctime' );
+                                       }
+                                       list( $exists, $claimed ) = array_chunk( $conn->exec(), count( $dedupUids ) );
+                               } else {
+                                       $exists = $conn->exec();
+                                       $claimed = array(); // no claim system
+                               }
+                               // Remove the duplicate jobs to cut down on pushing duplicate uids...
+                               foreach ( $dedupUids as $k => $uid ) {
+                                       if ( $exists[$k] && empty( $claimed[$k] ) ) {
+                                               unset( $items[$uid] );
+                                       }
+                               }
+                       }
+                       // Actually push the non-duplicate jobs into the queue...
+                       if ( count( $items ) ) {
+                               $uids = array_keys( $items );
+                               $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                               $conn->mSet( $this->prefixKeysWithQueueKey( 'data', $items ) );
+                               call_user_func_array(
+                                       array( $conn, 'lPush' ),
+                                       array_merge( array( $this->getQueueKey( 'l-unclaimed' ) ), $uids )
+                               );
+                               $res = $conn->exec(); // commit (atomic trx)
+                               if ( in_array( false, $res, true ) ) {
+                                       wfDebugLog( 'JobQueueRedis', "Could not insert {$this->type} job(s)." );
+                                       return false;
+                               }
+                       }
+                       wfIncrStats( 'job-insert', count( $items ) );
+                       wfIncrStats( 'job-insert-duplicate', count( $jobs ) - count( $items ) );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               return true;
+       }
+
+       /**
+        * @see JobQueue::doPop()
+        * @return Job|bool
+        * @throws MWException
+        */
+       protected function doPop() {
+               $job = false;
+
+               if ( $this->claimTTL <= 0 && mt_rand( 0, 99 ) == 0 ) {
+                       $this->cleanupClaimedJobs(); // prune jobs and IDs from the "garbage" list
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       do {
+                               // Atomically pop an item off the queue and onto the "claimed" list
+                               $uid = $conn->rpoplpush(
+                                       $this->getQueueKey( 'l-unclaimed' ),
+                                       $this->getQueueKey( 'l-claimed' )
+                               );
+                               if ( $uid === false ) {
+                                       break; // no jobs; nothing to do
+                               }
+
+                               wfIncrStats( 'job-pop' );
+                               $conn->multi( Redis::PIPELINE );
+                               $conn->get( $this->prefixWithQueueKey( 'data', $uid ) );
+                               if ( $this->claimTTL > 0 ) {
+                                       // Set the claim timestamp metadata. If this step fails, then
+                                       // the timestamp will be assumed to be the current timestamp by
+                                       // recycleAndDeleteStaleJobs() as of the next time that it runs.
+                                       // If two runners claim duplicate jobs, one will abort here.
+                                       $conn->hSetNx( $this->prefixWithQueueKey( 'h-meta', $uid ), 'ctime', time() );
+                               } else {
+                                       // If this fails, the message key will be deleted in cleanupClaimedJobs().
+                                       // If two runners claim duplicate jobs, one of them will abort here.
+                                       $conn->delete(
+                                               $this->prefixWithQueueKey( 'h-meta', $uid ),
+                                               $this->prefixWithQueueKey( 'data', $uid ) );
+                               }
+                               list( $item, $ok ) = $conn->exec();
+                               if ( $item === false || ( $this->claimTTL && !$ok ) ) {
+                                       wfDebug( "Could not find or delete job $uid; probably was a duplicate." );
+                                       continue; // job was probably a duplicate
+                               }
+
+                               // If $item is invalid, recycleAndDeleteStaleJobs() will cleanup as needed
+                               $job = $this->getJobFromFields( $item ); // may be false
+                       } while ( !$job ); // job may be false if invalid
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               // Flag this job as an old duplicate based on its "root" job...
+               try {
+                       if ( $job && $this->isRootJobOldDuplicate( $job ) ) {
+                               wfIncrStats( 'job-pop-duplicate' );
+                               return DuplicateJob::newFromJob( $job ); // convert to a no-op
+                       }
+               } catch ( MWException $e ) {} // don't lose jobs over this
+
+               return $job;
+       }
+
+       /**
+        * @see JobQueue::doAck()
+        * @param Job $job
+        * @return Job|bool
+        * @throws MWException
+        */
+       protected function doAck( Job $job ) {
+               if ( $this->claimTTL > 0 ) {
+                       $conn = $this->getConnection();
+                       try {
+                               // Get the exact field map this Job came from, regardless of whether
+                               // the job was transformed into a DuplicateJob or anything of the sort.
+                               $item = $job->metadata['sourceFields'];
+
+                               $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                               // Remove the first instance of this job scanning right-to-left.
+                               // This is O(N) in the worst case, but is likely to be much faster since
+                               // jobs are pushed to the left and we are starting from the right, where
+                               // the longest running jobs are likely to be. These should be the first
+                               // jobs to be acknowledged assuming that job run times are roughly equal.
+                               $conn->lRem( $this->getQueueKey( 'l-claimed' ), $item['uid'], -1 );
+                               // Delete the job data and its claim metadata
+                               $conn->delete(
+                                       $this->prefixWithQueueKey( 'h-meta', $item['uid'] ),
+                                       $this->prefixWithQueueKey( 'data', $item['uid'] ) );
+                               $res = $conn->exec(); // commit (atomic trx)
+
+                               if ( in_array( false, $res, true ) ) {
+                                       wfDebugLog( 'JobQueueRedis', "Could not acknowledge {$this->type} job." );
+                                       return false;
+                               }
+                       } catch ( RedisException $e ) {
+                               $this->throwRedisException( $this->server, $conn, $e );
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * @see JobQueue::doDeduplicateRootJob()
+        * @param Job $job
+        * @return bool
+        * @throws MWException
+        */
+       protected function doDeduplicateRootJob( Job $job ) {
+               $params = $job->getParams();
+               if ( !isset( $params['rootJobSignature'] ) ) {
+                       throw new MWException( "Cannot register root job; missing 'rootJobSignature'." );
+               } elseif ( !isset( $params['rootJobTimestamp'] ) ) {
+                       throw new MWException( "Cannot register root job; missing 'rootJobTimestamp'." );
+               }
+               $key = $this->getRootJobKey( $params['rootJobSignature'] );
+
+               $conn = $this->getConnection();
+               try {
+                       $timestamp = $conn->get( $key ); // current last timestamp of this job
+                       if ( $timestamp && $timestamp >= $params['rootJobTimestamp'] ) {
+                               return true; // a newer version of this root job was enqueued
+                       }
+                       // Update the timestamp of the last root job started at the location...
+                       return $conn->set( $key, $params['rootJobTimestamp'], self::ROOTJOB_TTL ); // 2 weeks
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * Check if the "root" job of a given job has been superseded by a newer one
+        *
+        * @param $job Job
+        * @return bool
+        * @throws MWException
+        */
+       protected function isRootJobOldDuplicate( Job $job ) {
+               $params = $job->getParams();
+               if ( !isset( $params['rootJobSignature'] ) ) {
+                       return false; // job has no de-deplication info
+               } elseif ( !isset( $params['rootJobTimestamp'] ) ) {
+                       wfDebugLog( 'JobQueueRedis', "Cannot check root job; missing 'rootJobTimestamp'." );
+                       return false;
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       // Get the last time this root job was enqueued
+                       $timestamp = $conn->get( $this->getRootJobKey( $params['rootJobSignature'] ) );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               // Check if a new root job was started at the location after this one's...
+               return ( $timestamp && $timestamp > $params['rootJobTimestamp'] );
+       }
+
+       /**
+        * Recycle or destroy any jobs that have been claimed for too long
+        *
+        * @return integer Number of jobs recycled/deleted
+        * @throws MWException
+        */
+       public function recycleAndDeleteStaleJobs() {
+               if ( $this->claimTTL <= 0 ) { // sanity
+                       throw new MWException( "Cannot recycle jobs since acknowledgements are disabled." );
+               }
+               $count = 0;
+               // For each job item that can be retried, we need to add it back to the
+               // main queue and remove it from the list of currenty claimed job items.
+               $conn = $this->getConnection();
+               try {
+                       // Avoid duplicate insertions of items to be re-enqueued
+                       $conn->multi( Redis::MULTI );
+                       $conn->setnx( $this->getQueueKey( 'lock' ), 1 );
+                       $conn->expire( $this->getQueueKey( 'lock' ), 3600 );
+                       if ( $conn->exec() !== array( true, true ) ) { // lock
+                               return $count; // already in progress
+                       }
+
+                       $now = time();
+                       $claimCutoff = $now - $this->claimTTL;
+                       $pruneCutoff = $now - self::MAX_AGE_PRUNE;
+
+                       // Get the list of all claimed jobs
+                       $claimedUids = $conn->lRange( $this->getQueueKey( 'l-claimed' ), 0, -1 );
+                       // Get a map of (uid => claim metadata) for all claimed jobs
+                       $metadata = $conn->mGet( $this->prefixValuesWithQueueKey( 'h-meta', $claimedUids ) );
+
+                       $uidsPush = array(); // items IDs to move to the "unclaimed" queue
+                       $uidsRemove = array(); // item IDs to remove from "claimed" queue
+                       foreach ( $claimedUids as $i => $uid ) { // all claimed items
+                               $info = $metadata[$i] ? $metadata[$i] : array();
+                               if ( isset( $info['ctime'] ) || isset( $info['rctime'] ) ) {
+                                       // Prefer "ctime" (set by pop()) over "rctime" (set by this function)
+                                       $ctime = isset( $info['ctime'] ) ? $info['ctime'] : $info['rctime'];
+                                       // Claimed job claimed for too long?
+                                       if ( $ctime < $claimCutoff ) {
+                                               // Get the number of failed attempts
+                                               $attempts = isset( $info['attempts'] ) ? $info['attempts'] : 0;
+                                               if ( $attempts < $this->maxTries ) {
+                                                       $uidsPush[] = $uid; // retry it
+                                               } elseif ( $ctime < $pruneCutoff ) {
+                                                       $uidsRemove[] = $uid; // just remove it
+                                               }
+                                       }
+                               } else {
+                                       // If pop() failed to set the claim timestamp, set it to the current time.
+                                       // Since that function sets this non-atomically *after* moving the job to
+                                       // the "claimed" queue, it may be the case that it just didn't set it yet.
+                                       $conn->hSet( $this->prefixWithQueueKey( 'h-meta', $uid ), 'rctime', $now );
+                               }
+                       }
+
+                       $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                       if ( count( $uidsPush ) ) { // move from "l-claimed" to "l-unclaimed"
+                               call_user_func_array(
+                                       array( $conn, 'lPush' ),
+                                       array_merge( array( $this->getQueueKey( 'l-unclaimed' ) ), $uidsPush )
+                               );
+                               foreach ( $uidsPush as $uid ) {
+                                       $conn->lRem( $this->getQueueKey( 'l-claimed' ), $uid, -1 );
+                                       $conn->hDel( $this->prefixWithQueueKey( 'h-meta', $uid ), 'ctime', 'rctime' );
+                                       $conn->hIncrBy( $this->prefixWithQueueKey( 'h-meta', $uid ), 'attempts', 1 );
+                               }
+                       }
+                       foreach ( $uidsRemove as $uid ) { // remove from "l-claimed"
+                               $conn->lRem( $this->getQueueKey( 'l-claimed' ), $uid, -1 );
+                               $conn->delete( // delete job data and metadata
+                                       $this->prefixWithQueueKey( 'h-meta', $uid ),
+                                       $this->prefixWithQueueKey( 'data', $uid ) );
+                       }
+                       $res = $conn->exec(); // commit (atomic trx)
+
+                       if ( in_array( false, $res, true ) ) {
+                               wfDebugLog( 'JobQueueRedis', "Could not recycle {$this->type} job(s)." );
+                       } else {
+                               $count += ( count( $uidsPush ) + count( $uidsRemove ) );
+                               wfIncrStats( 'job-recycle', count( $uidsPush ) );
+                       }
+
+                       $conn->delete( $this->getQueueKey( 'lock' ) ); // unlock
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               return $count;
+       }
+
+       /**
+        * Destroy any jobs that have been claimed
+        *
+        * @return integer Number of jobs deleted
+        * @throws MWException
+        */
+       protected function cleanupClaimedJobs() {
+               $count = 0;
+               // Make sure the message for claimed jobs was deleted
+               // and remove the claimed job IDs from the "claimed" list.
+               $conn = $this->getConnection();
+               try {
+                       // Avoid races and duplicate effort
+                       $conn->multi( Redis::MULTI );
+                       $conn->setnx( $this->getQueueKey( 'lock' ), 1 );
+                       $conn->expire( $this->getQueueKey( 'lock' ), 3600 );
+                       if ( $conn->exec() !== array( true, true ) ) { // lock
+                               return $count; // already in progress
+                       }
+                       // Get the list of all claimed jobs
+                       $uids = $conn->lRange( $this->getQueueKey( 'l-claimed' ), 0, -1 );
+                       if ( count( $uids ) ) {
+                               // Delete the message keys and delist the corresponding ids.
+                               // Since the only other changes to "l-claimed" are left pushes, we can just strip
+                               // off the elements read here using a right trim based on the number of ids read.
+                               $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                               $conn->lTrim( $this->getQueueKey( 'l-claimed' ), 0, -count( $uids ) - 1 );
+                               $conn->delete( array_merge(
+                                       $this->prefixValuesWithQueueKey( 'h-meta', $uids ),
+                                       $this->prefixValuesWithQueueKey( 'data', $uids )
+                               ) );
+                               $res = $conn->exec(); // commit (atomic trx)
+
+                               if ( in_array( false, $res, true ) ) {
+                                       wfDebugLog( 'JobQueueRedis', "Could not purge {$this->type} job(s)." );
+                               } else {
+                                       $count += count( $uids );
+                               }
+                       }
+                       $conn->delete( $this->getQueueKey( 'lock' ) ); // unlock
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               return $count;
+       }
+
+       /**
+        * @return Array
+        */
+       protected function doGetPeriodicTasks() {
+               if ( $this->claimTTL > 0 ) {
+                       return array(
+                               'recycleAndDeleteStaleJobs' => array(
+                                       'callback' => array( $this, 'recycleAndDeleteStaleJobs' ),
+                                       'period'   => ceil( $this->claimTTL / 2 )
+                               )
+                       );
+               } else {
+                       return array();
+               }
+       }
+
+       /**
+        * @param $job Job
+        * @return array
+        */
+       protected function getNewJobFields( Job $job ) {
+               return array(
+                       // Fields that describe the nature of the job
+                       'type'      => $job->getType(),
+                       'namespace' => $job->getTitle()->getNamespace(),
+                       'title'     => $job->getTitle()->getDBkey(),
+                       'params'    => $job->getParams(),
+                       // Additional metadata
+                       'uid'       => $job->ignoreDuplicates()
+                               ? wfBaseConvert( sha1( serialize( $job->getDeduplicationInfo() ) ), 16, 36, 31 )
+                               : wfRandomString( 32 ),
+                       'timestamp' => time() // UNIX timestamp
+               );
+       }
+
+       /**
+        * @param $fields array
+        * @return Job|bool
+        */
+       protected function getJobFromFields( array $fields ) {
+               $title = Title::makeTitleSafe( $fields['namespace'], $fields['title'] );
+               if ( $title ) {
+                       $job = Job::factory( $fields['type'], $title, $fields['params'] );
+                       $job->metadata['sourceFields'] = $fields;
+                       return $job;
+               }
+               return false;
+       }
+
+       /**
+        * @param $uid string Job UID
+        * @return bool Whether $uid is a SHA-1 hash based identifier for de-duplication
+        */
+       protected function isHashUid( $uid ) {
+               return strlen( $uid ) == 31;
+       }
+
+       /**
+        * Get a connection to the server that handles all sub-queues for this queue
+        *
+        * @return Array (server name, Redis instance)
+        * @throws MWException
+        */
+       protected function getConnection() {
+               $conn = $this->redisPool->getConnection( $this->server );
+               if ( !$conn ) {
+                       throw new MWException( "Unable to connect to redis server." );
+               }
+               return $conn;
+       }
+
+       /**
+        * @param $server string
+        * @param $conn RedisConnRef
+        * @param $e RedisException
+        * @throws MWException
+        */
+       protected function throwRedisException( $server, RedisConnRef $conn, $e ) {
+               $this->redisPool->handleException( $server, $conn, $e );
+               throw new MWException( "Redis server error: {$e->getMessage()}\n" );
+       }
+
+       /**
+        * @param $prop string
+        * @return string
+        */
+       private function getQueueKey( $prop ) {
+               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+               if ( strlen( $this->key ) ) { // namespaced queue (for testing)
+                       return wfForeignMemcKey( $db, $prefix, 'jobqueue', $this->type, $this->key, $prop );
+               } else {
+                       return wfForeignMemcKey( $db, $prefix, 'jobqueue', $this->type, $prop );
+               }
+       }
+
+       /**
+        * @param string $signature Hash identifier of the root job
+        * @return string
+        */
+       private function getRootJobKey( $signature ) {
+               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+               return wfForeignMemcKey( $db, $prefix, 'jobqueue', $this->type, 'rootjob', $signature );
+       }
+
+       /**
+        * @param $prop string
+        * @param $string string
+        * @return string
+        */
+       private function prefixWithQueueKey( $prop, $string ) {
+               return $this->getQueueKey( $prop ) . ':' . $string;
+       }
+
+       /**
+        * @param $prop string
+        * @param $items array
+        * @return Array
+        */
+       private function prefixValuesWithQueueKey( $prop, array $items ) {
+               $res = array();
+               foreach ( $items as $item ) {
+                       $res[] = $this->prefixWithQueueKey( $prop, $item );
+               }
+               return $res;
+       }
+
+       /**
+        * @param $prop string
+        * @param $items array
+        * @return Array
+        */
+       private function prefixKeysWithQueueKey( $prop, array $items ) {
+               $res = array();
+               foreach ( $items as $key => $item ) {
+                       $res[$this->prefixWithQueueKey( $prop, $key )] = $item;
+               }
+               return $res;
+       }
+
+       /**
+        * @param $key string
+        * @return void
+        */
+       public function setTestingPrefix( $key ) {
+               $this->key = $key;
+       }
+}
index fb73bf1..6158a67 100644 (file)
@@ -131,15 +131,21 @@ class DoubleRedirectJob extends Job {
                        return false;
                }
 
+               $user = $this->getUser();
+               if ( !$user ) {
+                       $this->setLastError( 'Invalid user' );
+                       return false;
+               }
+
                # Save it
                global $wgUser;
                $oldUser = $wgUser;
-               $wgUser = $this->getUser();
+               $wgUser = $user;
                $article = WikiPage::factory( $this->title );
                $reason = wfMessage( 'double-redirect-fixed-' . $this->reason,
                        $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText()
                )->inContentLanguage()->text();
-               $article->doEditContent( $newContent, $reason, EDIT_UPDATE | EDIT_SUPPRESS_RC, false, $this->getUser() );
+               $article->doEditContent( $newContent, $reason, EDIT_UPDATE | EDIT_SUPPRESS_RC, false, $user );
                $wgUser = $oldUser;
 
                return true;
@@ -194,17 +200,19 @@ class DoubleRedirectJob extends Job {
 
        /**
         * Get a user object for doing edits, from a request-lifetime cache
-        * @return User
+        * False will be returned if the user name specified in the
+        * 'double-redirect-fixer' message is invalid.
+        *
+        * @return User|bool
         */
        function getUser() {
                if ( !self::$user ) {
-                       self::$user = User::newFromName( wfMessage( 'double-redirect-fixer' )->inContentLanguage()->text(), false );
-                       # FIXME: newFromName could return false on a badly configured wiki.
-                       if ( !self::$user->isLoggedIn() ) {
+                       self::$user = User::newFromName( wfMessage( 'double-redirect-fixer' )->inContentLanguage()->text() );
+                       # User::newFromName() can return false on a badly configured wiki.
+                       if ( self::$user && !self::$user->isLoggedIn() ) {
                                self::$user->addToDatabase();
                        }
                }
                return self::$user;
        }
 }
-
index 23418e3..1b64b10 100644 (file)
@@ -46,9 +46,10 @@ final class DuplicateJob extends Job {
         */
        public static function newFromJob( Job $job ) {
                $djob = new self( $job->getTitle(), $job->getParams(), $job->getId() );
-               $djob->command = $job->getType();
-               $djob->params  = is_array( $djob->params ) ? $djob->params : array();
-               $djob->params  = array( 'isDuplicate' => true ) + $djob->params;
+               $djob->command  = $job->getType();
+               $djob->params   = is_array( $djob->params ) ? $djob->params : array();
+               $djob->params   = array( 'isDuplicate' => true ) + $djob->params;
+               $djob->metadata = $job->metadata;
                return $djob;
        }
 
index d359988..9fbf312 100644 (file)
@@ -33,14 +33,15 @@ class EmaillingJob extends Job {
        }
 
        function run() {
-               UserMailer::send(
+               $status = UserMailer::send(
                        $this->params['to'],
                        $this->params['from'],
                        $this->params['subj'],
                        $this->params['body'],
                        $this->params['replyto']
                );
-               return true;
+
+               return $status->isOK();
        }
 
 }
index 2566072..fe84369 100644 (file)
@@ -424,7 +424,7 @@ class Services_JSON
                                */
 
                                // treat as a JSON object
-                               if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+                               if (is_array($var) && count($var) && (array_keys($var) !== range(0, count($var) - 1))) {
                                        $this->indent++;
                                        $properties = array_map(array($this, 'name_value'),
                                                                array_keys($var),
index 4ebbc49..76c5b6a 100644 (file)
@@ -57,6 +57,7 @@ class CSSJanus {
                'lookahead_not_open_brace' => null,
                'lookahead_not_closing_paren' => null,
                'lookahead_for_closing_paren' => null,
+               'lookahead_not_letter' => '(?![a-zA-Z])',
                'lookbehind_not_letter' => '(?<![a-zA-Z])',
                'chars_within_selector' => '[^\}]*?',
                'noflip_annotation' => '\/\*\s*@noflip\s*\*\/',
@@ -104,8 +105,8 @@ class CSSJanus {
                $patterns['noflip_class'] = "/({$patterns['noflip_annotation']}{$patterns['chars_within_selector']}})/i";
                $patterns['direction_ltr'] = "/({$patterns['direction']})ltr/i";
                $patterns['direction_rtl'] = "/({$patterns['direction']})rtl/i";
-               $patterns['left'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
-               $patterns['right'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
+               $patterns['left'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_not_letter']}{$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
+               $patterns['right'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_not_letter']}{$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
                $patterns['left_in_url'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_for_closing_paren']}/i";
                $patterns['right_in_url'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_for_closing_paren']}/i";
                $patterns['ltr_in_url'] = "/{$patterns['lookbehind_not_letter']}(ltr){$patterns['lookahead_for_closing_paren']}/i";
index 9b3e796..ef7587d 100644 (file)
@@ -41,7 +41,7 @@ abstract class GenericArrayObject extends ArrayObject {
         *
         * @return string
         */
-       public abstract function getObjectType();
+       abstract public function getObjectType();
 
        /**
         * @see SiteList::getNewOffset()
index cfc7f53..fae06ad 100644 (file)
@@ -848,4 +848,3 @@ class IEContentAnalyzer {
                return 'unknown';
        }
 }
-
diff --git a/includes/limit.sh b/includes/limit.sh
new file mode 100644 (file)
index 0000000..44b9edc
--- /dev/null
@@ -0,0 +1,100 @@
+#!/bin/bash
+#
+# Resource limiting wrapper for command execution
+#
+# Why is this in shell script? Because bash has a setrlimit() wrapper
+# and is available on most Linux systems. If Perl was distributed with
+# BSD::Resource included, we would happily use that instead, but it isn't.
+
+MW_CPU_LIMIT=0
+MW_CGROUP=
+MW_MEM_LIMIT=0
+MW_FILE_SIZE_LIMIT=0
+MW_WALL_CLOCK_LIMIT=0
+
+# Override settings
+eval "$2"
+
+if [ "$MW_CPU_LIMIT" -gt 0 ]; then
+       ulimit -t "$MW_CPU_LIMIT"
+fi
+if [ "$MW_MEM_LIMIT" -gt 0 ]; then
+       if [ -n "$MW_CGROUP" ]; then
+               # Create cgroup
+               if ! mkdir -m 0700 "$MW_CGROUP"/$$; then
+                       echo "limit.sh: failed to create the cgroup." 1>&2
+                       exit 1
+               fi
+               echo $$ > "$MW_CGROUP"/$$/tasks
+               if [ -n "$MW_CGROUP_NOTIFY" ]; then
+                       echo "1" > "$MW_CGROUP"/$$/notify_on_release
+               fi
+               # Memory
+               echo $(($MW_MEM_LIMIT*1024)) > "$MW_CGROUP"/$$/memory.limit_in_bytes
+               # Memory+swap
+               echo $(($MW_MEM_LIMIT*1024)) > "$MW_CGROUP"/$$/memory.memsw.limit_in_bytes
+       else
+               ulimit -v "$MW_MEM_LIMIT"
+       fi
+fi
+if [ "$MW_FILE_SIZE_LIMIT" -gt 0 ]; then
+       ulimit -f "$MW_FILE_SIZE_LIMIT"
+fi
+if [ "$MW_WALL_CLOCK_LIMIT" -gt 0 -a -x "/usr/bin/timeout" ]; then
+       /usr/bin/timeout $MW_WALL_CLOCK_LIMIT /bin/bash -c "$1"
+       STATUS="$?"
+       if [ "$STATUS" == 124 ]; then
+               echo "limit.sh: timed out." 1>&2
+       fi
+else
+       eval "$1"
+       STATUS="$?"
+fi
+
+# Clean up cgroup
+cleanup() {
+       # First we have to move the current task into a "garbage" group, otherwise 
+       # the cgroup will not be empty, and attempting to remove it will fail with
+       # "Device or resource busy"
+       if [ -w "$MW_CGROUP"/tasks ]; then
+               GARBAGE="$MW_CGROUP"
+       else
+               GARBAGE="$MW_CGROUP"/garbage-"$USER"
+               if [ ! -e "$GARBAGE" ]; then
+                       mkdir -m 0700 "$GARBAGE"
+               fi
+       fi
+       echo $BASHPID > "$GARBAGE"/tasks
+
+       # Suppress errors in case the cgroup has disappeared due to a release script
+       rmdir "$MW_CGROUP"/$$ 2>/dev/null
+}
+
+updateTaskCount() {
+       # There are lots of ways to count lines in a file in shell script, but this
+       # is one of the few that doesn't create another process, which would
+       # increase the returned number of tasks.
+       readarray < "$MW_CGROUP"/$$/tasks
+       NUM_TASKS=${#MAPFILE[*]}
+}
+
+if [ -n "$MW_CGROUP" ]; then
+       updateTaskCount
+
+       if [ $NUM_TASKS -gt 1 ]; then
+               # Spawn a monitor process which will continue to poll for completion 
+               # of all processes in the cgroup after termination of the parent shell
+               (
+                       while [ $NUM_TASKS -gt 1 ]; do
+                               sleep 10
+                               updateTaskCount
+                       done
+                       cleanup
+               ) >&/dev/null < /dev/null &
+               disown -a
+       else
+               cleanup
+       fi
+fi
+exit "$STATUS"
+
index 1110249..47b2231 100644 (file)
@@ -74,7 +74,7 @@ class LogEventsList extends ContextSource {
        public function showHeader( $type ) {
                wfDeprecated( __METHOD__, '1.19' );
                // If only one log type is used, then show a special message...
-               $headerType = (count($type) == 1) ? $type[0] : '';
+               $headerType = (count( $type ) == 1) ? $type[0] : '';
                $out = $this->getOutput();
                if( LogPage::isLogType( $headerType ) ) {
                        $page = new LogPage( $headerType );
@@ -97,8 +97,8 @@ class LogEventsList extends ContextSource {
         * @param $filter: array
         * @param $tagFilter: array?
         */
-       public function showOptions( $types=array(), $user='', $page='', $pattern='', $year='',
-               $month = '', $filter = null, $tagFilter='' ) {
+       public function showOptions( $types=array(), $user = '', $page = '', $pattern = '', $year = '',
+               $month = '', $filter = null, $tagFilter = '' ) {
                global $wgScript, $wgMiserMode;
 
                $title = SpecialPage::getTitleFor( 'Log' );
@@ -117,7 +117,7 @@ class LogEventsList extends ContextSource {
                $html .= $this->getExtraInputs( $types ) . "\n";
 
                // Title pattern, if allowed
-               if (!$wgMiserMode) {
+               if ( !$wgMiserMode ) {
                        $html .= $this->getTitlePattern( $pattern ) . "\n";
                }
 
@@ -125,12 +125,12 @@ class LogEventsList extends ContextSource {
                $html .= Xml::tags( 'p', null, Xml::dateMenu( $year, $month ) );
 
                // Tag filter
-               if ($tagSelector) {
+               if ( $tagSelector ) {
                        $html .= Xml::tags( 'p', null, implode( '&#160;', $tagSelector ) );
                }
 
                // Filter links
-               if ($filter) {
+               if ( $filter ) {
                        $html .= Xml::tags( 'p', null, $this->getFilterLinks( $filter ) );
                }
 
@@ -162,7 +162,7 @@ class LogEventsList extends ContextSource {
                        $query = $this->getDefaultQuery();
                        $queryKey = "hide_{$type}_log";
 
-                       $hideVal = 1 - intval($val);
+                       $hideVal = 1 - intval( $val );
                        $query[$queryKey] = $hideVal;
 
                        $link = Linker::linkKnown(
@@ -176,7 +176,7 @@ class LogEventsList extends ContextSource {
                        $hiddens .= Html::hidden( "hide_{$type}_log", $val ) . "\n";
                }
                // Build links
-               return '<small>'.$this->getLanguage()->pipeList( $links ) . '</small>' . $hiddens;
+               return '<small>' . $this->getLanguage()->pipeList( $links ) . '</small>' . $hiddens;
        }
 
        private function getDefaultQuery() {
@@ -198,7 +198,7 @@ class LogEventsList extends ContextSource {
         * @return String: Formatted HTML
         */
        private function getTypeMenu( $queryTypes ) {
-               $queryType = count($queryTypes) == 1 ? $queryTypes[0] : '';
+               $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
                $selector = $this->getTypeSelector();
                $selector->setDefault( $queryType );
                return $selector->getHtml();
@@ -212,7 +212,7 @@ class LogEventsList extends ContextSource {
        public function getTypeSelector() {
                $typesByName = array(); // Temporary array
                // First pass to load the log names
-               foreach(  LogPage::validTypes() as $type ) {
+               foreach( LogPage::validTypes() as $type ) {
                        $page = new LogPage( $type );
                        $restriction = $page->getRestriction();
                        if ( $this->getUser()->isAllowed( $restriction ) ) {
@@ -221,7 +221,7 @@ class LogEventsList extends ContextSource {
                }
 
                // Second pass to sort by name
-               asort($typesByName);
+               asort( $typesByName );
 
                // Always put "All public logs" on top
                $public = $typesByName[''];
@@ -273,10 +273,10 @@ class LogEventsList extends ContextSource {
        private function getExtraInputs( $types ) {
                $offender = $this->getRequest()->getVal( 'offender' );
                $user = User::newFromName( $offender, false );
-               if( !$user || ($user->getId() == 0 && !IP::isIPAddress($offender) ) ) {
+               if( !$user || ( $user->getId() == 0 && !IP::isIPAddress( $offender ) ) ) {
                        $offender = ''; // Blank field if invalid
                }
-               if( count($types) == 1 && $types[0] == 'suppress' ) {
+               if( count( $types ) == 1 && $types[0] == 'suppress' ) {
                        return Xml::inputLabel( $this->msg( 'revdelete-offender' )->text(), 'offender',
                                'mw-log-offender', 20, $offender );
                }
@@ -383,8 +383,8 @@ class LogEventsList extends ContextSource {
         * @param $right string
         * @return Boolean
         */
-       public static function typeAction( $row, $type, $action, $right='' ) {
-               $match = is_array($type) ?
+       public static function typeAction( $row, $type, $action, $right = '' ) {
+               $match = is_array( $type ) ?
                        in_array( $row->log_type, $type ) : $row->log_type == $type;
                if( $match ) {
                        $match = is_array( $action ) ?
@@ -468,13 +468,13 @@ class LogEventsList extends ContextSource {
         * @return Integer Number of total log items (not limited by $lim)
         */
        public static function showLogExtract(
-               &$out, $types=array(), $page='', $user='', $param = array()
+               &$out, $types=array(), $page = '', $user = '', $param = array()
        ) {
                $defaultParameters = array(
                        'lim' => 25,
                        'conds' => array(),
                        'showIfEmpty' => true,
-                       'msgKey' => array(''),
+                       'msgKey' => array( '' ),
                        'wrap' => "$1",
                        'flags' => 0
                );
@@ -520,8 +520,8 @@ class LogEventsList extends ContextSource {
                                }
                        }
                        $s .= $loglist->beginLogEventsList() .
-                                $logBody .
-                                $loglist->endLogEventsList();
+                               $logBody .
+                               $loglist->endLogEventsList();
                } else {
                        if ( $showIfEmpty ) {
                                $s = Html::rawElement( 'div', array( 'class' => 'mw-warning-logempty' ),
@@ -535,7 +535,7 @@ class LogEventsList extends ContextSource {
                        } elseif ( $page != '' ) {
                                $urlParam['page'] = $page;
                        }
-                       if ( $user != '')
+                       if ( $user != '' )
                                $urlParam['user'] = $user;
                        if ( !is_array( $types ) ) # Make it an array, if it isn't
                                $types = array( $types );
@@ -560,7 +560,7 @@ class LogEventsList extends ContextSource {
                /* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
                if ( wfRunHooks( 'LogEventsListShowLogExtract', array( &$s, $types, $page, $user, $param ) ) ) {
                        // $out can be either an OutputPage object or a String-by-reference
-                       if ( $out instanceof OutputPage ){
+                       if ( $out instanceof OutputPage ) {
                                $out->addHTML( $s );
                        } else {
                                $out = $s;
@@ -602,4 +602,4 @@ class LogEventsList extends ContextSource {
                }
                return false;
        }
- }
+}
index 4f699f1..eb8779f 100644 (file)
@@ -192,18 +192,18 @@ class LogFormatter {
                $parameters = $entry->getParameters();
                // @see LogPage::actionText()
                // Text of title the action is aimed at.
-               $target = $entry->getTarget()->getPrefixedText() ;
+               $target = $entry->getTarget()->getPrefixedText();
                $text = null;
                switch( $entry->getType() ) {
                        case 'move':
                                switch( $entry->getSubtype() ) {
                                        case 'move':
-                                               $movesource =  $parameters['4::target'];
+                                               $movesource = $parameters['4::target'];
                                                $text = wfMessage( '1movedto2' )
                                                        ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
                                                break;
                                        case 'move_redir':
-                                               $movesource =  $parameters['4::target'];
+                                               $movesource = $parameters['4::target'];
                                                $text = wfMessage( '1movedto2_redir' )
                                                        ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
                                                break;
@@ -270,6 +270,7 @@ class LogFormatter {
                                                        ->inContentLanguage()->escaped();
                                                break;
                                        case 'create2':
+                                       case 'byemail':
                                                $text = wfMessage( 'newuserlog-create2-entry' )
                                                        ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
@@ -587,7 +588,7 @@ class LogFormatter {
                        return $this->msg( $message )->text();
                }
 
-               $content =  $this->msg( $message )->escaped();
+               $content = $this->msg( $message )->escaped();
                $attribs = array( 'class' => 'history-deleted' );
                return Html::rawElement( 'span', $attribs, $content );
        }
@@ -712,7 +713,7 @@ class LegacyLogFormatter extends LogFormatter {
 
                $performer = $this->getPerformerElement();
                if ( !$this->irctext ) {
-                       $action = $performer .  $this->msg( 'word-separator' )->text() . $action;
+                       $action = $performer . $this->msg( 'word-separator' )->text() . $action;
                }
 
                return $action;
@@ -912,7 +913,7 @@ class DeleteLogFormatter extends LogFormatter {
                                foreach ( $extra as $v ) {
                                        $changes[] = $this->msg( $v )->plain();
                                }
-                               $changeText =  $this->context->getLanguage()->listToText( $changes );
+                               $changeText = $this->context->getLanguage()->listToText( $changes );
 
 
                                $newParams = array_slice( $params, 0, 3 );
@@ -956,7 +957,7 @@ class DeleteLogFormatter extends LogFormatter {
                                $this->msg( $message )->escaped(),
                                array(),
                                array( 'target' => $this->entry->getTarget()->getPrefixedDBkey() )
-                        );
+                       );
                        return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
 
                case 'revision': // If an edit was hidden from a page give a review link to the history
@@ -1085,7 +1086,8 @@ class PatrolLogFormatter extends LogFormatter {
 class NewUsersLogFormatter extends LogFormatter {
        protected function getMessageParameters() {
                $params = parent::getMessageParameters();
-               if ( $this->entry->getSubtype() === 'create2' ) {
+               $subtype = $this->entry->getSubtype();
+               if ( $subtype === 'create2' || $subtype === 'byemail' ) {
                        if ( isset( $params[3] ) ) {
                                $target = User::newFromId( $params[3] );
                        } else {
@@ -1108,7 +1110,8 @@ class NewUsersLogFormatter extends LogFormatter {
        }
 
        public function getPreloadTitles() {
-               if ( $this->entry->getSubtype() === 'create2' ) {
+               $subtype = $this->entry->getSubtype();
+               if ( $subtype === 'create2' || $subtype === 'byemail' ) {
                        //add the user talk to LinkBatch for the userLink
                        return array( Title::makeTitle( NS_USER_TALK, $this->entry->getTarget()->getText() ) );
                }
index 5854e99..9778f27 100644 (file)
@@ -271,7 +271,7 @@ class LogPage {
                                                $params[2] = isset( $params[2] ) ?
                                                        self::formatBlockFlags( $params[2], $langObj ) : '';
                                        // Page protections
-                                       } elseif ( $type == 'protect' && count($params) == 3 ) {
+                                       } elseif ( $type == 'protect' && count( $params ) == 3 ) {
                                                // Restrictions and expiries
                                                if( $skin ) {
                                                        $details .= $wgLang->getDirMark() . htmlspecialchars( " {$params[1]}" );
index af62ce3..fad1058 100644 (file)
@@ -71,7 +71,7 @@ class LogPager extends ReverseChronologicalPager {
        public function getFilterParams() {
                global $wgFilterLogTypes;
                $filters = array();
-               if( count($this->types) ) {
+               if( count( $this->types ) ) {
                        return $filters;
                }
                foreach( $wgFilterLogTypes as $type => $default ) {
@@ -122,10 +122,10 @@ class LogPager extends ReverseChronologicalPager {
                if( $hideLogs !== false ) {
                        $this->mConds[] = $hideLogs;
                }
-               if( count($types) ) {
+               if( count( $types ) ) {
                        $this->mConds['log_type'] = $types;
                        // Set typeCGI; used in url param for paging
-                       if( count($types) == 1 ) $this->typeCGI = $types[0];
+                       if( count( $types ) == 1 ) $this->typeCGI = $types[0];
                }
        }
 
@@ -140,7 +140,7 @@ class LogPager extends ReverseChronologicalPager {
                        return false;
                }
                $usertitle = Title::makeTitleSafe( NS_USER, $name );
-               if( is_null($usertitle) ) {
+               if( is_null( $usertitle ) ) {
                        return false;
                }
                /* Fetch userid at first, if known, provides awesome query plan afterwards */
@@ -154,9 +154,9 @@ class LogPager extends ReverseChronologicalPager {
                        // Paranoia: avoid brute force searches (bug 17342)
                        $user = $this->getUser();
                        if( !$user->isAllowed( 'deletedhistory' ) ) {
-                               $this->mConds[] = $this->mDb->bitAnd('log_deleted', LogPage::DELETED_USER) . ' = 0';
+                               $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_USER ) . ' = 0';
                        } elseif( !$user->isAllowed( 'suppressrevision' ) ) {
-                               $this->mConds[] = $this->mDb->bitAnd('log_deleted', LogPage::SUPPRESSED_USER) .
+                               $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_USER ) .
                                        ' != ' . LogPage::SUPPRESSED_USER;
                        }
                        $this->performer = $usertitle->getText();
@@ -209,9 +209,9 @@ class LogPager extends ReverseChronologicalPager {
                // Paranoia: avoid brute force searches (bug 17342)
                $user = $this->getUser();
                if( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $this->mConds[] = $db->bitAnd('log_deleted', LogPage::DELETED_ACTION) . ' = 0';
+                       $this->mConds[] = $db->bitAnd( 'log_deleted', LogPage::DELETED_ACTION) . ' = 0';
                } elseif( !$user->isAllowed( 'suppressrevision' ) ) {
-                       $this->mConds[] = $db->bitAnd('log_deleted', LogPage::SUPPRESSED_ACTION) .
+                       $this->mConds[] = $db->bitAnd( 'log_deleted', LogPage::SUPPRESSED_ACTION) .
                                ' != ' . LogPage::SUPPRESSED_ACTION;
                }
        }
@@ -251,10 +251,10 @@ class LogPager extends ReverseChronologicalPager {
                # avoids site-breaking filesorts.
                } elseif( $this->title || $this->pattern || $this->performer ) {
                        $index['logging'] = array( 'page_time', 'user_time' );
-                       if( count($this->types) == 1 ) {
+                       if( count( $this->types ) == 1 ) {
                                $index['logging'][] = 'log_user_type_time';
                        }
-               } elseif( count($this->types) == 1 ) {
+               } elseif( count( $this->types ) == 1 ) {
                        $index['logging'] = 'type_time';
                } else {
                        $index['logging'] = 'times';
index a515c63..46d1b95 100644 (file)
@@ -62,7 +62,7 @@ class BmpHandler extends BitmapHandler {
                        return false;
                }
                $header = fread( $f, 54 );
-               fclose($f);
+               fclose( $f );
 
                // Extract binary form of width and height from the header
                $w = substr( $header, 18, 4);
index 2b04f78..55deef0 100644 (file)
@@ -190,7 +190,7 @@ class BitmapMetadataHandler {
         * @param $filename String full path to file
         * @return Array Array for storage in img_metadata.
         */
-       static public function PNG ( $filename ) {
+       public static function PNG ( $filename ) {
                $showXMP = function_exists( 'xml_parser_create_ns' );
 
                $meta = new self();
@@ -219,7 +219,7 @@ class BitmapMetadataHandler {
         * @param $filename string full path to file
         * @return Array metadata array
         */
-       static public function GIF ( $filename ) {
+       public static function GIF ( $filename ) {
 
                $meta = new self();
                $baseArray = GIFMetadataExtractor::getMetadata( $filename );
@@ -260,7 +260,7 @@ class BitmapMetadataHandler {
         * @throws MWException
         * @return Array The metadata.
         */
-       static public function Tiff ( $filename ) {
+       public static function Tiff ( $filename ) {
                if ( file_exists( $filename ) ) {
                        $byteOrder = self::getTiffByteOrder( $filename );
                        if ( !$byteOrder ) {
index 124db32..0a39a2c 100644 (file)
@@ -183,7 +183,7 @@ class DjVuHandler extends ImageHandler {
                if ( $wgDjvuPostProcessor ) {
                        $cmd .= " | {$wgDjvuPostProcessor}";
                }
-               $cmd .= ' > ' . wfEscapeShellArg($dstPath) . ') 2>&1';
+               $cmd .= ' > ' . wfEscapeShellArg( $dstPath ) . ') 2>&1';
                wfProfileIn( 'ddjvu' );
                wfDebug( __METHOD__.": $cmd\n" );
                $retval = '';
@@ -194,7 +194,7 @@ class DjVuHandler extends ImageHandler {
                if ( $retval != 0 || $removed ) {
                        wfDebugLog( 'thumbnail',
                                sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
-                                       wfHostname(), $retval, trim($err), $cmd ) );
+                                       wfHostname(), $retval, trim( $err ), $cmd ) );
                        return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
                } else {
                        $params = array(
@@ -228,7 +228,7 @@ class DjVuHandler extends ImageHandler {
         * @param $gettext Boolean: DOCUMENT (Default: false)
         * @return bool
         */
-       function getMetaTree( $image , $gettext = false ) {
+       function getMetaTree( $image, $gettext = false ) {
                if ( isset( $image->dejaMetaTree ) ) {
                        return $image->dejaMetaTree;
                }
@@ -247,7 +247,7 @@ class DjVuHandler extends ImageHandler {
                        $image->djvuTextTree = false;
                        $tree = new SimpleXMLElement( $metadata );
                        if( $tree->getName() == 'mw-djvu' ) {
-                               foreach($tree->children() as $b){
+                               foreach( $tree->children() as $b ) {
                                        if( $b->getName() == 'DjVuTxt' ) {
                                                $image->djvuTextTree = $b;
                                        }
index cad9c1b..9735791 100644 (file)
@@ -43,9 +43,9 @@ class DjVuImage {
                $this->mFilename = $filename;
        }
 
-        /**
-         * @const DJVUTXT_MEMORY_LIMIT Memory limit for the DjVu description software
-         */
+       /**
+        * @const DJVUTXT_MEMORY_LIMIT Memory limit for the DjVu description software
+        */
        const DJVUTXT_MEMORY_LIMIT = 300000;
 
        /**
@@ -259,8 +259,8 @@ class DjVuImage {
                # Text layer
                if ( isset( $wgDjvuTxt ) ) {
                        wfProfileIn( 'djvutxt' );
-                       $cmd = wfEscapeShellArg( $wgDjvuTxt ) . ' --detail=page ' . wfEscapeShellArg( $this->mFilename ) ;
-                       wfDebug( __METHOD__.": $cmd\n" );
+                       $cmd = wfEscapeShellArg( $wgDjvuTxt ) . ' --detail=page ' . wfEscapeShellArg( $this->mFilename );
+                       wfDebug( __METHOD__ . ": $cmd\n" );
                        $retval = '';
                        $txt = wfShellExec( $cmd, $retval, array(), array( 'memory' => self::DJVUTXT_MEMORY_LIMIT ) );
                        wfProfileOut( 'djvutxt' );
@@ -281,7 +281,7 @@ EOR;
                                $txt = preg_replace_callback( $reg, array( $this, 'pageTextCallback' ), $txt );
                                $txt = "<DjVuTxt>\n<HEAD></HEAD>\n<BODY>\n" . $txt . "</BODY>\n</DjVuTxt>\n";
                                $xml = preg_replace( "/<DjVuXML>/", "<mw-djvu><DjVuXML>", $xml, 1 );
-                               $xml = $xml . $txt. '</mw-djvu>' ;
+                               $xml = $xml . $txt. '</mw-djvu>';
                        }
                }
                wfProfileOut( __METHOD__ );
index bdacbc8..2dc2eae 100644 (file)
@@ -290,8 +290,8 @@ class Exif {
                        // Only give a warning for b/c, since originally we didn't
                        // require this. The number of things affected by this is
                        // rather small.
-                       wfWarn( 'Exif class did not have byte order specified. '
-                        . 'Some properties may be decoded incorrectly.' );
+                       wfWarn( 'Exif class did not have byte order specified. ' .
+                               'Some properties may be decoded incorrectly.' );
                        $this->byteOrder = 'BE'; // BE seems about twice as popular as LE in jpg's.
                }
 
@@ -322,7 +322,7 @@ class Exif {
 
                foreach ( array_keys( $this->mRawExifData ) as $section ) {
                        if ( !in_array( $section, array_keys( $this->mExifTags ) ) ) {
-                               $this->debug( $section , __FUNCTION__, "'$section' is not a valid Exif section" );
+                               $this->debug( $section, __FUNCTION__, "'$section' is not a valid Exif section" );
                                continue;
                        }
 
@@ -387,7 +387,7 @@ class Exif {
                $this->exifPropToOrd( 'SceneType' );
 
                $this->charCodeString( 'UserComment' );
-               $this->charCodeString( 'GPSProcessingMethod');
+               $this->charCodeString( 'GPSProcessingMethod' );
                $this->charCodeString( 'GPSAreaInformation' );
 
                //ComponentsConfiguration should really be an array instead of a string...
@@ -396,8 +396,8 @@ class Exif {
                if ( isset ( $this->mFilteredExifData['ComponentsConfiguration'] ) ) {
                        $val = $this->mFilteredExifData['ComponentsConfiguration'];
                        $ccVals = array();
-                       for ($i = 0; $i < strlen($val); $i++) {
-                               $ccVals[$i] = ord( substr($val, $i, 1) );
+                       for ( $i = 0; $i < strlen( $val ); $i++ ) {
+                               $ccVals[$i] = ord( substr( $val, $i, 1 ) );
                        }
                        $ccVals['_type'] = 'ol'; //this is for formatting later.
                        $this->mFilteredExifData['ComponentsConfiguration'] = $ccVals;
@@ -413,11 +413,11 @@ class Exif {
                if ( isset ( $this->mFilteredExifData['GPSVersion'] ) ) {
                        $val = $this->mFilteredExifData['GPSVersion'];
                        $newVal = '';
-                       for ($i = 0; $i < strlen($val); $i++) {
+                       for ( $i = 0; $i < strlen( $val ); $i++ ) {
                                if ( $i !== 0 ) {
                                        $newVal .= '.';
                                }
-                               $newVal .= ord( substr($val, $i, 1) );
+                               $newVal .= ord( substr( $val, $i, 1 ) );
                        }
                        if ( $this->byteOrder === 'LE' ) {
                                // Need to reverse the string
@@ -442,17 +442,17 @@ class Exif {
        private function charCodeString ( $prop ) {
                if ( isset( $this->mFilteredExifData[$prop] ) ) {
 
-                       if ( strlen($this->mFilteredExifData[$prop]) <= 8 ) {
+                       if ( strlen( $this->mFilteredExifData[$prop] ) <= 8 ) {
                                //invalid. Must be at least 9 bytes long.
 
-                               $this->debug( $this->mFilteredExifData[$prop] , __FUNCTION__, false );
-                               unset($this->mFilteredExifData[$prop]);
+                               $this->debug( $this->mFilteredExifData[$prop], __FUNCTION__, false );
+                               unset( $this->mFilteredExifData[$prop] );
                                return;
                        }
-                       $charCode = substr( $this->mFilteredExifData[$prop], 0, 8);
-                       $val = substr( $this->mFilteredExifData[$prop], 8);
+                       $charCode = substr( $this->mFilteredExifData[$prop], 0, 8 );
+                       $val = substr( $this->mFilteredExifData[$prop], 8 );
 
-                       switch ($charCode) {
+                       switch ( $charCode ) {
                                case "\x4A\x49\x53\x00\x00\x00\x00\x00":
                                        //JIS
                                        $charset = "Shift-JIS";
@@ -466,9 +466,9 @@ class Exif {
                        }
                        // This could possibly check to see if iconv is really installed
                        // or if we're using the compatibility wrapper in globalFunctions.php
-                       if ($charset) {
+                       if ( $charset ) {
                                wfSuppressWarnings();
-                               $val = iconv($charset, 'UTF-8//IGNORE', $val);
+                               $val = iconv( $charset, 'UTF-8//IGNORE', $val );
                                wfRestoreWarnings();
                        } else {
                                // if valid utf-8, assume that, otherwise assume windows-1252
@@ -476,17 +476,17 @@ class Exif {
                                UtfNormal::quickIsNFCVerify( $valCopy ); //validates $valCopy.
                                if ( $valCopy !== $val ) {
                                        wfSuppressWarnings();
-                                       $val = iconv('Windows-1252', 'UTF-8//IGNORE', $val);
+                                       $val = iconv( 'Windows-1252', 'UTF-8//IGNORE', $val );
                                        wfRestoreWarnings();
                                }
                        }
 
                        //trim and check to make sure not only whitespace.
-                       $val = trim($val);
+                       $val = trim( $val );
                        if ( strlen( $val ) === 0 ) {
                                //only whitespace.
-                               $this->debug( $this->mFilteredExifData[$prop] , __FUNCTION__, "$prop: Is only whitespace" );
-                               unset($this->mFilteredExifData[$prop]);
+                               $this->debug( $this->mFilteredExifData[$prop], __FUNCTION__, "$prop: Is only whitespace" );
+                               unset( $this->mFilteredExifData[$prop] );
                                return;
                        }
 
@@ -580,7 +580,7 @@ class Exif {
         */
        function getFormattedData() {
                wfDeprecated( __METHOD__, '1.18' );
-               if (!$this->mFormattedExifData) {
+               if ( !$this->mFormattedExifData ) {
                        $this->makeFormattedData();
                }
                return $this->mFormattedExifData;
@@ -612,7 +612,7 @@ class Exif {
         * @return bool
         */
        private function isByte( $in ) {
-               if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 255 ) {
+               if ( !is_array( $in ) && sprintf( '%d', $in ) == $in && $in >= 0 && $in <= 255 ) {
                        $this->debug( $in, __FUNCTION__, true );
                        return true;
                } else {
@@ -648,7 +648,7 @@ class Exif {
         * @return bool
         */
        private function isShort( $in ) {
-               if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 65536 ) {
+               if ( !is_array( $in ) && sprintf( '%d', $in ) == $in && $in >= 0 && $in <= 65536 ) {
                        $this->debug( $in, __FUNCTION__, true );
                        return true;
                } else {
@@ -662,7 +662,7 @@ class Exif {
         * @return bool
         */
        private function isLong( $in ) {
-               if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 4294967296 ) {
+               if ( !is_array( $in ) && sprintf( '%d', $in ) == $in && $in >= 0 && $in <= 4294967296 ) {
                        $this->debug( $in, __FUNCTION__, true );
                        return true;
                } else {
@@ -813,13 +813,13 @@ class Exif {
                }
 
                if ( $action === true ) {
-                       wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)\n");
+                       wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)\n" );
                } elseif ( $action === false ) {
-                       wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)\n");
+                       wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)\n" );
                } elseif ( $action === null ) {
-                       wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)\n");
+                       wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)\n" );
                } else {
-                       wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')\n");
+                       wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')\n" );
                }
        }
 
@@ -843,4 +843,3 @@ class Exif {
                }
        }
 }
-
index 34a1f51..1671ab2 100644 (file)
@@ -34,8 +34,8 @@ class ExifBitmapHandler extends BitmapHandler {
 
        function convertMetadataVersion( $metadata, $version = 1 ) {
                // basically flattens arrays.
-               $version = explode(';', $version, 2);
-               $version = intval($version[0]);
+               $version = explode( ';', $version, 2 );
+               $version = intval( $version[0] );
                if ( $version < 1 || $version >= 2 ) {
                        return $metadata;
                }
@@ -56,7 +56,7 @@ class ExifBitmapHandler extends BitmapHandler {
                        && is_array( $metadata['Software'][0])
                        && isset( $metadata['Software'][0][0] )
                        && isset( $metadata['Software'][0][1])
-                ) {
+               ) {
                        $metadata['Software'] = $metadata['Software'][0][0] . ' (Version '
                                . $metadata['Software'][0][1] . ')';
                }
@@ -86,7 +86,7 @@ class ExifBitmapHandler extends BitmapHandler {
                if ( $metadata === self::OLD_BROKEN_FILE ) {
                        # Old special value indicating that there is no EXIF data in the file.
                        # or that there was an error well extracting the metadata.
-                       wfDebug( __METHOD__ . ": back-compat version\n");
+                       wfDebug( __METHOD__ . ": back-compat version\n" );
                        return self::METADATA_COMPATIBLE;
                }
                if ( $metadata === self::BROKEN_FILE ) {
@@ -102,11 +102,11 @@ class ExifBitmapHandler extends BitmapHandler {
                                $exif['MEDIAWIKI_EXIF_VERSION'] == 1 )
                        {
                                //back-compatible but old
-                               wfDebug( __METHOD__.": back-compat version\n" );
+                               wfDebug( __METHOD__ . ": back-compat version\n" );
                                return self::METADATA_COMPATIBLE;
                        }
                        # Wrong (non-compatible) version
-                       wfDebug( __METHOD__.": wrong version\n" );
+                       wfDebug( __METHOD__ . ": wrong version\n" );
                        return self::METADATA_BAD;
                }
                return self::METADATA_GOOD;
@@ -163,7 +163,7 @@ class ExifBitmapHandler extends BitmapHandler {
                        $rotation = 0;
                }
 
-               if ($rotation == 90 || $rotation == 270) {
+               if ( $rotation == 90 || $rotation == 270 ) {
                        $width = $gis[0];
                        $gis[0] = $gis[1];
                        $gis[1] = $width;
@@ -225,4 +225,3 @@ class ExifBitmapHandler extends BitmapHandler {
                return 0;
        }
 }
-
index f2710f7..97aa28b 100644 (file)
@@ -80,20 +80,20 @@ class FormatMetadata {
                        }
 
                        //This is done differently as the tag is an array.
-                       if ($tag == 'GPSTimeStamp' && count($vals) === 3) {
+                       if ( $tag == 'GPSTimeStamp' && count( $vals ) === 3) {
                                //hour min sec array
 
-                               $h = explode('/', $vals[0]);
-                               $m = explode('/', $vals[1]);
-                               $s = explode('/', $vals[2]);
+                               $h = explode( '/', $vals[0] );
+                               $m = explode( '/', $vals[1] );
+                               $s = explode( '/', $vals[2] );
 
                                // this should already be validated
                                // when loaded from file, but it could
                                // come from a foreign repo, so be
                                // paranoid.
-                               if ( !isset($h[1])
-                                       || !isset($m[1])
-                                       || !isset($s[1])
+                               if ( !isset( $h[1] )
+                                       || !isset( $m[1] )
+                                       || !isset( $s[1] )
                                        || $h[1] == 0
                                        || $m[1] == 0
                                        || $s[1] == 0
@@ -322,7 +322,7 @@ class FormatMetadata {
                                                if ( $subTag != 'fired' && $subValue == 0 ) {
                                                        continue;
                                                }
-                                               $fullTag = $tag . '-' . $subTag ;
+                                               $fullTag = $tag . '-' . $subTag;
                                                $flashMsgs[] = self::msg( $fullTag, $subValue );
                                        }
                                        $val = $wgLang->commaList( $flashMsgs );
@@ -631,7 +631,7 @@ class FormatMetadata {
                                case 'MaxApertureValue':
                                        if ( strpos( $val, '/' ) !== false ) {
                                                // need to expand this earlier to calculate fNumber
-                                               list($n, $d) = explode('/', $val);
+                                               list( $n, $d ) = explode( '/', $val );
                                                if ( is_numeric( $n ) && is_numeric( $d ) ) {
                                                        $val = $n / $d;
                                                }
@@ -809,7 +809,7 @@ class FormatMetadata {
 
                                case 'LanguageCode':
                                        $lang = Language::fetchLanguageName( strtolower( $val ), $wgLang->getCode() );
-                                       if ($lang) {
+                                       if ( $lang ) {
                                                $val = htmlspecialchars( $lang );
                                        } else {
                                                $val = htmlspecialchars( $val );
@@ -850,7 +850,7 @@ class FormatMetadata {
                }
 
                if ( !is_array( $vals ) ) {
-                        return $vals; // do nothing if not an array;
+                       return $vals; // do nothing if not an array;
                }
                elseif ( count( $vals ) === 1 && $type !== 'lang' ) {
                        return $vals[0];
@@ -899,7 +899,7 @@ class FormatMetadata {
                                        }
                                        $content .= self::langItem(
                                                $vals[$cLang], $cLang,
-                                                $isDefault, $noHtml );
+                                               $isDefault, $noHtml );
 
                                        unset( $vals[$cLang] );
                                }
@@ -915,8 +915,8 @@ class FormatMetadata {
                                }
                                if ( $defaultItem !== false ) {
                                        $content = self::langItem( $defaultItem,
-                                               $defaultLang, true, $noHtml )
-                                                . $content;
+                                               $defaultLang, true, $noHtml ) .
+                                               $content;
                                }
                                if ( $noHtml ) {
                                        return $content;
@@ -951,8 +951,8 @@ class FormatMetadata {
         */
        private static function langItem( $value, $lang, $default = false, $noHtml = false ) {
                if ( $lang === false && $default === false) {
-                       throw new MWException('$lang and $default cannot both '
-                               . 'be false.');
+                       throw new MWException( '$lang and $default cannot both '
+                               . 'be false.' );
                }
 
                if ( $noHtml ) {
@@ -1017,7 +1017,7 @@ class FormatMetadata {
        static function msg( $tag, $val, $arg = null, $arg2 = null ) {
                global $wgContLang;
 
-               if ($val === '')
+               if ( $val === '' )
                        $val = 'value';
                return wfMessage( $wgContLang->lc( "exif-$tag-$val" ), $arg, $arg2 )->text();
        }
@@ -1033,10 +1033,10 @@ class FormatMetadata {
        static function formatNum( $num, $round = false ) {
                global $wgLang;
                $m = array();
-               if( is_array($num) ) {
+               if( is_array( $num ) ) {
                        $out = array();
                        foreach( $num as $number ) {
-                               $out[] = self::formatNum($number);
+                               $out[] = self::formatNum( $number );
                        }
                        return $wgLang->commaList( $out );
                }
@@ -1120,13 +1120,13 @@ class FormatMetadata {
         * @param $val String: The 8 digit news code.
         * @return string The human readable form
         */
-       static private function convertNewsCode( $val ) {
+       private static function convertNewsCode( $val ) {
                if ( !preg_match( '/^\d{8}$/D', $val ) ) {
                        // Not a valid news code.
                        return $val;
                }
                $cat = '';
-               switch( substr( $val , 0, 2 ) ) {
+               switch( substr( $val, 0, 2 ) ) {
                        case '01':
                                $cat = 'ace';
                                break;
@@ -1238,7 +1238,7 @@ class FormatMetadata {
         * @return String of html-ish looking wikitext
         */
        public static function collapseContactInfo( $vals ) {
-               if( ! ( isset( $vals['CiAdrExtadr'] )
+               if( !( isset( $vals['CiAdrExtadr'] )
                        || isset( $vals['CiAdrCity'] )
                        || isset( $vals['CiAdrCtry'] )
                        || isset( $vals['CiEmailWork'] )
index da8fc6f..2e532fe 100644 (file)
@@ -39,7 +39,7 @@ class GIFHandler extends BitmapHandler {
                        return self::BROKEN_FILE;
                }
 
-               return serialize($parsedGIFMetadata);
+               return serialize( $parsedGIFMetadata );
        }
 
        /**
@@ -53,7 +53,7 @@ class GIFHandler extends BitmapHandler {
                        return false;
                }
                $meta = unserialize( $meta );
-                if ( !isset( $meta['metadata'] ) || count( $meta['metadata'] ) <= 1 ) {
+               if ( !isset( $meta['metadata'] ) || count( $meta['metadata'] ) <= 1 ) {
                        return false;
                }
 
@@ -85,7 +85,7 @@ class GIFHandler extends BitmapHandler {
        function isAnimatedImage( $image ) {
                $ser = $image->getMetadata();
                if ( $ser ) {
-                       $metadata = unserialize($ser);
+                       $metadata = unserialize( $ser );
                        if( $metadata['frameCount'] > 1 ) {
                                return true;
                        }
@@ -119,13 +119,13 @@ class GIFHandler extends BitmapHandler {
                wfRestoreWarnings();
 
                if ( !$data || !is_array( $data ) ) {
-                       wfDebug(__METHOD__ . ' invalid GIF metadata' );
+                       wfDebug( __METHOD__ . ' invalid GIF metadata' );
                        return self::METADATA_BAD;
                }
 
                if ( !isset( $data['metadata']['_MW_GIF_VERSION'] )
                        || $data['metadata']['_MW_GIF_VERSION'] != GIFMetadataExtractor::VERSION ) {
-                       wfDebug(__METHOD__ . ' old but compatible GIF metadata' );
+                       wfDebug( __METHOD__ . ' old but compatible GIF metadata' );
                        return self::METADATA_COMPATIBLE;
                }
                return self::METADATA_GOOD;
@@ -141,10 +141,10 @@ class GIFHandler extends BitmapHandler {
                $original = parent::getLongDesc( $image );
 
                wfSuppressWarnings();
-               $metadata = unserialize($image->getMetadata());
+               $metadata = unserialize( $image->getMetadata() );
                wfRestoreWarnings();
 
-               if (!$metadata || $metadata['frameCount'] <=  1) {
+               if ( !$metadata || $metadata['frameCount'] <= 1 ) {
                        return $original;
                }
 
index 7a162c3..8b44585 100644 (file)
@@ -49,9 +49,9 @@ class GIFMetadataExtractor {
         * @return array
         */
        static function getMetadata( $filename ) {
-               self::$gif_frame_sep = pack( "C", ord("," ) );
-               self::$gif_extension_sep = pack( "C", ord("!" ) );
-               self::$gif_term = pack( "C", ord(";" ) );
+               self::$gif_frame_sep = pack( "C", ord( "," ) );
+               self::$gif_extension_sep = pack( "C", ord( "!" ) );
+               self::$gif_term = pack( "C", ord( ";" ) );
 
                $frameCount = 0;
                $duration = 0.0;
@@ -73,7 +73,7 @@ class GIFMetadataExtractor {
 
                // Check for the GIF header
                $buf = fread( $fh, 6 );
-               if ( !($buf == 'GIF87a' || $buf == 'GIF89a') ) {
+               if ( !( $buf == 'GIF87a' || $buf == 'GIF89a' ) ) {
                        throw new Exception( "Not a valid GIF file; header: $buf" );
                }
 
@@ -93,7 +93,7 @@ class GIFMetadataExtractor {
                while( !feof( $fh ) ) {
                        $buf = fread( $fh, 1 );
 
-                       if ($buf == self::$gif_frame_sep) {
+                       if ( $buf == self::$gif_frame_sep ) {
                                // Found a frame
                                $frameCount++;
 
@@ -114,7 +114,7 @@ class GIFMetadataExtractor {
                                $extension_code = unpack( 'C', $buf );
                                $extension_code = $extension_code[1];
 
-                               if ($extension_code == 0xF9) {
+                               if ( $extension_code == 0xF9 ) {
                                        // Graphics Control Extension.
                                        fread( $fh, 1 ); // Block size
 
@@ -132,10 +132,10 @@ class GIFMetadataExtractor {
                                        if ( strlen( $term ) < 1 ) throw new Exception( "Ran out of input" );
                                        $term = unpack( 'C', $term );
                                        $term = $term[1];
-                                       if ($term != 0 ) {
+                                       if ( $term != 0 ) {
                                                throw new Exception( "Malformed Graphics Control Extension block" );
                                        }
-                               } elseif ($extension_code == 0xFE) {
+                               } elseif ( $extension_code == 0xFE ) {
                                        // Comment block(s).
                                        $data = self::readBlock( $fh );
                                        if ( $data === "" ) {
@@ -164,7 +164,7 @@ class GIFMetadataExtractor {
                                                // is identical to the last, only extract once.
                                                $comment[] = $data;
                                        }
-                               } elseif ($extension_code == 0xFF) {
+                               } elseif ( $extension_code == 0xFF ) {
                                        // Application extension (Netscape info about the animated gif)
                                        // or XMP (or theoretically any other type of extension block)
                                        $blockLength = fread( $fh, 1 );
@@ -173,7 +173,7 @@ class GIFMetadataExtractor {
                                        $blockLength = $blockLength[1];
                                        $data = fread( $fh, $blockLength );
 
-                                       if ($blockLength != 11 ) {
+                                       if ( $blockLength != 11 ) {
                                                wfDebug( __METHOD__ . ' GIF application block with wrong length' );
                                                fseek( $fh, -($blockLength + 1), SEEK_CUR );
                                                self::skipBlock( $fh );
@@ -184,7 +184,7 @@ class GIFMetadataExtractor {
                                        if ( $data == 'NETSCAPE2.0' ) {
                                                $data = fread( $fh, 2 ); // Block length and introduction, should be 03 01
 
-                                               if ($data != "\x03\x01") {
+                                               if ( $data != "\x03\x01" ) {
                                                        throw new Exception( "Expected \x03\x01, got $data" );
                                                }
 
@@ -194,7 +194,7 @@ class GIFMetadataExtractor {
                                                $loopData = unpack( 'v', $loopData );
                                                $loopCount = $loopData[1];
 
-                                               if ($loopCount != 1) {
+                                               if ( $loopCount != 1 ) {
                                                        $isLooped = true;
                                                }
 
@@ -231,7 +231,7 @@ class GIFMetadataExtractor {
                                if ( strlen( $buf ) < 1 ) throw new Exception( "Ran out of input" );
                                $byte = unpack( 'C', $buf );
                                $byte = $byte[1];
-                               throw new Exception( "At position: ".ftell($fh). ", Unknown byte ".$byte );
+                               throw new Exception( "At position: " . ftell( $fh ) . ", Unknown byte " . $byte );
                        }
                }
 
@@ -284,7 +284,7 @@ class GIFMetadataExtractor {
                        if ( strlen( $buf ) < 1 ) throw new Exception( "Ran out of input" );
                        $block_len = unpack( 'C', $buf );
                        $block_len = $block_len[1];
-                       if ($block_len == 0) {
+                       if ( $block_len == 0 ) {
                                return;
                        }
                        fread( $fh, $block_len );
index 8fd3552..06cbc3b 100644 (file)
@@ -41,15 +41,15 @@ class IPTC {
        static function parse( $rawData ) {
                $parsed = iptcparse( $rawData );
                $data = Array();
-               if (!is_array($parsed)) {
+               if ( !is_array( $parsed ) ) {
                                return $data;
                }
 
                $c = '';
                //charset info contained in tag 1:90.
-               if (isset($parsed['1#090']) && isset($parsed['1#090'][0])) {
-                       $c = self::getCharset($parsed['1#090'][0]);
-                       if ($c === false) {
+               if ( isset( $parsed['1#090'] ) && isset( $parsed['1#090'][0] ) ) {
+                       $c = self::getCharset( $parsed['1#090'][0] );
+                       if ( $c === false ) {
                                //Unknown charset. refuse to parse.
                                //note: There is a different between
                                //unknown and no charset specified.
@@ -59,8 +59,8 @@ class IPTC {
                }
 
                foreach ( $parsed as $tag => $val ) {
-                       if ( isset( $val[0] ) && trim($val[0]) == '' ) {
-                               wfDebugLog('iptc', "IPTC tag $tag had only whitespace as its value.");
+                       if ( isset( $val[0] ) && trim( $val[0] ) == '' ) {
+                               wfDebugLog( 'iptc', "IPTC tag $tag had only whitespace as its value." );
                                continue;
                        }
                        switch( $tag ) {
@@ -175,7 +175,7 @@ class IPTC {
                                        if ( isset( $parsed['2#070'] ) ) {
                                                //if a version is set for the software.
                                                $softwareVersion = self::convIPTC( $parsed['2#070'], $c );
-                                               unset($parsed['2#070']);
+                                               unset( $parsed['2#070'] );
                                                $data['Software'] = array( array( $software[0], $softwareVersion[0] ) );
                                        } else {
                                                $data['Software'] = $software;
@@ -227,8 +227,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeOriginal'] = $timestamp;
                                        }
                                        break;
@@ -241,8 +241,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeDigitized'] = $timestamp;
                                        }
                                        break;
@@ -254,8 +254,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeReleased'] = $timestamp;
                                        }
                                        break;
@@ -267,8 +267,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeExpires'] = $timestamp;
                                        }
                                        break;
@@ -313,7 +313,7 @@ class IPTC {
                                        // describing the subject matter of the content.
                                        $codes = self::convIPTC( $val, $c );
                                        foreach ( $codes as $ic ) {
-                                               $fields = explode(':', $ic, 3 );
+                                               $fields = explode( ':', $ic, 3 );
 
                                                if ( count( $fields ) < 2 ||
                                                        $fields[0] !== 'IPTC' )
@@ -362,31 +362,31 @@ class IPTC {
                if ( count( $date ) === 1 ) {
                        //the standard says this should always be 1
                        //just double checking.
-                       list($date) = self::convIPTC( $date, $c );
+                       list( $date ) = self::convIPTC( $date, $c );
                } else {
                        return null;
                }
 
                if ( count( $time ) === 1 ) {
-                       list($time) = self::convIPTC( $time, $c );
+                       list( $time ) = self::convIPTC( $time, $c );
                        $dateOnly = false;
                } else {
                        $time = '000000+0000'; //placeholder
                        $dateOnly = true;
                }
 
-               if ( ! ( preg_match('/\d\d\d\d\d\d[-+]\d\d\d\d/', $time)
-                       && preg_match('/\d\d\d\d\d\d\d\d/', $date)
-                       && substr($date, 0, 4) !== '0000'
-                       && substr($date, 4, 2) !== '00'
-                       && substr($date, 6, 2) !== '00'
-                ) ) {
+               if ( !( preg_match( '/\d\d\d\d\d\d[-+]\d\d\d\d/', $time )
+                       && preg_match( '/\d\d\d\d\d\d\d\d/', $date )
+                       && substr( $date, 0, 4 ) !== '0000'
+                       && substr( $date, 4, 2 ) !== '00'
+                       && substr( $date, 6, 2 ) !== '00'
+               ) ) {
                        //something wrong.
                        // Note, this rejects some valid dates according to iptc spec
                        // for example: the date 00000400 means the photo was taken in
                        // April, but the year and day is unknown. We don't process these
                        // types of incomplete dates atm.
-                       wfDebugLog( 'iptc', "IPTC: invalid time ( $time ) or date ( $date )");
+                       wfDebugLog( 'iptc', "IPTC: invalid time ( $time ) or date ( $date )" );
                        return null;
                }
 
@@ -425,7 +425,7 @@ class IPTC {
        */
        private static function convIPTC ( $data, $charset ) {
                if ( is_array( $data ) ) {
-                       foreach ($data as &$val) {
+                       foreach ( $data as &$val ) {
                                $val = self::convIPTCHelper( $val, $charset );
                        }
                } else {
@@ -444,18 +444,18 @@ class IPTC {
        private static function convIPTCHelper ( $data, $charset ) {
                if ( $charset ) {
                        wfSuppressWarnings();
-                       $data = iconv($charset, "UTF-8//IGNORE", $data);
+                       $data = iconv( $charset, "UTF-8//IGNORE", $data );
                        wfRestoreWarnings();
-                       if ($data === false) {
+                       if ( $data === false ) {
                                $data = "";
-                               wfDebugLog('iptc', __METHOD__ . " Error converting iptc data charset $charset to utf-8");
+                               wfDebugLog( 'iptc', __METHOD__ . " Error converting iptc data charset $charset to utf-8" );
                        }
                } else {
                        //treat as utf-8 if is valid utf-8. otherwise pretend its windows-1252
                        // most of the time if there is no 1:90 tag, it is either ascii, latin1, or utf-8
                        $oldData = $data;
                        UtfNormal::quickIsNFCVerify( $data ); //make $data valid utf-8
-                       if ($data === $oldData) {
+                       if ( $data === $oldData ) {
                                return $data; //if validation didn't change $data
                        } else {
                                return self::convIPTCHelper( $oldData, 'Windows-1252' );
@@ -472,7 +472,7 @@ class IPTC {
        * all iso 2022 escape codes. In practise, the code for utf-8 is the
        * only code that seems to have wide use. It does detect that code.
        */
-       static function getCharset($tag) {
+       static function getCharset( $tag ) {
 
                //According to iim standard, charset is defined by the tag 1:90.
                //in which there are iso 2022 escape sequences to specify the character set.
@@ -590,7 +590,7 @@ class IPTC {
                                $c = 'CSN_369103';
                                break;
                        default:
-                               wfDebugLog('iptc', __METHOD__ . 'Unknown charset in iptc 1:90: ' . bin2hex( $tag ) );
+                               wfDebugLog( 'iptc', __METHOD__ . 'Unknown charset in iptc 1:90: ' . bin2hex( $tag ) );
                                //at this point just give up and refuse to parse iptc?
                                $c = false;
                }
index 6175907..472372c 100644 (file)
@@ -162,11 +162,11 @@ abstract class ImageHandler extends MediaHandler {
 
                # Sanity check $width
                if( $width <= 0) {
-                       wfDebug( __METHOD__.": Invalid destination width: $width\n" );
+                       wfDebug( __METHOD__ . ": Invalid destination width: $width\n" );
                        return false;
                }
                if ( $srcWidth <= 0 ) {
-                       wfDebug( __METHOD__.": Invalid source width: $srcWidth\n" );
+                       wfDebug( __METHOD__ . ": Invalid source width: $srcWidth\n" );
                        return false;
                }
 
@@ -188,7 +188,7 @@ abstract class ImageHandler extends MediaHandler {
                if ( !$this->normaliseParams( $image, $params ) ) {
                        return false;
                }
-               $url = $script . '&' . wfArrayToCGI( $this->getScriptParams( $params ) );
+               $url = $script . '&' . wfArrayToCgi( $this->getScriptParams( $params ) );
 
                if( $image->mustRender() || $params['width'] < $image->getWidth() ) {
                        return new ThumbnailImage( $image, $url, false, $params );
index a15b652..5ea30f2 100644 (file)
@@ -37,7 +37,7 @@ class JpegHandler extends ExifBitmapHandler {
                        $meta = BitmapMetadataHandler::Jpeg( $filename );
                        if ( !is_array( $meta ) ) {
                                // This should never happen, but doesn't hurt to be paranoid.
-                               throw new MWException('Metadata array is not an array');
+                               throw new MWException( 'Metadata array is not an array' );
                        }
                        $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
                        return serialize( $meta );
@@ -60,4 +60,3 @@ class JpegHandler extends ExifBitmapHandler {
        }
 
 }
-
index dd764e9..46993e7 100644 (file)
@@ -46,7 +46,7 @@ abstract class MediaHandler {
        static function getHandler( $type ) {
                global $wgMediaHandlers;
                if ( !isset( $wgMediaHandlers[$type] ) ) {
-                       wfDebug( __METHOD__ . ": no handler found for $type.\n");
+                       wfDebug( __METHOD__ . ": no handler found for $type.\n" );
                        return false;
                }
                $class = $wgMediaHandlers[$type];
@@ -135,9 +135,9 @@ abstract class MediaHandler {
        */
        static function getMetadataVersion () {
                $version = Array( '2' ); // core metadata version
-               wfRunHooks('GetMetadataVersion', Array(&$version));
+               wfRunHooks( 'GetMetadataVersion', Array( &$version ) );
                return implode( ';', $version);
-        }
+       }
 
        /**
        * Convert metadata version.
@@ -365,7 +365,7 @@ abstract class MediaHandler {
         * @return array for use displaying metadata.
         */
        function formatMetadataHelper( $metadataArray ) {
-                $result = array(
+               $result = array(
                        'visible' => array(),
                        'collapsed' => array()
                );
index 7301df6..1fbe029 100644 (file)
@@ -198,10 +198,10 @@ abstract class MediaTransformOutput {
        public function getDescLinkAttribs( $title = null, $params = '' ) {
                $query = '';
                if ( $this->page && $this->page !== 1 ) {
-                         $query = 'page=' . urlencode( $this->page );
+                       $query = 'page=' . urlencode( $this->page );
                }
                if( $params ) {
-                       $query .= $query ? '&'.$params : $params;
+                       $query .= $query ? '&' . $params : $params;
                }
                $attribs = array(
                        'href' => $this->file->getTitle()->getLocalURL( $query ),
@@ -237,7 +237,7 @@ class ThumbnailImage extends MediaTransformOutput {
                # Previous parameters:
                #   $file, $url, $width, $height, $path = false, $page = false
 
-               if( is_array( $parameters ) ){
+               if( is_array( $parameters ) ) {
                        $defaults = array(
                                'page' => false
                        );
@@ -301,7 +301,7 @@ class ThumbnailImage extends MediaTransformOutput {
 
                $alt = empty( $options['alt'] ) ? '' : $options['alt'];
 
-               $query = empty( $options['desc-query'] )  ? '' : $options['desc-query'];
+               $query = empty( $options['desc-query'] ) ? '' : $options['desc-query'];
 
                if ( !empty( $options['custom-url-link'] ) ) {
                        $linkAttribs = array( 'href' => $options['custom-url-link'] );
@@ -404,7 +404,7 @@ class MediaTransformError extends MediaTransformOutput {
 class TransformParameterError extends MediaTransformError {
        function __construct( $params ) {
                parent::__construct( 'thumbnail_error',
-                       max( isset( $params['width']  ) ? $params['width']  : 0, 120 ),
+                       max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
                        max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
                        wfMessage( 'thumbnail_invalid_params' )->text() );
        }
index a23821f..b8a5b40 100644 (file)
@@ -44,7 +44,7 @@ class PNGHandler extends BitmapHandler {
                        return self::BROKEN_FILE;
                }
 
-               return serialize($metadata);
+               return serialize( $metadata );
        }
 
        /**
@@ -74,8 +74,8 @@ class PNGHandler extends BitmapHandler {
         */
        function isAnimatedImage( $image ) {
                $ser = $image->getMetadata();
-               if ($ser) {
-                       $metadata = unserialize($ser);
+               if ( $ser ) {
+                       $metadata = unserialize( $ser );
                        if( $metadata['frameCount'] > 1 ) return true;
                }
                return false;
@@ -105,13 +105,13 @@ class PNGHandler extends BitmapHandler {
                wfRestoreWarnings();
 
                if ( !$data || !is_array( $data ) ) {
-                       wfDebug(__METHOD__ . ' invalid png metadata' );
+                       wfDebug( __METHOD__ . ' invalid png metadata' );
                        return self::METADATA_BAD;
                }
 
                if ( !isset( $data['metadata']['_MW_PNG_VERSION'] )
                        || $data['metadata']['_MW_PNG_VERSION'] != PNGMetadataExtractor::VERSION ) {
-                       wfDebug(__METHOD__ . ' old but compatible png metadata' );
+                       wfDebug( __METHOD__ . ' old but compatible png metadata' );
                        return self::METADATA_COMPATIBLE;
                }
                return self::METADATA_GOOD;
@@ -126,7 +126,7 @@ class PNGHandler extends BitmapHandler {
                $original = parent::getLongDesc( $image );
 
                wfSuppressWarnings();
-               $metadata = unserialize($image->getMetadata());
+               $metadata = unserialize( $image->getMetadata() );
                wfRestoreWarnings();
 
                if( !$metadata || $metadata['frameCount'] <= 0 )
index 55f087a..87f705c 100644 (file)
@@ -417,7 +417,7 @@ class PNGMetadataExtractor {
         * @throws Exception if too big.
         * @return String The chunk.
         */
-       static private function read( $fh, $size ) {
+       private static function read( $fh, $size ) {
                if ( $size > self::MAX_CHUNK_SIZE ) {
                        throw new Exception( __METHOD__ . ': Chunk size of ' . $size .
                                ' too big. Max size is: ' . self::MAX_CHUNK_SIZE );
index f7e988f..cddab51 100644 (file)
@@ -170,14 +170,14 @@ class SvgHandler extends ImageHandler {
                                $cmd = str_replace(
                                        array( '$path/', '$width', '$height', '$input', '$output' ),
                                        array( $wgSVGConverterPath ? wfEscapeShellArg( "$wgSVGConverterPath/" ) : "",
-                                                  intval( $width ),
-                                                  intval( $height ),
-                                                  wfEscapeShellArg( $srcPath ),
-                                                  wfEscapeShellArg( $dstPath ) ),
+                                               intval( $width ),
+                                               intval( $height ),
+                                               wfEscapeShellArg( $srcPath ),
+                                               wfEscapeShellArg( $dstPath ) ),
                                        $wgSVGConverters[$wgSVGConverter]
                                ) . " 2>&1";
                                wfProfileIn( 'rsvg' );
-                               wfDebug( __METHOD__.": $cmd\n" );
+                               wfDebug( __METHOD__ . ": $cmd\n" );
                                $err = wfShellExec( $cmd, $retval );
                                wfProfileOut( 'rsvg' );
                        }
@@ -185,7 +185,7 @@ class SvgHandler extends ImageHandler {
                $removed = $this->removeBadFile( $dstPath, $retval );
                if ( $retval != 0 || $removed ) {
                        wfDebugLog( 'thumbnail', sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
-                                       wfHostname(), $retval, trim($err), $cmd ) );
+                                       wfHostname(), $retval, trim( $err ), $cmd ) );
                        return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
                }
                return true;
index 456c016..e4235a7 100644 (file)
@@ -67,7 +67,7 @@ class SVGReader {
                if ( $size > $wgSVGMetadataCutoff ) {
                        $this->debug( "SVG is $size bytes, which is bigger than $wgSVGMetadataCutoff. Truncating." );
                        $contents = file_get_contents( $source, false, null, -1, $wgSVGMetadataCutoff );
-                       if ($contents === false) {
+                       if ( $contents === false ) {
                                throw new MWException( 'Error reading SVG file.' );
                        }
                        $this->reader->XML( $contents, null, LIBXML_NOERROR | LIBXML_NOWARNING );
@@ -132,7 +132,7 @@ class SVGReader {
                $this->debug( "<svg> tag is correct." );
                $this->handleSVGAttribs();
 
-               $exitDepth =  $this->reader->depth;
+               $exitDepth = $this->reader->depth;
                $keepReading = $this->reader->read();
                while ( $keepReading ) {
                        $tag = $this->reader->localName;
@@ -187,7 +187,7 @@ class SVGReader {
                while( $keepReading ) {
                        if( $this->reader->localName == $name && $this->reader->namespaceURI == self::NS_SVG && $this->reader->nodeType == XmlReader::END_ELEMENT ) {
                                break;
-                       } elseif( $this->reader->nodeType == XmlReader::TEXT ){
+                       } elseif( $this->reader->nodeType == XmlReader::TEXT ) {
                                $this->metadata[$metafield] = trim( $this->reader->value );
                        }
                        $keepReading = $this->reader->read();
@@ -227,7 +227,7 @@ class SVGReader {
                if ( $this->reader->isEmptyElement ) {
                        return;
                }
-               $exitDepth =  $this->reader->depth;
+               $exitDepth = $this->reader->depth;
                $keepReading = $this->reader->read();
                while( $keepReading ) {
                        if( $this->reader->localName == $name && $this->reader->depth <= $exitDepth
@@ -285,9 +285,9 @@ class SVGReader {
                $width = null;
                $height = null;
 
-               if( $this->reader->getAttribute('viewBox') ) {
+               if( $this->reader->getAttribute( 'viewBox' ) ) {
                        // min-x min-y width height
-                       $viewBox = preg_split( '/\s+/', trim( $this->reader->getAttribute('viewBox') ) );
+                       $viewBox = preg_split( '/\s+/', trim( $this->reader->getAttribute( 'viewBox' ) ) );
                        if( count( $viewBox ) == 4 ) {
                                $viewWidth = $this->scaleSVGUnit( $viewBox[2] );
                                $viewHeight = $this->scaleSVGUnit( $viewBox[3] );
@@ -297,12 +297,12 @@ class SVGReader {
                                }
                        }
                }
-               if( $this->reader->getAttribute('width') ) {
-                       $width = $this->scaleSVGUnit( $this->reader->getAttribute('width'), $defaultWidth );
+               if( $this->reader->getAttribute( 'width' ) ) {
+                       $width = $this->scaleSVGUnit( $this->reader->getAttribute( 'width' ), $defaultWidth );
                        $this->metadata['originalWidth'] = $this->reader->getAttribute( 'width' );
                }
-               if( $this->reader->getAttribute('height') ) {
-                       $height = $this->scaleSVGUnit( $this->reader->getAttribute('height'), $defaultHeight );
+               if( $this->reader->getAttribute( 'height' ) ) {
+                       $height = $this->scaleSVGUnit( $this->reader->getAttribute( 'height' ), $defaultHeight );
                        $this->metadata['originalHeight'] = $this->reader->getAttribute( 'height' );
                }
 
@@ -329,7 +329,7 @@ class SVGReader {
         * @param $viewportSize: Float optional scale for percentage units...
         * @return float: length in pixels
         */
-       static function scaleSVGUnit( $length, $viewportSize=512 ) {
+       static function scaleSVGUnit( $length, $viewportSize = 512 ) {
                static $unitLength = array(
                        'px' => 1.0,
                        'pt' => 1.25,
index 55dff77..0042208 100644 (file)
@@ -82,7 +82,7 @@ class TiffHandler extends ExifBitmapHandler {
                                $meta = BitmapMetadataHandler::Tiff( $filename );
                                if ( !is_array( $meta ) ) {
                                        // This should never happen, but doesn't hurt to be paranoid.
-                                       throw new MWException('Metadata array is not an array');
+                                       throw new MWException( 'Metadata array is not an array' );
                                }
                                $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
                                return serialize( $meta );
index 555fa1f..ba0d419 100644 (file)
@@ -84,7 +84,7 @@ class XCFHandler extends BitmapHandler {
                # The image structure always starts at offset 0 in the XCF file.
                # So we just read it :-)
                $binaryHeader = fread( $f, 26 );
-               fclose($f);
+               fclose( $f );
 
                # Master image structure:
                #
index c5743d7..0decb75 100644 (file)
@@ -114,7 +114,7 @@ class XMPReader {
        */
        private function resetXMLParser() {
 
-               if ($this->xmlParser) {
+               if ( $this->xmlParser ) {
                        //is this needed?
                        xml_parser_free( $this->xmlParser );
                }
@@ -156,7 +156,7 @@ class XMPReader {
 
                $data = $this->results;
 
-               wfRunHooks('XMPGetResults', Array(&$data));
+               wfRunHooks( 'XMPGetResults', Array( &$data ) );
 
                if ( isset( $data['xmp-special']['AuthorsPosition'] )
                        && is_string( $data['xmp-special']['AuthorsPosition'] )
@@ -201,7 +201,7 @@ class XMPReader {
                                        // To avoid copying over the _type meta-fields.
                                        continue;
                                }
-                               foreach(  $loc as $field => $val ) {
+                               foreach( $loc as $field => $val ) {
                                        $data['xmp-general'][$field . 'Created'][] = $val;
                                }
                        }
@@ -255,7 +255,7 @@ class XMPReader {
                        if ( !$this->charset ) {
                                $bom = array();
                                if ( preg_match( '/\xEF\xBB\xBF|\xFE\xFF|\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\xFF\xFE/',
-                                        $content, $bom )
+                                       $content, $bom )
                                ) {
                                        switch ( $bom[0] ) {
                                                case "\xFE\xFF":
@@ -275,11 +275,8 @@ class XMPReader {
                                                        break;
                                                default:
                                                        //this should be impossible to get to
-                                                       throw new MWException("Invalid BOM");
-                                                       break;
-
+                                                       throw new MWException( "Invalid BOM" );
                                        }
-
                                } else {
                                        // standard specifically says, if no bom assume utf-8
                                        $this->charset = 'UTF-8';
@@ -324,13 +321,13 @@ class XMPReader {
                $guid = substr( $content, 0, 32 );
                if ( !isset( $this->results['xmp-special']['HasExtendedXMP'] )
                        || $this->results['xmp-special']['HasExtendedXMP'] !== $guid ) {
-                       wfDebugLog('XMP', __METHOD__ . " Ignoring XMPExtended block due to wrong guid (guid= '$guid' )");
+                       wfDebugLog( 'XMP', __METHOD__ . " Ignoring XMPExtended block due to wrong guid (guid= '$guid')" );
                        return false;
                }
-               $len  = unpack( 'Nlength/Noffset', substr( $content, 32, 8 ) );
+               $len = unpack( 'Nlength/Noffset', substr( $content, 32, 8 ) );
 
-               if (!$len || $len['length'] < 4 || $len['offset'] < 0 || $len['offset'] > $len['length'] ) {
-                       wfDebugLog('XMP', __METHOD__ . 'Error reading extended XMP block, invalid length or offset.');
+               if ( !$len || $len['length'] < 4 || $len['offset'] < 0 || $len['offset'] > $len['length'] ) {
+                       wfDebugLog( 'XMP', __METHOD__ . 'Error reading extended XMP block, invalid length or offset.' );
                        return false;
                }
 
@@ -345,8 +342,8 @@ class XMPReader {
                // so the probability that it will have > 128k, and be in the wrong order is very low...
 
                if ( $len['offset'] !== $this->extendedXMPOffset ) {
-                       wfDebugLog('XMP', __METHOD__ . 'Ignoring XMPExtended block due to wrong order. (Offset was '
-                               . $len['offset'] . ' but expected ' . $this->extendedXMPOffset . ')');
+                       wfDebugLog( 'XMP', __METHOD__ . 'Ignoring XMPExtended block due to wrong order. (Offset was '
+                               . $len['offset'] . ' but expected ' . $this->extendedXMPOffset . ')' );
                        return false;
                }
 
@@ -366,7 +363,7 @@ class XMPReader {
                        $atEnd = false;
                }
 
-               wfDebugLog('XMP', __METHOD__ . 'Parsing a XMPExtended block');
+               wfDebugLog( 'XMP', __METHOD__ . 'Parsing a XMPExtended block' );
                return $this->parse( $actualContent, $atEnd );
        }
 
@@ -421,13 +418,10 @@ class XMPReader {
        * @param $elm String Namespace of element followed by a space and then tag name of element.
        */
        private function endElementModeIgnore ( $elm ) {
-
                if ( $this->curItem[0] === $elm ) {
                        array_shift( $this->curItem );
                        array_shift( $this->mode );
                }
-               return;
-
        }
 
        /**
@@ -488,7 +482,7 @@ class XMPReader {
                if ( $this->curItem[0] !== $elm
                        && !( $elm === self::NS_RDF . ' Description'
                                && $this->mode[0] === self::MODE_STRUCT )
-                ) {
+               ) {
                        throw new MWException( "nesting mismatch. got a </$elm> but expected a </" . $this->curItem[0] . '>' );
                }
 
@@ -1035,7 +1029,7 @@ class XMPReader {
 
                if ( $elm === self::NS_RDF . ' RDF'
                        || $elm === 'adobe:ns:meta/ xmpmeta'
-                       || $elm === 'adobe:ns:meta/ xapmeta')
+                       || $elm === 'adobe:ns:meta/ xapmeta' )
                {
                        /* ignore. */
                        return;
@@ -1065,7 +1059,7 @@ class XMPReader {
 
                if ( count( $this->mode ) === 0 ) {
                        // This should not happen.
-                       throw new MWException('Error extracting XMP, '
+                       throw new MWException( 'Error extracting XMP, '
                                . "encountered <$elm> with no mode" );
                }
 
@@ -1103,7 +1097,6 @@ class XMPReader {
                                break;
                        default:
                                throw new MWException( 'StartElement in unknown mode: ' . $this->mode[0] );
-                               break;
                }
        }
 
index aa411df..a4ba741 100644 (file)
@@ -35,7 +35,7 @@ class XMPInfo {
                if( !self::$ranHooks ) {
                        // This is for if someone makes a custom metadata extension.
                        // For example, a medical wiki might want to decode DICOM xmp properties.
-                       wfRunHooks('XMPGetInfo', Array(&self::$items));
+                       wfRunHooks( 'XMPGetInfo', Array( &self::$items ) );
                        self::$ranHooks = true; // Only want to do this once.
                }
                return self::$items;
@@ -260,7 +260,7 @@ class XMPInfo {
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateDate',
                        ),
-                       'DateTimeDigitized' => array(  /* xmp:CreateDate */
+                       'DateTimeDigitized' => array( /* xmp:CreateDate */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateDate',
@@ -552,12 +552,12 @@ class XMPInfo {
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_LANG,
                        ),
-                       'DateTime'          => array(  /* proper prop is xmp:ModifyDate */
+                       'DateTime'          => array( /* proper prop is xmp:ModifyDate */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateDate',
                        ),
-                       'ImageDescription'  => array(  /* proper one is dc:description */
+                       'ImageDescription'  => array( /* proper one is dc:description */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_LANG,
                        ),
@@ -622,7 +622,7 @@ class XMPInfo {
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateInteger',
                        ),
-                       'Software'          => array(  /* see xmp:CreatorTool */
+                       'Software'          => array( /* see xmp:CreatorTool */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_SIMPLE,
                        ),
index e3fd59f..e2ae535 100644 (file)
@@ -95,8 +95,8 @@ class XMPValidate {
                        return;
                }
                if ( !preg_match( '/^[-+]?\d*(?:\.?\d*)$/D', $val )
-                       || !is_numeric($val)
-                ) {
+                       || !is_numeric( $val )
+               ) {
                        wfDebugLog( 'XMP', __METHOD__ . " Expected rating but got $val" );
                        $val = null;
                        return;
@@ -106,12 +106,12 @@ class XMPValidate {
                                // We do < 0 here instead of < -1 here, since
                                // the values between 0 and -1 are also illegal
                                // as -1 is meant as a special reject rating.
-                               wfDebugLog( 'XMP', __METHOD__ . " Rating too low, setting to -1 (Rejected)");
+                               wfDebugLog( 'XMP', __METHOD__ . " Rating too low, setting to -1 (Rejected)" );
                                $val = '-1';
                                return;
                        }
                        if ( $nVal > 5 ) {
-                               wfDebugLog( 'XMP', __METHOD__ . " Rating too high, setting to 5");
+                               wfDebugLog( 'XMP', __METHOD__ . " Rating too high, setting to 5" );
                                $val = '5';
                                return;
                        }
@@ -247,8 +247,8 @@ class XMPValidate {
                $res = array();
                if ( !preg_match(
                        /* ahh! scary regex... */
-                       '/^([0-3]\d{3})(?:-([01]\d)(?:-([0-3]\d)(?:T([0-2]\d):([0-6]\d)(?::([0-6]\d)(?:\.\d+)?)?([-+]\d{2}:\d{2}|Z)?)?)?)?$/D'
-                       , $val, $res)
+                       '/^([0-3]\d{3})(?:-([01]\d)(?:-([0-3]\d)(?:T([0-2]\d):([0-6]\d)(?::([0-6]\d)(?:\.\d+)?)?([-+]\d{2}:\d{2}|Z)?)?)?)?$/D',
+                       $val, $res )
                ) {
                        wfDebugLog( 'XMP', __METHOD__ . " Expected date but got $val" );
                        $val = null;
index 23471e9..9dc1c86 100644 (file)
@@ -26,7 +26,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index d9deb3c..adc3ef2 100644 (file)
@@ -25,7 +25,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
@@ -60,7 +60,7 @@ while( false !== ($line = fgets( $in ) ) ) {
 }
 fclose( $in );
 
-$out = fopen("Utf8Case.php", "wt");
+$out = fopen( "Utf8Case.php", "wt" );
 if( $out ) {
        $outUpperChars = escapeArray( $wikiUpperChars );
        $outLowerChars = escapeArray( $wikiLowerChars );
index 6eae6e7..c5c1be5 100644 (file)
 
 /** */
 
+if ( PHP_SAPI != 'cli' ) {
+       die( "Run me from the command line please.\n" );
+}
+
 require_once 'UtfNormalDefines.php';
 require_once 'UtfNormalUtil.php';
 require_once 'UtfNormal.php';
@@ -34,9 +38,6 @@ mb_internal_encoding( "utf-8" );
 
 $verbose = false;
 #$verbose = true;
-if( php_sapi_name() != 'cli' ) {
-       die( "Run me from the command line please.\n" );
-}
 
 $in = fopen( "UTF-8-test.txt", "rt" );
 if( !$in ) {
index 64d9618..f5b698a 100644 (file)
@@ -627,8 +627,8 @@ class UtfNormal {
                $lastHangul = 0;
                $startChar = '';
                $combining = '';
-               $x1 = ord(substr(UTF8_HANGUL_VBASE,0,1));
-               $x2 = ord(substr(UTF8_HANGUL_TEND,0,1));
+               $x1 = ord(substr(UTF8_HANGUL_VBASE, 0, 1));
+               $x2 = ord(substr(UTF8_HANGUL_TEND, 0, 1));
                for( $i = 0; $i < $len; $i++ ) {
                        $c = $string[$i];
                        $n = ord( $c );
index 6642844..89de929 100644 (file)
  * @ingroup UtfNormal
  */
 
+if( PHP_SAPI != 'cli' ) {
+       die( "Run me from the command line please.\n" );
+}
+
 if( isset( $_SERVER['argv'] ) && in_array( '--icu', $_SERVER['argv'] ) ) {
        dl( 'php_utfnormal.so' );
 }
@@ -34,10 +38,6 @@ require_once 'UtfNormal.php';
 
 define( 'BENCH_CYCLES', 5 );
 
-if( php_sapi_name() != 'cli' ) {
-       die( "Run me from the command line please.\n" );
-}
-
 $testfiles = array(
        'testdata/washington.txt' => 'English text',
        'testdata/berlin.txt' => 'German text',
@@ -80,7 +80,7 @@ function benchmarkTest( &$u, $filename, $desc ) {
        }
 }
 
-function benchTime(){
+function benchTime() {
        $st = explode( ' ', microtime() );
        return (float)$st[0] + (float)$st[1];
 }
index 64624b8..b07e339 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 define( 'UNICODE_HANGUL_FIRST', 0xac00 );
-define( 'UNICODE_HANGUL_LAST',  0xd7a3 );
+define( 'UNICODE_HANGUL_LAST', 0xd7a3 );
 
 define( 'UNICODE_HANGUL_LBASE', 0x1100 );
 define( 'UNICODE_HANGUL_VBASE', 0x1161 );
index 11d06d4..f392df5 100644 (file)
@@ -25,7 +25,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index 1277dc2..9732d76 100644 (file)
  * @ingroup UtfNormal
  */
 
+if( PHP_SAPI != 'cli' ) {
+       die( "Run me from the command line please.\n" );
+}
+
 if( isset( $_SERVER['argv'] ) && in_array( '--icu', $_SERVER['argv'] ) ) {
        dl( 'php_utfnormal.so' );
 }
@@ -38,10 +42,6 @@ define( 'BENCH_CYCLES', 1 );
 define( 'BIGSIZE', 1024 * 1024 * 10); // 10m
 ini_set('memory_limit', BIGSIZE + 120 * 1024 * 1024);
 
-if( php_sapi_name() != 'cli' ) {
-       die( "Run me from the command line please.\n" );
-}
-
 $testfiles = array(
        'testdata/washington.txt' => 'English text',
        'testdata/berlin.txt' => 'German text',
@@ -82,7 +82,7 @@ function benchmarkTest( &$u, $filename, $desc ) {
        }
 }
 
-function benchTime(){
+function benchTime() {
        $st = explode( ' ', microtime() );
        return (float)$st[0] + (float)$st[1];
 }
index 5872ec3..661e53f 100644 (file)
  * @ingroup UtfNormal
  */
 
+if( PHP_SAPI != 'cli' ) {
+       die( "Run me from the command line please.\n" );
+}
+
 $verbose = true;
 #define( 'PRETTY_UTF8', true );
 
@@ -54,10 +58,6 @@ require_once 'UtfNormalDefines.php';
 require_once 'UtfNormalUtil.php';
 require_once 'UtfNormal.php';
 
-if( php_sapi_name() != 'cli' ) {
-       die( "Run me from the command line please.\n" );
-}
-
 $in = fopen("NormalizationTest.txt", "rt");
 if( !$in ) {
        print "Couldn't open NormalizationTest.txt -- can't run tests.\n";
index 691bfaa..f4a8379 100644 (file)
@@ -22,7 +22,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index 03b0d5b..1205ceb 100644 (file)
@@ -89,7 +89,9 @@ abstract class BagOStuff {
        abstract public function delete( $key, $time = 0 );
 
        /**
-        * Merge changes into the existing cache value (possibly creating a new one)
+        * Merge changes into the existing cache value (possibly creating a new one).
+        * The callback function returns the new value given the current value (possibly false),
+        * and takes the arguments: (this BagOStuff object, cache key, current value).
         *
         * @param $key string
         * @param $callback closure Callback method to be executed
index b8a1bc2..960668f 100644 (file)
@@ -39,13 +39,13 @@ class EhcacheBagOStuff extends BagOStuff {
         */
        function __construct( $params ) {
                if ( !defined( 'CURLOPT_TIMEOUT_MS' ) ) {
-                       throw new MWException( __CLASS__.' requires curl version 7.16.2 or later.' );
+                       throw new MWException( __CLASS__ . ' requires curl version 7.16.2 or later.' );
                }
                if ( !extension_loaded( 'zlib' ) ) {
-                       throw new MWException( __CLASS__.' requires the zlib extension' );
+                       throw new MWException( __CLASS__ . ' requires the zlib extension' );
                }
                if ( !isset( $params['servers'] ) ) {
-                       throw new MWException( __METHOD__.': servers parameter is required' );
+                       throw new MWException( __METHOD__ . ': servers parameter is required' );
                }
                $this->servers = $params['servers'];
                $this->cacheName = isset( $params['cache'] ) ? $params['cache'] : 'mw';
@@ -76,7 +76,7 @@ class EhcacheBagOStuff extends BagOStuff {
                        return false;
                }
                if ( $response['http_code'] >= 300 ) {
-                       wfDebug( __METHOD__.": GET failure, got HTTP {$response['http_code']}\n" );
+                       wfDebug( __METHOD__ . ": GET failure, got HTTP {$response['http_code']}\n" );
                        wfProfileOut( __METHOD__ );
                        return false;
                }
@@ -85,7 +85,7 @@ class EhcacheBagOStuff extends BagOStuff {
                if ( $type == 'application/vnd.php.serialized+deflate' ) {
                        $body = gzinflate( $body );
                        if ( !$body ) {
-                               wfDebug( __METHOD__.": error inflating $key\n" );
+                               wfDebug( __METHOD__ . ": error inflating $key\n" );
                                wfProfileOut( __METHOD__ );
                                return false;
                        }
@@ -93,7 +93,7 @@ class EhcacheBagOStuff extends BagOStuff {
                } elseif ( $type == 'application/vnd.php.serialized' ) {
                        $data = unserialize( $body );
                } else {
-                       wfDebug( __METHOD__.": unknown content type \"$type\"\n" );
+                       wfDebug( __METHOD__ . ": unknown content type \"$type\"\n" );
                        wfProfileOut( __METHOD__ );
                        return false;
                }
@@ -127,7 +127,7 @@ class EhcacheBagOStuff extends BagOStuff {
                if ( $code == 404 ) {
                        // Maybe the cache does not exist yet, let's try creating it
                        if ( !$this->createCache( $key ) ) {
-                               wfDebug( __METHOD__.": cache creation failed\n" );
+                               wfDebug( __METHOD__ . ": cache creation failed\n" );
                                wfProfileOut( __METHOD__ );
                                return false;
                        }
@@ -136,9 +136,9 @@ class EhcacheBagOStuff extends BagOStuff {
 
                $result = false;
                if ( !$code ) {
-                       wfDebug( __METHOD__.": PUT failure for key $key\n" );
+                       wfDebug( __METHOD__ . ": PUT failure for key $key\n" );
                } elseif ( $code >= 300 ) {
-                       wfDebug( __METHOD__.": PUT failure for key $key: HTTP $code\n" );
+                       wfDebug( __METHOD__ . ": PUT failure for key $key: HTTP $code\n" );
                } else {
                        $result = true;
                }
@@ -172,7 +172,7 @@ class EhcacheBagOStuff extends BagOStuff {
                        array( CURLOPT_CUSTOMREQUEST => 'DELETE' ) );
                $code = isset( $response['http_code'] ) ? $response['http_code'] : 0;
                if ( !$response || ( $code != 404 && $code >= 300 ) ) {
-                       wfDebug( __METHOD__.": DELETE failure for key $key\n" );
+                       wfDebug( __METHOD__ . ": DELETE failure for key $key\n" );
                        $result = false;
                } else {
                        $result = true;
@@ -256,7 +256,7 @@ class EhcacheBagOStuff extends BagOStuff {
         * @return bool
         */
        protected function createCache( $key ) {
-               wfDebug( __METHOD__.": creating cache for $key\n" );
+               wfDebug( __METHOD__ . ": creating cache for $key\n" );
                $response = $this->doCacheRequest( $key,
                        array(
                                CURLOPT_POST => 1,
@@ -264,7 +264,7 @@ class EhcacheBagOStuff extends BagOStuff {
                                CURLOPT_POSTFIELDS => '',
                        ) );
                if ( !$response ) {
-                       wfDebug( __CLASS__.": failed to create cache for $key\n" );
+                       wfDebug( __CLASS__ . ": failed to create cache for $key\n" );
                        return false;
                }
                return ( $response['http_code'] == 201 /* created */
@@ -304,7 +304,7 @@ class EhcacheBagOStuff extends BagOStuff {
        protected function doRequest( $curl, $url, $curlOptions = array() ) {
                if ( array_diff_key( $curlOptions, $this->curlOptions ) ) {
                        // var_dump( array_diff_key( $curlOptions, $this->curlOptions ) );
-                       throw new MWException( __METHOD__.": to prevent options set in one doRequest() " .
+                       throw new MWException( __METHOD__ . ": to prevent options set in one doRequest() " .
                                "call from affecting subsequent doRequest() calls, only options listed " .
                                "in \$this->curlOptions may be specified in the \$curlOptions parameter." );
                }
@@ -314,7 +314,7 @@ class EhcacheBagOStuff extends BagOStuff {
                curl_setopt_array( $curl, $curlOptions );
                $result = curl_exec( $curl );
                if ( $result === false ) {
-                       wfDebug( __CLASS__.": curl error: " . curl_error( $curl ) . "\n" );
+                       wfDebug( __CLASS__ . ": curl error: " . curl_error( $curl ) . "\n" );
                        return false;
                }
                $info = curl_getinfo( $curl );
index d3f3583..d061eff 100644 (file)
@@ -110,4 +110,3 @@ class HashBagOStuff extends BagOStuff {
                return true;
        }
 }
-
index aebcbe7..4f8209d 100644 (file)
@@ -185,4 +185,3 @@ class MemcachedBagOStuff extends BagOStuff {
                wfDebugLog( 'memcached', $text );
        }
 }
-
index faa676d..2342d63 100644 (file)
@@ -991,7 +991,7 @@ class MWMemcached {
                $len = strlen( $val );
 
                if ( $this->_have_zlib && $this->_compress_enable &&
-                        $this->_compress_threshold && $len >= $this->_compress_threshold )
+                       $this->_compress_threshold && $len >= $this->_compress_threshold )
                {
                        $c_val = gzcompress( $val, 9 );
                        $c_len = strlen( $c_val );
index 5a9ee50..33a134c 100644 (file)
@@ -100,4 +100,3 @@ class MemcachedPhpBagOStuff extends MemcachedBagOStuff {
                return $this->client->decr( $this->encodeKey( $key ), $value );
        }
 }
-
index e4af262..eafa836 100644 (file)
@@ -123,7 +123,7 @@ class ObjectCache {
         * @return ObjectCache
         */
        static function newAccelerator( $params ) {
-               if ( function_exists( 'apc_fetch') ) {
+               if ( function_exists( 'apc_fetch' ) ) {
                        $id = 'apc';
                } elseif( function_exists( 'xcache_get' ) && wfIniGetBool( 'xcache.var_size' ) ) {
                        $id = 'xcache';
index bd5b354..2946407 100644 (file)
@@ -449,4 +449,3 @@ class RedisBagOStuff extends BagOStuff {
                        ( $result === false ? "failure" : "success" ) );
        }
 }
-
index 80c670e..5cc02d3 100644 (file)
@@ -127,7 +127,7 @@ class SqlBagOStuff extends BagOStuff {
                                $info = $this->serverInfos[$serverIndex];
                                $type = isset( $info['type'] ) ? $info['type'] : 'mysql';
                                $host = isset( $info['host'] ) ? $info['host'] : '[unknown]';
-                               wfDebug( __CLASS__.": connecting to $host\n" );
+                               wfDebug( __CLASS__ . ": connecting to $host\n" );
                                $db = DatabaseBase::factory( $type, $info );
                                $db->clearFlag( DBO_TRX );
                        } else {
@@ -324,28 +324,28 @@ class SqlBagOStuff extends BagOStuff {
         * @return bool
         */
        public function cas( $casToken, $key, $value, $exptime = 0 ) {
-               $db = $this->getDB();
-               $exptime = intval( $exptime );
-
-               if ( $exptime < 0 ) {
-                       $exptime = 0;
-               }
+               list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
+               try {
+                       $db = $this->getDB( $serverIndex );
+                       $exptime = intval( $exptime );
 
-               if ( $exptime == 0 ) {
-                       $encExpiry = $this->getMaxDateTime();
-               } else {
-                       if ( $exptime < 3.16e8 ) { # ~10 years
-                               $exptime += time();
+                       if ( $exptime < 0 ) {
+                               $exptime = 0;
                        }
 
-                       $encExpiry = $db->timestamp( $exptime );
-               }
-               try {
+                       if ( $exptime == 0 ) {
+                               $encExpiry = $this->getMaxDateTime( $db );
+                       } else {
+                               if ( $exptime < 3.16e8 ) { # ~10 years
+                                       $exptime += time();
+                               }
+                               $encExpiry = $db->timestamp( $exptime );
+                       }
                        $db->begin( __METHOD__ );
                        // (bug 24425) use a replace if the db supports it instead of
                        // delete/insert to avoid clashes with conflicting keynames
                        $db->update(
-                               $this->getTableByKey( $key ),
+                               $tableName,
                                array(
                                        'keyname' => $key,
                                        'value' => $db->encodeBlob( $this->serialize( $value ) ),
@@ -354,7 +354,9 @@ class SqlBagOStuff extends BagOStuff {
                                array(
                                        'keyname' => $key,
                                        'value' => $db->encodeBlob( $this->serialize( $casToken ) )
-                               ), __METHOD__ );
+                               ),
+                               __METHOD__
+                       );
                        $db->commit( __METHOD__ );
                } catch ( DBQueryError $e ) {
                        $this->handleWriteError( $e );
@@ -659,12 +661,12 @@ class SqlBagOStuff extends BagOStuff {
                                unset( $this->connFailureTimes[$serverIndex] );
                                unset( $this->connFailureErrors[$serverIndex] );
                        } else {
-                               wfDebug( __METHOD__.": Server #$serverIndex already down\n" );
+                               wfDebug( __METHOD__ . ": Server #$serverIndex already down\n" );
                                return;
                        }
                }
                $now = time();
-               wfDebug( __METHOD__.": Server #$serverIndex down until " . ( $now + 60 ) . "\n" );
+               wfDebug( __METHOD__ . ": Server #$serverIndex down until " . ( $now + 60 ) . "\n" );
                $this->connFailureTimes[$serverIndex] = $now;
                $this->connFailureErrors[$serverIndex] = $exception;
        }
@@ -697,4 +699,3 @@ class SqlBagOStuff extends BagOStuff {
  * Backwards compatibility alias
  */
 class MediaWikiBagOStuff extends SqlBagOStuff { }
-
index 4bfa9d3..1cabf76 100644 (file)
@@ -47,15 +47,15 @@ class CoreLinkFunctions {
         */
        static function defaultLinkHook( $parser, $holders, $markers,
                        Title $title, $titleText, &$displayText = null, &$leadingColon = false ) {
-               if( isset($displayText) && $markers->findMarker( $displayText ) ) {
+               if( isset( $displayText ) && $markers->findMarker( $displayText ) ) {
                        # There are links inside of the displayText
                        # For backwards compatibility the deepest links are dominant so this
                        # link should not be handled
-                       $displayText = $markers->expand($displayText);
+                       $displayText = $markers->expand( $displayText );
                        # Return false so that this link is reverted back to WikiText
                        return false;
                }
-               return $holders->makeHolder( $title, isset($displayText) ? $displayText : $titleText, array(), '', '' );
+               return $holders->makeHolder( $title, isset( $displayText ) ? $displayText : $titleText, array(), '', '' );
        }
 
        /**
@@ -73,15 +73,15 @@ class CoreLinkFunctions {
                global $wgContLang;
                # When a category link starts with a : treat it as a normal link
                if( $leadingColon ) return true;
-               if( isset($sortText) && $markers->findMarker( $sortText ) ) {
+               if( isset( $sortText ) && $markers->findMarker( $sortText ) ) {
                        # There are links inside of the sortText
                        # For backwards compatibility the deepest links are dominant so this
                        # link should not be handled
-                       $sortText = $markers->expand($sortText);
+                       $sortText = $markers->expand( $sortText );
                        # Return false so that this link is reverted back to WikiText
                        return false;
                }
-               if( !isset($sortText) ) $sortText = $parser->getDefaultSort();
+               if( !isset( $sortText ) ) $sortText = $parser->getDefaultSort();
                $sortText = Sanitizer::decodeCharReferences( $sortText );
                $sortText = str_replace( "\n", '', $sortText );
                $sortText = $wgContLang->convertCategoryKey( $sortText );
index fa934d7..b2a72a4 100644 (file)
@@ -422,7 +422,7 @@ class CoreParserFunctions {
                return self::formatRaw( SiteStats::images(), $raw );
        }
        static function numberofadmins( $parser, $raw = null ) {
-               return self::formatRaw( SiteStats::numberingroup('sysop'), $raw );
+               return self::formatRaw( SiteStats::numberingroup( 'sysop' ), $raw );
        }
        static function numberofedits( $parser, $raw = null ) {
                return self::formatRaw( SiteStats::edits(), $raw );
@@ -662,11 +662,12 @@ class CoreParserFunctions {
                        $length = $cache[$page];
                } elseif( $parser->incrementExpensiveFunctionCount() ) {
                        $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
-                       $id = $rev ? $rev->getPage() : 0;
+                       $pageID = $rev ? $rev->getPage() : 0;
+                       $revID = $rev ? $rev->getId() : 0;
                        $length = $cache[$page] = $rev ? $rev->getSize() : 0;
 
                        // Register dependency in templatelinks
-                       $parser->mOutput->addTemplate( $title, $id, $rev ? $rev->getId() : 0 );
+                       $parser->mOutput->addTemplate( $title, $pageID, $revID );
                }
                return self::formatRaw( $length, $raw );
        }
@@ -799,7 +800,7 @@ class CoreParserFunctions {
 
        // Usage {{filepath|300}}, {{filepath|nowiki}}, {{filepath|nowiki|300}} or {{filepath|300|nowiki}}
        // or {{filepath|300px}}, {{filepath|200x300px}}, {{filepath|nowiki|200x300px}}, {{filepath|200x300px|nowiki}}
-       public static function filepath( $parser, $name='', $argA='', $argB='' ) {
+       public static function filepath( $parser, $name = '', $argA = '', $argB = '' ) {
                $file = wfFindFile( $name );
 
                if( $argA == 'nowiki' ) {
index 0f22675..88d68a7 100644 (file)
@@ -102,11 +102,11 @@ class DateFormatter {
 
                # Rules
                #            pref    source       target
-               $this->rules[self::DMY][self::MD]       = self::DM;
-               $this->rules[self::ALL][self::MD]       = self::MD;
-               $this->rules[self::MDY][self::DM]       = self::MD;
-               $this->rules[self::ALL][self::DM]       = self::DM;
-               $this->rules[self::NONE][self::ISO2]    = self::ISO1;
+               $this->rules[self::DMY][self::MD] = self::DM;
+               $this->rules[self::ALL][self::MD] = self::MD;
+               $this->rules[self::MDY][self::DM] = self::MD;
+               $this->rules[self::ALL][self::DM] = self::DM;
+               $this->rules[self::NONE][self::ISO2] = self::ISO1;
 
                $this->preferences = array(
                        'default' => self::NONE,
@@ -145,7 +145,7 @@ class DateFormatter {
         * @param $options Array: can contain 'linked' and/or 'match-whole'
         * @return mixed|String
         */
-       function reformat( $preference, $text, $options = array('linked') ) {
+       function reformat( $preference, $text, $options = array( 'linked' ) ) {
                $linked = in_array( 'linked', $options );
                $match_whole = in_array( 'match-whole', $options );
 
@@ -172,21 +172,21 @@ class DateFormatter {
                        $regex = $this->regexes[$i];
 
                        // Horrible hack
-                       if (!$linked) {
+                       if ( !$linked ) {
                                $regex = str_replace( array( '\[\[', '\]\]' ), '', $regex );
                        }
 
-                       if ($match_whole) {
+                       if ( $match_whole ) {
                                // Let's hope this works
                                $regex = preg_replace( '!^/!', '/^', $regex );
                                $regex = str_replace( $this->regexTrail,
-                                       '$'.$this->regexTrail, $regex );
+                                       '$' . $this->regexTrail, $regex );
                        }
 
                        // Another horrible hack
                        $this->mLinked = $linked;
                        $text = preg_replace_callback( $regex, array( &$this, 'replace' ), $text );
-                       unset($this->mLinked);
+                       unset( $this->mLinked );
                }
                return $text;
        }
@@ -203,7 +203,7 @@ class DateFormatter {
 
                $bits = array();
                $key = $this->keys[$this->mSource];
-               for ( $p=0; $p < strlen($key); $p++ ) {
+               for ( $p=0; $p < strlen( $key ); $p++ ) {
                        if ( $key[$p] != ' ' ) {
                                $bits[$key[$p]] = $matches[$p+1];
                        }
@@ -220,7 +220,7 @@ class DateFormatter {
        function formatDate( $bits, $link = true ) {
                $format = $this->targets[$this->mTarget];
 
-               if (!$link) {
+               if ( !$link ) {
                        // strip piped links
                        $format = preg_replace( '/\[\[[^|]+\|([^\]]+)\]\]/', '$1', $format );
                        // strip remaining links
@@ -246,7 +246,7 @@ class DateFormatter {
                        }
                }
 
-               if ( !isset($bits['d']) ) {
+               if ( !isset( $bits['d'] ) ) {
                        $bits['d'] = sprintf( '%02d', $bits['j'] );
                }
 
@@ -263,7 +263,7 @@ class DateFormatter {
                                        $text .= $bits['y'];
                                        break;
                                case 'j': # ordinary day of month
-                                       if ( !isset($bits['j']) ) {
+                                       if ( !isset( $bits['j'] ) ) {
                                                $text .= intval( $bits['d'] );
                                        } else {
                                                $text .= $bits['j'];
@@ -271,7 +271,7 @@ class DateFormatter {
                                        break;
                                case 'F': # long month
                                        if ( !isset( $bits['F'] ) ) {
-                                               $m = intval($bits['m']);
+                                               $m = intval( $bits['m'] );
                                                if ( $m > 12 || $m < 1 ) {
                                                        $fail = true;
                                                } else {
@@ -293,7 +293,7 @@ class DateFormatter {
                }
 
                $isoBits = array();
-               if ( isset($bits['y']) )
+               if ( isset( $bits['y'] ) )
                        $isoBits[] = $bits['y'];
                $isoBits[] = $bits['m'];
                $isoBits[] = $bits['d'];
index 083bd29..ff1e0af 100644 (file)
@@ -215,9 +215,9 @@ class LinkHolderArray {
         * @param $prefix String [optional]
         * @return string
         */
-       function makeHolder( $nt, $text = '', $query = array(), $trail = '', $prefix = ''  ) {
+       function makeHolder( $nt, $text = '', $query = array(), $trail = '', $prefix = '' ) {
                wfProfileIn( __METHOD__ );
-               if ( ! is_object($nt) ) {
+               if ( !is_object( $nt ) ) {
                        # Fail gracefully
                        $retVal = "<!-- ERROR -->{$prefix}{$text}{$trail}";
                } else {
@@ -226,7 +226,7 @@ class LinkHolderArray {
 
                        $entry = array(
                                'title' => $nt,
-                               'text' => $prefix.$text.$inside,
+                               'text' => $prefix . $text . $inside,
                                'pdbk' => $nt->getPrefixedDBkey(),
                        );
                        if ( $query !== array() ) {
@@ -281,7 +281,7 @@ class LinkHolderArray {
                $linkCache = LinkCache::singleton();
                $output = $this->parent->getOutput();
 
-               wfProfileIn( __METHOD__.'-check' );
+               wfProfileIn( __METHOD__ . '-check' );
                $dbr = wfGetDB( DB_SLAVE );
                $threshold = $this->parent->getOptions()->getStubThreshold();
 
@@ -322,7 +322,7 @@ class LinkHolderArray {
                }
                if ( $queries ) {
                        $where = array();
-                       foreach( $queries as $ns => $pages ){
+                       foreach( $queries as $ns => $pages ) {
                                $where[] = $dbr->makeList(
                                        array(
                                                'page_namespace' => $ns,
@@ -355,19 +355,19 @@ class LinkHolderArray {
                        }
                        unset( $res );
                }
-               if ( count($linkcolour_ids) ) {
+               if ( count( $linkcolour_ids ) ) {
                        //pass an array of page_ids to an extension
                        wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
                }
-               wfProfileOut( __METHOD__.'-check' );
+               wfProfileOut( __METHOD__ . '-check' );
 
                # Do a second query for different language variants of links and categories
-               if($wgContLang->hasVariants()) {
+               if( $wgContLang->hasVariants() ) {
                        $this->doVariants( $colours );
                }
 
                # Construct search and replace arrays
-               wfProfileIn( __METHOD__.'-construct' );
+               wfProfileIn( __METHOD__ . '-construct' );
                $replacePairs = array();
                foreach ( $this->internals as $ns => $entries ) {
                        foreach ( $entries as $index => $entry ) {
@@ -399,16 +399,16 @@ class LinkHolderArray {
                        }
                }
                $replacer = new HashtableReplacer( $replacePairs, 1 );
-               wfProfileOut( __METHOD__.'-construct' );
+               wfProfileOut( __METHOD__ . '-construct' );
 
                # Do the thing
-               wfProfileIn( __METHOD__.'-replace' );
+               wfProfileIn( __METHOD__ . '-replace' );
                $text = preg_replace_callback(
                        '/(<!--LINK .*?-->)/',
                        $replacer->cb(),
                        $text);
 
-               wfProfileOut( __METHOD__.'-replace' );
+               wfProfileOut( __METHOD__ . '-replace' );
                wfProfileOut( __METHOD__ );
        }
 
@@ -514,7 +514,7 @@ class LinkHolderArray {
                }
 
 
-               if(!$linkBatch->isEmpty()){
+               if( !$linkBatch->isEmpty() ) {
                        // construct query
                        $dbr = wfGetDB( DB_SLAVE );
                        $varRes = $dbr->select( 'page',
@@ -570,16 +570,18 @@ class LinkHolderArray {
                        wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
 
                        // rebuild the categories in original order (if there are replacements)
-                       if(count($varCategories)>0){
+                       if( count( $varCategories ) > 0 ) {
                                $newCats = array();
                                $originalCats = $output->getCategories();
-                               foreach($originalCats as $cat => $sortkey){
+                               foreach( $originalCats as $cat => $sortkey ) {
                                        // make the replacement
-                                       if( array_key_exists($cat,$varCategories) )
+                                       if( array_key_exists( $cat, $varCategories ) ) {
                                                $newCats[$varCategories[$cat]] = $sortkey;
-                                       else $newCats[$cat] = $sortkey;
+                                       } else {
+                                               $newCats[$cat] = $sortkey;
+                                       }
                                }
-                               $output->setCategoryLinks($newCats);
+                               $output->setCategoryLinks( $newCats );
                        }
                }
        }
index d47ccb9..ed5071e 100644 (file)
@@ -62,7 +62,6 @@
  * $wgAllowSpecialInclusion
  * $wgInterwikiMagic
  * $wgMaxArticleSize
- * $wgUseDynamicDates
  *
  * @ingroup Parser
  */
@@ -215,8 +214,8 @@ class Parser {
        public function __construct( $conf = array() ) {
                $this->mConf = $conf;
                $this->mUrlProtocols = wfUrlProtocols();
-               $this->mExtLinkBracketedRegex = '/\[(((?i)' . $this->mUrlProtocols . ')'.
-                       self::EXT_LINK_URL_CLASS.'+)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/Su';
+               $this->mExtLinkBracketedRegex = '/\[(((?i)' . $this->mUrlProtocols . ')' .
+                       self::EXT_LINK_URL_CLASS . '+)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/Su';
                if ( isset( $conf['preprocessorClass'] ) ) {
                        $this->mPreprocessorClass = $conf['preprocessorClass'];
                } elseif ( defined( 'MW_COMPILED' ) ) {
@@ -357,7 +356,7 @@ class Parser {
                 */
 
                global $wgUseTidy, $wgAlwaysUseTidy;
-               $fname = __METHOD__.'-' . wfGetCaller();
+               $fname = __METHOD__ . '-' . wfGetCaller();
                wfProfileIn( __METHOD__ );
                wfProfileIn( $fname );
 
@@ -499,8 +498,8 @@ class Parser {
                                "Preprocessor generated node count: " .
                                        "{$this->mGeneratedPPNodeCount}/{$this->mOptions->getMaxGeneratedPPNodeCount()}\n" .
                                "Post-expand include size: {$this->mIncludeSizes['post-expand']}/$max bytes\n" .
-                               "Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n".
-                               "Highest expansion depth: {$this->mHighestExpansionDepth}/{$this->mOptions->getMaxPPExpandDepth()}\n".
+                               "Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n" .
+                               "Highest expansion depth: {$this->mHighestExpansionDepth}/{$this->mOptions->getMaxPPExpandDepth()}\n" .
                                $PFreport;
                        wfRunHooks( 'ParserLimitReport', array( $this, &$limitReport ) );
                        $text .= "\n<!-- \n$limitReport-->\n";
@@ -606,7 +605,7 @@ class Parser {
         *
         * @return string
         */
-       static public function getRandomString() {
+       public static function getRandomString() {
                return wfRandomString( 16 );
        }
 
@@ -937,33 +936,33 @@ class Parser {
                        $line = trim( $outLine );
 
                        if ( $line === '' ) { # empty line, go to next line
-                               $out .= $outLine."\n";
+                               $out .= $outLine . "\n";
                                continue;
                        }
 
                        $first_character = $line[0];
                        $matches = array();
 
-                       if ( preg_match( '/^(:*)\{\|(.*)$/', $line , $matches ) ) {
+                       if ( preg_match( '/^(:*)\{\|(.*)$/', $line, $matches ) ) {
                                # First check if we are starting a new table
                                $indent_level = strlen( $matches[1] );
 
                                $attributes = $this->mStripState->unstripBoth( $matches[2] );
-                               $attributes = Sanitizer::fixTagAttributes( $attributes , 'table' );
-
-                               $outLine = str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>";
-                               array_push( $td_history , false );
-                               array_push( $last_tag_history , '' );
-                               array_push( $tr_history , false );
-                               array_push( $tr_attributes , '' );
-                               array_push( $has_opened_tr , false );
+                               $attributes = Sanitizer::fixTagAttributes( $attributes, 'table' );
+
+                               $outLine = str_repeat( '<dl><dd>', $indent_level ) . "<table{$attributes}>";
+                               array_push( $td_history, false );
+                               array_push( $last_tag_history, '' );
+                               array_push( $tr_history, false );
+                               array_push( $tr_attributes, '' );
+                               array_push( $has_opened_tr, false );
                        } elseif ( count( $td_history ) == 0 ) {
                                # Don't do any of the following
-                               $out .= $outLine."\n";
+                               $out .= $outLine . "\n";
                                continue;
-                       } elseif ( substr( $line , 0 , 2 ) === '|}' ) {
+                       } elseif ( substr( $line, 0, 2 ) === '|}' ) {
                                # We are ending a table
-                               $line = '</table>' . substr( $line , 2 );
+                               $line = '</table>' . substr( $line, 2 );
                                $last_tag = array_pop( $last_tag_history );
 
                                if ( !array_pop( $has_opened_tr ) ) {
@@ -978,8 +977,8 @@ class Parser {
                                        $line = "</{$last_tag}>{$line}";
                                }
                                array_pop( $tr_attributes );
-                               $outLine = $line . str_repeat( '</dd></dl>' , $indent_level );
-                       } elseif ( substr( $line , 0 , 2 ) === '|-' ) {
+                               $outLine = $line . str_repeat( '</dd></dl>', $indent_level );
+                       } elseif ( substr( $line, 0, 2 ) === '|-' ) {
                                # Now we have a table row
                                $line = preg_replace( '#^\|-+#', '', $line );
 
@@ -992,7 +991,7 @@ class Parser {
                                $line = '';
                                $last_tag = array_pop( $last_tag_history );
                                array_pop( $has_opened_tr );
-                               array_push( $has_opened_tr , true );
+                               array_push( $has_opened_tr, true );
 
                                if ( array_pop( $tr_history ) ) {
                                        $line = '</tr>';
@@ -1003,27 +1002,27 @@ class Parser {
                                }
 
                                $outLine = $line;
-                               array_push( $tr_history , false );
-                               array_push( $td_history , false );
-                               array_push( $last_tag_history , '' );
-                       } elseif ( $first_character === '|' || $first_character === '!' || substr( $line , 0 , 2 )  === '|+' ) {
+                               array_push( $tr_history, false );
+                               array_push( $td_history, false );
+                               array_push( $last_tag_history, '' );
+                       } elseif ( $first_character === '|' || $first_character === '!' || substr( $line, 0, 2 )  === '|+' ) {
                                # This might be cell elements, td, th or captions
-                               if ( substr( $line , 0 , 2 ) === '|+' ) {
+                               if ( substr( $line, 0, 2 ) === '|+' ) {
                                        $first_character = '+';
-                                       $line = substr( $line , 1 );
+                                       $line = substr( $line, 1 );
                                }
 
-                               $line = substr( $line , 1 );
+                               $line = substr( $line, 1 );
 
                                if ( $first_character === '!' ) {
-                                       $line = str_replace( '!!' , '||' , $line );
+                                       $line = str_replace( '!!', '||', $line );
                                }
 
                                # Split up multiple cells on the same line.
                                # FIXME : This can result in improper nesting of tags processed
                                # by earlier parser steps, but should avoid splitting up eg
                                # attribute values containing literal "||".
-                               $cells = StringUtils::explodeMarkup( '||' , $line );
+                               $cells = StringUtils::explodeMarkup( '||', $line );
 
                                $outLine = '';
 
@@ -1035,10 +1034,10 @@ class Parser {
                                                if ( !array_pop( $tr_history ) ) {
                                                        $previous = "<tr{$tr_after}>\n";
                                                }
-                                               array_push( $tr_history , true );
-                                               array_push( $tr_attributes , '' );
+                                               array_push( $tr_history, true );
+                                               array_push( $tr_attributes, '' );
                                                array_pop( $has_opened_tr );
-                                               array_push( $has_opened_tr , true );
+                                               array_push( $has_opened_tr, true );
                                        }
 
                                        $last_tag = array_pop( $last_tag_history );
@@ -1057,10 +1056,10 @@ class Parser {
                                                $last_tag = '';
                                        }
 
-                                       array_push( $last_tag_history , $last_tag );
+                                       array_push( $last_tag_history, $last_tag );
 
                                        # A cell could contain both parameters and data
-                                       $cell_data = explode( '|' , $cell , 2 );
+                                       $cell_data = explode( '|', $cell, 2 );
 
                                        # Bug 553: Note that a '|' inside an invalid link should not
                                        # be mistaken as delimiting cell parameters
@@ -1070,12 +1069,12 @@ class Parser {
                                                $cell = "{$previous}<{$last_tag}>{$cell_data[0]}";
                                        } else {
                                                $attributes = $this->mStripState->unstripBoth( $cell_data[0] );
-                                               $attributes = Sanitizer::fixTagAttributes( $attributes , $last_tag );
+                                               $attributes = Sanitizer::fixTagAttributes( $attributes, $last_tag );
                                                $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}";
                                        }
 
                                        $outLine .= $cell;
-                                       array_push( $td_history , true );
+                                       array_push( $td_history, true );
                                }
                        }
                        $out .= $outLine . "\n";
@@ -1090,7 +1089,7 @@ class Parser {
                                $out .= "</tr>\n";
                        }
                        if ( !array_pop( $has_opened_tr ) ) {
-                               $out .= "<tr><td></td></tr>\n" ;
+                               $out .= "<tr><td></td></tr>\n";
                        }
 
                        $out .= "</table>\n";
@@ -1131,7 +1130,7 @@ class Parser {
                # Hook to suspend the parser in this state
                if ( !wfRunHooks( 'ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ) ) ) {
                        wfProfileOut( __METHOD__ );
-                       return $text ;
+                       return $text;
                }
 
                # if $frame is provided, then use $frame for replacing any variables
@@ -1165,17 +1164,13 @@ class Parser {
                $text = $this->doDoubleUnderscore( $text );
 
                $text = $this->doHeadings( $text );
-               if ( $this->mOptions->getUseDynamicDates() ) {
-                       $df = DateFormatter::getInstance();
-                       $text = $df->reformat( $this->mOptions->getDateFormat(), $text );
-               }
                $text = $this->replaceInternalLinks( $text );
                $text = $this->doAllQuotes( $text );
                $text = $this->replaceExternalLinks( $text );
 
                # replaceInternalLinks may sometimes leave behind
                # absolute URLs, which have to be masked to hide them from replaceExternalLinks
-               $text = str_replace( $this->mUniqPrefix.'NOPARSE', '', $text );
+               $text = str_replace( $this->mUniqPrefix . 'NOPARSE', '', $text );
 
                $text = $this->doMagicLinks( $text );
                $text = $this->formatHeadings( $text, $origText, $isMain );
@@ -1243,7 +1238,7 @@ class Parser {
                                $CssClass = 'mw-magiclink-pmid';
                                $id = $m[4];
                        } else {
-                               throw new MWException( __METHOD__.': unrecognised match type "' .
+                               throw new MWException( __METHOD__ . ': unrecognised match type "' .
                                        substr( $m[0], 0, 20 ) . '"' );
                        }
                        $url = wfMessage( $urlmsg, $id )->inContentLanguage()->text();
@@ -1333,8 +1328,7 @@ class Parser {
                wfProfileIn( __METHOD__ );
                for ( $i = 6; $i >= 1; --$i ) {
                        $h = str_repeat( '=', $i );
-                       $text = preg_replace( "/^$h(.+)$h\\s*$/m",
-                         "<h$i>\\1</h$i>", $text );
+                       $text = preg_replace( "/^$h(.+)$h\\s*$/m", "<h$i>\\1</h$i>", $text );
                }
                wfProfileOut( __METHOD__ );
                return $text;
@@ -1355,7 +1349,7 @@ class Parser {
                foreach ( $lines as $line ) {
                        $outtext .= $this->doQuotes( $line ) . "\n";
                }
-               $outtext = substr( $outtext, 0,-1 );
+               $outtext = substr( $outtext, 0, -1 );
                wfProfileOut( __METHOD__ );
                return $outtext;
        }
@@ -1420,7 +1414,7 @@ class Parser {
                                                        if ( $firstspace == -1 ) {
                                                                $firstspace = $i;
                                                        }
-                                               } elseif ( $x2 === ' ') {
+                                               } elseif ( $x2 === ' ' ) {
                                                        if ( $firstsingleletterword == -1 ) {
                                                                $firstsingleletterword = $i;
                                                        }
@@ -1471,7 +1465,7 @@ class Parser {
                                                } elseif ( $state === 'ib' ) {
                                                        $output .= '</b></i><b>'; $state = 'b';
                                                } elseif ( $state === 'both' ) {
-                                                       $output .= '<b><i>'.$buffer.'</i>'; $state = 'b';
+                                                       $output .= '<b><i>' . $buffer . '</i>'; $state = 'b';
                                                } else { # $state can be 'b' or ''
                                                        $output .= '<i>'; $state .= 'i';
                                                }
@@ -1483,7 +1477,7 @@ class Parser {
                                                } elseif ( $state === 'ib' ) {
                                                        $output .= '</b>'; $state = 'i';
                                                } elseif ( $state === 'both' ) {
-                                                       $output .= '<i><b>'.$buffer.'</b>'; $state = 'i';
+                                                       $output .= '<i><b>' . $buffer . '</b>'; $state = 'i';
                                                } else { # $state can be 'i' or ''
                                                        $output .= '<b>'; $state .= 'b';
                                                }
@@ -1497,7 +1491,7 @@ class Parser {
                                                } elseif ( $state === 'ib' ) {
                                                        $output .= '</b></i>'; $state = '';
                                                } elseif ( $state === 'both' ) {
-                                                       $output .= '<i><b>'.$buffer.'</b></i>'; $state = '';
+                                                       $output .= '<i><b>' . $buffer . '</b></i>'; $state = '';
                                                } else { # ($state == '')
                                                        $buffer = ''; $state = 'both';
                                                }
@@ -1517,7 +1511,7 @@ class Parser {
                        }
                        # There might be lonely ''''', so make sure we have a buffer
                        if ( $state === 'both' && $buffer ) {
-                               $output .= '<b><i>'.$buffer.'</i></b>';
+                               $output .= '<b><i>' . $buffer . '</i></b>';
                        }
                        return $output;
                }
@@ -1760,8 +1754,8 @@ class Parser {
        function replaceInternalLinks2( &$s ) {
                wfProfileIn( __METHOD__ );
 
-               wfProfileIn( __METHOD__.'-setup' );
-               static $tc = FALSE, $e1, $e1_img;
+               wfProfileIn( __METHOD__ . '-setup' );
+               static $tc = false, $e1, $e1_img;
                # the % is needed to support urlencoded titles as well
                if ( !$tc ) {
                        $tc = Title::legalChars() . '#%';
@@ -1790,9 +1784,9 @@ class Parser {
                }
 
                if ( is_null( $this->mTitle ) ) {
-                       wfProfileOut( __METHOD__.'-setup' );
+                       wfProfileOut( __METHOD__ . '-setup' );
                        wfProfileOut( __METHOD__ );
-                       throw new MWException( __METHOD__.": \$this->mTitle is null\n" );
+                       throw new MWException( __METHOD__ . ": \$this->mTitle is null\n" );
                }
                $nottalk = !$this->mTitle->isTalkPage();
 
@@ -1807,17 +1801,11 @@ class Parser {
                        $prefix = '';
                }
 
-               if ( $this->getConverterLanguage()->hasVariants() ) {
-                       $selflink = $this->getConverterLanguage()->autoConvertToAllVariants(
-                               $this->mTitle->getPrefixedText() );
-               } else {
-                       $selflink = array( $this->mTitle->getPrefixedText() );
-               }
                $useSubpages = $this->areSubpagesAllowed();
-               wfProfileOut( __METHOD__.'-setup' );
+               wfProfileOut( __METHOD__ . '-setup' );
 
                # Loop for each link
-               for ( ; $line !== false && $line !== null ; $a->next(), $line = $a->current() ) {
+               for ( ; $line !== false && $line !== null; $a->next(), $line = $a->current() ) {
                        # Check for excessive memory usage
                        if ( $holders->isBig() ) {
                                # Too big
@@ -1827,24 +1815,24 @@ class Parser {
                        }
 
                        if ( $useLinkPrefixExtension ) {
-                               wfProfileIn( __METHOD__.'-prefixhandling' );
+                               wfProfileIn( __METHOD__ . '-prefixhandling' );
                                if ( preg_match( $e2, $s, $m ) ) {
                                        $prefix = $m[2];
                                        $s = $m[1];
                                } else {
-                                       $prefix='';
+                                       $prefix = '';
                                }
                                # first link
                                if ( $first_prefix ) {
                                        $prefix = $first_prefix;
                                        $first_prefix = false;
                                }
-                               wfProfileOut( __METHOD__.'-prefixhandling' );
+                               wfProfileOut( __METHOD__ . '-prefixhandling' );
                        }
 
                        $might_be_img = false;
 
-                       wfProfileIn( __METHOD__."-e1" );
+                       wfProfileIn( __METHOD__ . "-e1" );
                        if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
                                $text = $m[2];
                                # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
@@ -1866,7 +1854,7 @@ class Parser {
                                # fix up urlencoded title texts
                                if ( strpos( $m[1], '%' ) !== false ) {
                                        # Should anchors '#' also be rejected?
-                                       $m[1] = str_replace( array('<', '>'), array('&lt;', '&gt;'), rawurldecode( $m[1] ) );
+                                       $m[1] = str_replace( array( '<', '>' ), array( '&lt;', '&gt;' ), rawurldecode( $m[1] ) );
                                }
                                $trail = $m[3];
                        } elseif ( preg_match( $e1_img, $line, $m ) ) { # Invalid, but might be an image with a link in its caption
@@ -1877,19 +1865,19 @@ class Parser {
                                }
                                $trail = "";
                        } else { # Invalid form; output directly
-                               $s .= $prefix . '[[' . $line ;
-                               wfProfileOut( __METHOD__."-e1" );
+                               $s .= $prefix . '[[' . $line;
+                               wfProfileOut( __METHOD__ . "-e1" );
                                continue;
                        }
-                       wfProfileOut( __METHOD__."-e1" );
-                       wfProfileIn( __METHOD__."-misc" );
+                       wfProfileOut( __METHOD__ . "-e1" );
+                       wfProfileIn( __METHOD__ . "-misc" );
 
                        # Don't allow internal links to pages containing
                        # PROTO: where PROTO is a valid URL protocol; these
                        # should be external links.
                        if ( preg_match( '/^(?i:' . $this->mUrlProtocols . ')/', $m[1] ) ) {
-                               $s .= $prefix . '[[' . $line ;
-                               wfProfileOut( __METHOD__."-misc" );
+                               $s .= $prefix . '[[' . $line;
+                               wfProfileOut( __METHOD__ . "-misc" );
                                continue;
                        }
 
@@ -1906,21 +1894,21 @@ class Parser {
                                $link = substr( $link, 1 );
                        }
 
-                       wfProfileOut( __METHOD__."-misc" );
-                       wfProfileIn( __METHOD__."-title" );
+                       wfProfileOut( __METHOD__ . "-misc" );
+                       wfProfileIn( __METHOD__ . "-title" );
                        $nt = Title::newFromText( $this->mStripState->unstripNoWiki( $link ) );
                        if ( $nt === null ) {
                                $s .= $prefix . '[[' . $line;
-                               wfProfileOut( __METHOD__."-title" );
+                               wfProfileOut( __METHOD__ . "-title" );
                                continue;
                        }
 
                        $ns = $nt->getNamespace();
                        $iw = $nt->getInterWiki();
-                       wfProfileOut( __METHOD__."-title" );
+                       wfProfileOut( __METHOD__ . "-title" );
 
                        if ( $might_be_img ) { # if this is actually an invalid link
-                               wfProfileIn( __METHOD__."-might_be_img" );
+                               wfProfileIn( __METHOD__ . "-might_be_img" );
                                if ( $ns == NS_FILE && $noforce ) { # but might be an image
                                        $found = false;
                                        while ( true ) {
@@ -1952,16 +1940,16 @@ class Parser {
                                                $holders->merge( $this->replaceInternalLinks2( $text ) );
                                                $s .= "{$prefix}[[$link|$text";
                                                # note: no $trail, because without an end, there *is* no trail
-                                               wfProfileOut( __METHOD__."-might_be_img" );
+                                               wfProfileOut( __METHOD__ . "-might_be_img" );
                                                continue;
                                        }
                                } else { # it's not an image, so output it raw
                                        $s .= "{$prefix}[[$link|$text";
                                        # note: no $trail, because without an end, there *is* no trail
-                                       wfProfileOut( __METHOD__."-might_be_img" );
+                                       wfProfileOut( __METHOD__ . "-might_be_img" );
                                        continue;
                                }
-                               wfProfileOut( __METHOD__."-might_be_img" );
+                               wfProfileOut( __METHOD__ . "-might_be_img" );
                        }
 
                        $wasblank = ( $text  == '' );
@@ -1978,7 +1966,7 @@ class Parser {
                        # Link not escaped by : , create the various objects
                        if ( $noforce ) {
                                # Interwikis
-                               wfProfileIn( __METHOD__."-interwiki" );
+                               wfProfileIn( __METHOD__ . "-interwiki" );
                                if ( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && Language::fetchLanguageName( $iw, null, 'mw' ) ) {
                                        // XXX: the above check prevents links to sites with identifiers that are not language codes
 
@@ -1990,13 +1978,13 @@ class Parser {
 
                                        $s = rtrim( $s . $prefix );
                                        $s .= trim( $trail, "\n" ) == '' ? '': $prefix . $trail;
-                                       wfProfileOut( __METHOD__."-interwiki" );
+                                       wfProfileOut( __METHOD__ . "-interwiki" );
                                        continue;
                                }
-                               wfProfileOut( __METHOD__."-interwiki" );
+                               wfProfileOut( __METHOD__ . "-interwiki" );
 
                                if ( $ns == NS_FILE ) {
-                                       wfProfileIn( __METHOD__."-image" );
+                                       wfProfileIn( __METHOD__ . "-image" );
                                        if ( !wfIsBadImage( $nt->getDBkey(), $this->mTitle ) ) {
                                                if ( $wasblank ) {
                                                        # if no parameters were passed, $text
@@ -2017,12 +2005,12 @@ class Parser {
                                        } else {
                                                $s .= $prefix . $trail;
                                        }
-                                       wfProfileOut( __METHOD__."-image" );
+                                       wfProfileOut( __METHOD__ . "-image" );
                                        continue;
                                }
 
                                if ( $ns == NS_CATEGORY ) {
-                                       wfProfileIn( __METHOD__."-category" );
+                                       wfProfileIn( __METHOD__ . "-category" );
                                        $s = rtrim( $s . "\n" ); # bug 87
 
                                        if ( $wasblank ) {
@@ -2041,14 +2029,18 @@ class Parser {
                                         */
                                        $s .= trim( $prefix . $trail, "\n" ) == '' ? '' : $prefix . $trail;
 
-                                       wfProfileOut( __METHOD__."-category" );
+                                       wfProfileOut( __METHOD__ . "-category" );
                                        continue;
                                }
                        }
 
                        # Self-link checking
                        if ( $nt->getFragment() === '' && $ns != NS_SPECIAL ) {
-                               if ( in_array( $nt->getPrefixedText(), $selflink, true ) ) {
+                               if ( $nt->equals( $this->mTitle ) || ( !$nt->isKnown() && in_array(
+                                       $this->mTitle->getPrefixedText(),
+                                       $this->getConverterLanguage()->autoConvertToAllVariants( $nt->getPrefixedText() ),
+                                       true
+                               ) ) ) {
                                        $s .= $prefix . Linker::makeSelfLinkObj( $nt, $text, '', $trail );
                                        continue;
                                }
@@ -2057,7 +2049,7 @@ class Parser {
                        # NS_MEDIA is a pseudo-namespace for linking directly to a file
                        # @todo FIXME: Should do batch file existence checks, see comment below
                        if ( $ns == NS_MEDIA ) {
-                               wfProfileIn( __METHOD__."-media" );
+                               wfProfileIn( __METHOD__ . "-media" );
                                # Give extensions a chance to select the file revision for us
                                $options = array();
                                $descQuery = false;
@@ -2068,11 +2060,11 @@ class Parser {
                                # Cloak with NOPARSE to avoid replacement in replaceExternalLinks
                                $s .= $prefix . $this->armorLinks(
                                        Linker::makeMediaLinkFile( $nt, $file, $text ) ) . $trail;
-                               wfProfileOut( __METHOD__."-media" );
+                               wfProfileOut( __METHOD__ . "-media" );
                                continue;
                        }
 
-                       wfProfileIn( __METHOD__."-always_known" );
+                       wfProfileIn( __METHOD__ . "-always_known" );
                        # Some titles, such as valid special pages or files in foreign repos, should
                        # be shown as bluelinks even though they're not included in the page table
                        #
@@ -2085,7 +2077,7 @@ class Parser {
                                # Links will be added to the output link list after checking
                                $s .= $holders->makeHolder( $nt, $text, array(), $trail, $prefix );
                        }
-                       wfProfileOut( __METHOD__."-always_known" );
+                       wfProfileOut( __METHOD__ . "-always_known" );
                }
                wfProfileOut( __METHOD__ );
                return $holders;
@@ -2273,7 +2265,7 @@ class Parser {
                } else {
                        return '<!-- ERR 3 -->';
                }
-               return $text."\n";
+               return $text . "\n";
        }
        /**#@-*/
 
@@ -2340,7 +2332,7 @@ class Parser {
                                $output .= $this->nextItem( substr( $prefix, -1 ) );
                                $paragraphStack = false;
 
-                               if ( substr( $prefix, -1 ) === ';') {
+                               if ( substr( $prefix, -1 ) === ';' ) {
                                        # The one nasty exception: definition lists work like this:
                                        # ; title : definition text
                                        # So we check for : in the remainder text to split up the
@@ -2388,13 +2380,13 @@ class Parser {
 
                        # If we have no prefixes, go to paragraph mode.
                        if ( 0 == $prefixLength ) {
-                               wfProfileIn( __METHOD__."-paragraph" );
+                               wfProfileIn( __METHOD__ . "-paragraph" );
                                # No prefix (not in list)--go to paragraph mode
                                # XXX: use a stack for nestable elements like span, table and div
-                               $openmatch = preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<dl|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
+                               $openmatch = preg_match( '/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<dl|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
                                $closematch = preg_match(
                                        '/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
-                                       '<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol|<\\/dl|<\\/?center)/iS', $t );
+                                       '<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix . '-pre|<\\/li|<\\/ul|<\\/ol|<\\/dl|<\\/?center)/iS', $t );
                                if ( $openmatch or $closematch ) {
                                        $paragraphStack = false;
                                        # TODO bug 5718: paragraph closed
@@ -2408,7 +2400,7 @@ class Parser {
                                                # pre
                                                if ( $this->mLastSection !== 'pre' ) {
                                                        $paragraphStack = false;
-                                                       $output .= $this->closeParagraph().'<pre>';
+                                                       $output .= $this->closeParagraph() . '<pre>';
                                                        $this->mLastSection = 'pre';
                                                }
                                                $t = substr( $t, 1 );
@@ -2416,7 +2408,7 @@ class Parser {
                                                # paragraph
                                                if ( trim( $t ) === '' ) {
                                                        if ( $paragraphStack ) {
-                                                               $output .= $paragraphStack.'<br />';
+                                                               $output .= $paragraphStack . '<br />';
                                                                $paragraphStack = false;
                                                                $this->mLastSection = 'p';
                                                        } else {
@@ -2434,20 +2426,20 @@ class Parser {
                                                                $paragraphStack = false;
                                                                $this->mLastSection = 'p';
                                                        } elseif ( $this->mLastSection !== 'p' ) {
-                                                               $output .= $this->closeParagraph().'<p>';
+                                                               $output .= $this->closeParagraph() . '<p>';
                                                                $this->mLastSection = 'p';
                                                        }
                                                }
                                        }
                                }
-                               wfProfileOut( __METHOD__."-paragraph" );
+                               wfProfileOut( __METHOD__ . "-paragraph" );
                        }
                        # somewhere above we forget to get out of pre block (bug 785)
                        if ( $preCloseMatch && $this->mInPre ) {
                                $this->mInPre = false;
                        }
                        if ( $paragraphStack === false ) {
-                               $output .= $t."\n";
+                               $output .= $t . "\n";
                        }
                }
                while ( $prefixLength ) {
@@ -2581,7 +2573,7 @@ class Parser {
                                if ( $c === ">" ) {
                                        $stack--;
                                        if ( $stack < 0 ) {
-                                               wfDebug( __METHOD__.": Invalid input; too many close tags\n" );
+                                               wfDebug( __METHOD__ . ": Invalid input; too many close tags\n" );
                                                wfProfileOut( __METHOD__ );
                                                return false;
                                        }
@@ -2621,7 +2613,7 @@ class Parser {
                        }
                }
                if ( $stack > 0 ) {
-                       wfDebug( __METHOD__.": Invalid input; not enough close tags (stack $stack, state $state)\n" );
+                       wfDebug( __METHOD__ . ": Invalid input; not enough close tags (stack $stack, state $state)\n" );
                        wfProfileOut( __METHOD__ );
                        return false;
                }
@@ -2849,7 +2841,7 @@ class Parser {
                                $value = $this->getRevisionUser();
                                break;
                        case 'namespace':
-                               $value = str_replace( '_',' ',$wgContLang->getNsText( $this->mTitle->getNamespace() ) );
+                               $value = str_replace( '_', ' ', $wgContLang->getNsText( $this->mTitle->getNamespace() ) );
                                break;
                        case 'namespacee':
                                $value = wfUrlencode( $wgContLang->getNsText( $this->mTitle->getNamespace() ) );
@@ -2858,7 +2850,7 @@ class Parser {
                                $value = $this->mTitle->getNamespace();
                                break;
                        case 'talkspace':
-                               $value = $this->mTitle->canTalk() ? str_replace( '_',' ',$this->mTitle->getTalkNsText() ) : '';
+                               $value = $this->mTitle->canTalk() ? str_replace( '_', ' ', $this->mTitle->getTalkNsText() ) : '';
                                break;
                        case 'talkspacee':
                                $value = $this->mTitle->canTalk() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
@@ -3070,7 +3062,7 @@ class Parser {
                if ( $frame === false ) {
                        $frame = $this->getPreprocessor()->newFrame();
                } elseif ( !( $frame instanceof PPFrame ) ) {
-                       wfDebug( __METHOD__." called using plain parameters instead of a PPFrame instance. Creating custom frame.\n" );
+                       wfDebug( __METHOD__ . " called using plain parameters instead of a PPFrame instance. Creating custom frame.\n" );
                        $frame = $this->getPreprocessor()->newCustomFrame( $frame );
                }
 
@@ -3153,7 +3145,7 @@ class Parser {
        function braceSubstitution( $piece, $frame ) {
                global $wgContLang;
                wfProfileIn( __METHOD__ );
-               wfProfileIn( __METHOD__.'-setup' );
+               wfProfileIn( __METHOD__ . '-setup' );
 
                # Flags
                $found = false;             # $text has been filled
@@ -3178,12 +3170,12 @@ class Parser {
                # $args is a list of argument nodes, starting from index 0, not including $part1
                # @todo FIXME: If piece['parts'] is null then the call to getLength() below won't work b/c this $args isn't an object
                $args = ( null == $piece['parts'] ) ? array() : $piece['parts'];
-               wfProfileOut( __METHOD__.'-setup' );
+               wfProfileOut( __METHOD__ . '-setup' );
 
                $titleProfileIn = null; // profile templates
 
                # SUBST
-               wfProfileIn( __METHOD__.'-modifiers' );
+               wfProfileIn( __METHOD__ . '-modifiers' );
                if ( !$found ) {
 
                        $substMatch = $this->mSubstWords->matchStartAndRemove( $part1 );
@@ -3240,7 +3232,7 @@ class Parser {
                                $forceRawInterwiki = true;
                        }
                }
-               wfProfileOut( __METHOD__.'-modifiers' );
+               wfProfileOut( __METHOD__ . '-modifiers' );
 
                # Parser functions
                if ( !$found ) {
@@ -3387,7 +3379,7 @@ class Parser {
                                        }
                                } elseif ( MWNamespace::isNonincludable( $title->getNamespace() ) ) {
                                        $found = false; # access denied
-                                       wfDebug( __METHOD__.": template inclusion denied for " . $title->getPrefixedDBkey() );
+                                       wfDebug( __METHOD__ . ": template inclusion denied for " . $title->getPrefixedDBkey() );
                                } else {
                                        list( $text, $title ) = $this->getTemplateDom( $title );
                                        if ( $text !== false ) {
@@ -3422,7 +3414,7 @@ class Parser {
                                $text = '<span class="error">'
                                        . wfMessage( 'parser-template-loop-warning', $titleText )->inContentLanguage()->text()
                                        . '</span>';
-                               wfDebug( __METHOD__.": template loop broken at '$titleText'\n" );
+                               wfDebug( __METHOD__ . ": template loop broken at '$titleText'\n" );
                        }
                        wfProfileOut( __METHOD__ . '-loadtpl' );
                }
@@ -3718,7 +3710,7 @@ class Parser {
                global $wgEnableScaryTranscluding;
 
                if ( !$wgEnableScaryTranscluding ) {
-                       return wfMessage('scarytranscludedisabled')->inContentLanguage()->text();
+                       return wfMessage( 'scarytranscludedisabled' )->inContentLanguage()->text();
                }
 
                $url = $title->getFullUrl( "action=$action" );
@@ -3737,7 +3729,7 @@ class Parser {
                global $wgTranscludeCacheExpiry;
                $dbr = wfGetDB( DB_SLAVE );
                $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
-               $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ),
+               $obj = $dbr->selectRow( 'transcache', array( 'tc_time', 'tc_contents' ),
                                array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) );
                if ( $obj ) {
                        return $obj->tc_contents;
@@ -3754,7 +3746,7 @@ class Parser {
                }
 
                $dbw = wfGetDB( DB_MASTER );
-               $dbw->replace( 'transcache', array('tc_url'), array(
+               $dbw->replace( 'transcache', array( 'tc_url' ), array(
                        'tc_url' => $url,
                        'tc_time' => $dbw->timestamp( time() ),
                        'tc_contents' => $text)
@@ -3780,7 +3772,7 @@ class Parser {
                $argName = trim( $nameWithSpaces );
                $object = false;
                $text = $frame->getArgument( $argName );
-               if (  $text === false && $parts->getLength() > 0
+               if ( $text === false && $parts->getLength() > 0
                  && (
                        $this->ot['html']
                        || $this->ot['pre']
@@ -3833,7 +3825,7 @@ class Parser {
                $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
                $marker = "{$this->mUniqPrefix}-$name-" . sprintf( '%08X', $this->mMarkerIndex++ ) . self::MARKER_SUFFIX;
 
-               $isFunctionTag = isset( $this->mFunctionTagHooks[strtolower($name)] ) &&
+               $isFunctionTag = isset( $this->mFunctionTagHooks[strtolower( $name )] ) &&
                        ( $this->ot['html'] || $this->ot['pre'] );
                if ( $isFunctionTag ) {
                        $markerType = 'none';
@@ -3898,7 +3890,7 @@ class Parser {
                } elseif ( $markerType === 'general' ) {
                        $this->mStripState->addGeneral( $marker, $output );
                } else {
-                       throw new MWException( __METHOD__.': invalid marker type' );
+                       throw new MWException( __METHOD__ . ': invalid marker type' );
                }
                return $marker;
        }
@@ -3997,7 +3989,7 @@ class Parser {
         */
        public function addTrackingCategory( $msg ) {
                if ( $this->mTitle->getNamespace() === NS_SPECIAL ) {
-                       wfDebug( __METHOD__.": Not adding tracking category $msg to special page!\n" );
+                       wfDebug( __METHOD__ . ": Not adding tracking category $msg to special page!\n" );
                        return false;
                }
                // Important to parse with correct title (bug 31469)
@@ -4016,7 +4008,7 @@ class Parser {
                        $this->mOutput->addCategory( $containerCategory->getDBkey(), $this->getDefaultSort() );
                        return true;
                } else {
-                       wfDebug( __METHOD__.": [[MediaWiki:$msg]] is not a valid title!\n" );
+                       wfDebug( __METHOD__ . ": [[MediaWiki:$msg]] is not a valid title!\n" );
                        return false;
                }
        }
@@ -4112,7 +4104,7 @@ class Parser {
                        $sectionIndex = false;
                        $numbering = '';
                        $markerMatches = array();
-                       if ( preg_match("/^$markerRegex/", $headline, $markerMatches ) ) {
+                       if ( preg_match( "/^$markerRegex/", $headline, $markerMatches ) ) {
                                $serial = $markerMatches[1];
                                list( $titleText, $sectionIndex ) = $this->mHeadings[$serial];
                                $isTemplate = ( $titleText != $baseTitleText );
@@ -4204,7 +4196,7 @@ class Parser {
                        # to allow setting directionality in toc items.
                        $tocline = preg_replace(
                                array( '#<(?!/?(span|sup|sub|i|b)(?: [^>]*)?>).*?'.'>#', '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|i|b))(?: .*?)?'.'>#' ),
-                               array( '',                          '<$1>' ),
+                               array( '', '<$1>' ),
                                $safeHeadline
                        );
                        $tocline = trim( $tocline );
@@ -4325,9 +4317,9 @@ class Parser {
                                // We use a page and section attribute to stop the language converter from converting these important bits
                                // of data, but put the headline hint inside a content block because the language converter is supposed to
                                // be able to convert that piece of data.
-                               $editlink = '<mw:editsection page="' . htmlspecialchars($editlinkArgs[0]);
-                               $editlink .= '" section="' . htmlspecialchars($editlinkArgs[1]) .'"';
-                               if ( isset($editlinkArgs[2]) ) {
+                               $editlink = '<mw:editsection page="' . htmlspecialchars( $editlinkArgs[0] );
+                               $editlink .= '" section="' . htmlspecialchars( $editlinkArgs[1] ) . '"';
+                               if ( isset( $editlinkArgs[2] ) ) {
                                        $editlink .= '>' . $editlinkArgs[2] . '</mw:editsection>';
                                } else {
                                        $editlink .= '/>';
@@ -4492,14 +4484,14 @@ class Parser {
                        '~~~' => $sigText
                ) );
 
-               # Context links ("pipe trick"): [[|name]] and [[name (context)|]]
+               # Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
                $tc = '[' . Title::legalChars() . ']';
                $nc = '[ _0-9A-Za-z\x80-\xff-]'; # Namespaces can use non-ascii!
 
-               $p1 = "/\[\[(:?$nc+:|:|)($tc+?)( ?\\($tc+\\))\\|]]/";                  # [[ns:page (context)|]]
-               $p4 = "/\[\[(:?$nc+:|:|)($tc+?)( ?($tc+))\\|]]/";                    # [[ns:page(context)|]] (double-width brackets, added in r40257)
-               $p3 = "/\[\[(:?$nc+:|:|)($tc+?)( ?\\($tc+\\)|)((?:, |,)$tc+|)\\|]]/"; # [[ns:page (context), context|]]
-               $p2 = "/\[\[\\|($tc+)]]/";                                             # [[|page]]
+               $p1 = "/\[\[(:?$nc+:|:|)($tc+?)( ?\\($tc+\\))\\|]]/";                   # [[ns:page (context)|]]
+               $p4 = "/\[\[(:?$nc+:|:|)($tc+?)( ?($tc+))\\|]]/";                           # [[ns:page(context)|]] (double-width brackets, added in r40257)
+               $p3 = "/\[\[(:?$nc+:|:|)($tc+?)( ?\\($tc+\\)|)((?:, |,)$tc+|)\\|]]/";         # [[ns:page (context), context|]] (using either single or double-width comma)
+               $p2 = "/\[\[\\|($tc+)]]/";                                              # [[|page]] (reverse pipe trick: add context from page title)
 
                # try $p1 first, to turn "[[A, B (C)|]]" into "[[A, B (C)|A, B]]"
                $text = preg_replace( $p1, '[[\\1\\2\\3|\\2]]', $text );
@@ -4563,7 +4555,7 @@ class Parser {
                        } else {
                                # Failed to validate; fall back to the default
                                $nickname = $username;
-                               wfDebug( __METHOD__.": $username has bad XML tags in signature.\n" );
+                               wfDebug( __METHOD__ . ": $username has bad XML tags in signature.\n" );
                        }
                }
 
@@ -4824,7 +4816,7 @@ class Parser {
                # Add to function cache
                $mw = MagicWord::get( $id );
                if ( !$mw )
-                       throw new MWException( __METHOD__.'() expecting a magic word identifier.' );
+                       throw new MWException( __METHOD__ . '() expecting a magic word identifier.' );
 
                $synonyms = $mw->getSynonyms();
                $sensitive = intval( $mw->isCaseSensitive() );
@@ -4979,7 +4971,7 @@ class Parser {
                                // is defined for images in galleries
 
                                $matches[3] = $this->recursiveTagParse( trim( $matches[3] ) );
-                               $parameterMatches = StringUtils::explode('|', $matches[3]);
+                               $parameterMatches = StringUtils::explode( '|', $matches[3] );
                                $magicWordAlt = MagicWord::get( 'img_alt' );
                                $magicWordLink = MagicWord::get( 'img_link' );
 
@@ -4987,14 +4979,18 @@ class Parser {
                                        if ( $match = $magicWordAlt->matchVariableStartToEnd( $parameterMatch ) ) {
                                                $alt = $this->stripAltText( $match, false );
                                        }
-                                       elseif( $match = $magicWordLink->matchVariableStartToEnd( $parameterMatch ) ){
-                                               $link = strip_tags($this->replaceLinkHoldersText($match));
+                                       elseif( $match = $magicWordLink->matchVariableStartToEnd( $parameterMatch ) ) {
+                                               $linkValue = strip_tags( $this->replaceLinkHoldersText( $match ) );
                                                $chars = self::EXT_LINK_URL_CLASS;
                                                $prots = $this->mUrlProtocols;
                                                //check to see if link matches an absolute url, if not then it must be a wiki link.
-                                               if(!preg_match( "/^($prots)$chars+$/u", $link)){
-                                                       $localLinkTitle = Title::newFromText($link);
-                                                       $link = $localLinkTitle->getLocalURL();
+                                               if ( preg_match( "/^($prots)$chars+$/u", $linkValue ) ) {
+                                                       $link = $linkValue;
+                                               } else {
+                                                       $localLinkTitle = Title::newFromText( $linkValue );
+                                                       if ( $localLinkTitle !== null ) {
+                                                               $link = $localLinkTitle->getLocalURL();
+                                                       }
                                                }
                                        }
                                        else {
@@ -5006,7 +5002,7 @@ class Parser {
                                $label = substr( $label, 1 );
                        }
 
-                       $ig->add( $title, $label, $alt ,$link);
+                       $ig->add( $title, $label, $alt, $link );
                }
                return $ig->toHTML();
        }
@@ -5021,7 +5017,7 @@ class Parser {
                } else {
                        $handlerClass = '';
                }
-               if ( !isset( $this->mImageParams[$handlerClass]  ) ) {
+               if ( !isset( $this->mImageParams[$handlerClass] ) ) {
                        # Initialise static lists
                        static $internalParamNames = array(
                                'horizAlign' => array( 'left', 'right', 'center', 'none' ),
@@ -5239,7 +5235,7 @@ class Parser {
                } else { # Inline image
                        if ( !isset( $params['frame']['alt'] ) ) {
                                # No alt text, use the "caption" for the alt text
-                               if ( $caption !== '') {
+                               if ( $caption !== '' ) {
                                        $params['frame']['alt'] = $this->stripAltText( $caption, $holders );
                                } else {
                                        # No caption, fall back to using the filename for the
@@ -5385,7 +5381,7 @@ class Parser {
         * @return String: for "get", the extracted section text.
         *                 for "replace", the whole page with the section replaced.
         */
-       private function extractSections( $text, $section, $mode, $newText='' ) {
+       private function extractSections( $text, $section, $mode, $newText = '' ) {
                global $wgTitle; # not generally used but removes an ugly failure mode
                $this->startParse( $wgTitle, new ParserOptions, self::OT_PLAIN, true );
                $outText = '';
@@ -5506,7 +5502,7 @@ class Parser {
         * @param $deftext String: default to return if section is not found
         * @return string text of the requested section
         */
-       public function getSection( $text, $section, $deftext='' ) {
+       public function getSection( $text, $section, $deftext = '' ) {
                return $this->extractSections( $text, $section, "get", $deftext );
        }
 
@@ -5832,7 +5828,7 @@ class Parser {
         */
        function unserializeHalfParsedText( $data ) {
                if ( !isset( $data['version'] ) || $data['version'] != self::HALF_PARSED_VERSION ) {
-                       throw new MWException( __METHOD__.': invalid version' );
+                       throw new MWException( __METHOD__ . ': invalid version' );
                }
 
                # First, extract the strip state.
index d419621..0faa40a 100644 (file)
@@ -67,7 +67,7 @@ class ParserCache {
 
                // idhash seem to mean 'page id' + 'rendering hash' (r3710)
                $pageid = $article->getID();
-               $renderkey = (int)($wgRequest->getVal('action') == 'render');
+               $renderkey = (int)($wgRequest->getVal( 'action' ) == 'render');
 
                $key = wfMemcKey( 'pcache', 'idhash', "{$pageid}-{$renderkey}!{$hash}" );
                return $key;
index 064182e..bd4bcac 100644 (file)
  */
 class ParserOptions {
 
-       /**
-        * Use DateFormatter to format dates
-        */
-       var $mUseDynamicDates;
-
        /**
         * Interlanguage links are removed and returned in an array
         */
@@ -220,7 +215,6 @@ class ParserOptions {
         */
        protected $onAccessCallback = null;
 
-       function getUseDynamicDates()               { return $this->mUseDynamicDates; }
        function getInterwikiMagic()                { return $this->mInterwikiMagic; }
        function getAllowExternalImages()           { return $this->mAllowExternalImages; }
        function getAllowExternalImagesFrom()       { return $this->mAllowExternalImagesFrom; }
@@ -308,7 +302,6 @@ class ParserOptions {
                return $this->getUserLangObj()->getCode();
        }
 
-       function setUseDynamicDates( $x )           { return wfSetVar( $this->mUseDynamicDates, $x ); }
        function setInterwikiMagic( $x )            { return wfSetVar( $this->mInterwikiMagic, $x ); }
        function setAllowExternalImages( $x )       { return wfSetVar( $this->mAllowExternalImages, $x ); }
        function setAllowExternalImagesFrom( $x )   { return wfSetVar( $this->mAllowExternalImagesFrom, $x ); }
@@ -422,7 +415,7 @@ class ParserOptions {
         * @param $lang Language object
         */
        private function initialiseFromUser( $user, $lang ) {
-               global $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages,
+               global $wgInterwikiMagic, $wgAllowExternalImages,
                        $wgAllowExternalImagesFrom, $wgEnableImageWhitelist, $wgAllowSpecialInclusion,
                        $wgMaxArticleSize, $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth,
                        $wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit,
@@ -430,7 +423,6 @@ class ParserOptions {
 
                wfProfileIn( __METHOD__ );
 
-               $this->mUseDynamicDates = $wgUseDynamicDates;
                $this->mInterwikiMagic = $wgInterwikiMagic;
                $this->mAllowExternalImages = $wgAllowExternalImages;
                $this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
@@ -481,12 +473,7 @@ class ParserOptions {
         * @return array
         */
        public static function legacyOptions() {
-               global $wgUseDynamicDates;
-               $legacyOpts = array( 'math', 'stubthreshold', 'numberheadings', 'userlang', 'thumbsize', 'editsection', 'printable' );
-               if ( $wgUseDynamicDates ) {
-                       $legacyOpts[] = 'dateformat';
-               }
-               return $legacyOpts;
+               return array( 'math', 'stubthreshold', 'numberheadings', 'userlang', 'thumbsize', 'editsection', 'printable' );
        }
 
        /**
@@ -525,7 +512,7 @@ class ParserOptions {
                if ( in_array( 'stubthreshold', $forOptions ) ) {
                        $confstr .= '!' . $this->mStubThreshold;
                } else {
-                       $confstr .= '!*' ;
+                       $confstr .= '!*';
                }
 
                if ( in_array( 'dateformat', $forOptions ) ) {
index 28d07f1..27b75ac 100644 (file)
@@ -51,6 +51,7 @@ class ParserOutput extends CacheTime {
                private $mIndexPolicy = '';       # 'index' or 'noindex'?  Any other value will result in no change.
                private $mAccessedOptions = array(); # List of ParserOptions (stored in the keys)
                private $mSecondaryDataUpdates = array(); # List of DataUpdate, used to save info from the page somewhere else.
+               private $mExtensionData = array(); # extra data used by extensions
 
        const EDITSECTION_REGEX = '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#';
 
@@ -82,13 +83,13 @@ class ParserOutput extends CacheTime {
        function replaceEditSectionLinksCallback( $m ) {
                global $wgOut, $wgLang;
                $args = array(
-                       htmlspecialchars_decode($m[1]),
-                       htmlspecialchars_decode($m[2]),
-                       isset($m[4]) ? $m[3] : null,
+                       htmlspecialchars_decode( $m[1] ),
+                       htmlspecialchars_decode( $m[2] ),
+                       isset( $m[4] ) ? $m[3] : null,
                );
                $args[0] = Title::newFromText( $args[0] );
-               if ( !is_object($args[0]) ) {
-                       throw new MWException("Bad parser output text.");
+               if ( !is_object( $args[0] ) ) {
+                       throw new MWException( "Bad parser output text." );
                }
                $args[] = $wgLang->getCode();
                $skin = $wgOut->getSkin();
@@ -189,7 +190,7 @@ class ParserOutput extends CacheTime {
         * @param $title Title object
         * @param $id Mixed: optional known page_id so we can skip the lookup
         */
-       function addLink( $title, $id = null ) {
+       function addLink( Title $title, $id = null ) {
                if ( $title->isExternal() ) {
                        // Don't record interwikis in pagelinks
                        $this->addInterwikiLink( $title );
@@ -260,7 +261,7 @@ class ParserOutput extends CacheTime {
                if( $prefix == '' ) {
                        throw new MWException( 'Non-interwiki link passed, internal parser error.' );
                }
-               if (!isset($this->mInterwikiLinks[$prefix])) {
+               if ( !isset( $this->mInterwikiLinks[$prefix] ) ) {
                        $this->mInterwikiLinks[$prefix] = array();
                }
                $this->mInterwikiLinks[$prefix][$title->getDBkey()] = 1;
@@ -370,15 +371,31 @@ class ParserOutput extends CacheTime {
         *     Wikimedia Commons.
         *     This is not actually implemented, yet but would be pretty cool.
         *
-        * Do not use setProperty() to set a property which is only used in a
-        * context where the ParserOutput object itself is already available, for
-        * example a normal page view. There is no need to save such a property
+        * @note: Do not use setProperty() to set a property which is only used
+        * in a context where the ParserOutput object itself is already available,
+        * for example a normal page view. There is no need to save such a property
         * in the database since it the text is already parsed. You can just hook
         * OutputPageParserOutput and get your data out of the ParserOutput object.
         *
-        * If you are writing an extension where you want to set
-        * a property in the parser which is used by an OutputPageParserOutput hook,
-        * just use a custom variable within the ParserOutput object:
+        * If you are writing an extension where you want to set a property in the
+        * parser which is used by an OutputPageParserOutput hook, you have to
+        * associate the extension data directly with the ParserOutput object.
+        * Since MediaWiki 1.21, you can use setExtensionData() to do this:
+        *
+        * @par Example:
+        * @code
+        *    $parser->getOutput()->setExtensionData( 'my_ext_foo', '...' );
+        * @endcode
+        *
+        * And then later, in OutputPageParserOutput or similar:
+        *
+        * @par Example:
+        * @code
+        *    $output->getExtensionData( 'my_ext_foo' );
+        * @endcode
+        *
+        * In MediaWiki 1.20 and older, you have to use a custom member variable
+        * within the ParserOutput object:
         *
         * @par Example:
         * @code
@@ -390,7 +407,7 @@ class ParserOutput extends CacheTime {
                $this->mProperties[$name] = $value;
        }
 
-       public function getProperty( $name ){
+       public function getProperty( $name ) {
                return isset( $this->mProperties[$name] ) ? $this->mProperties[$name] : false;
        }
 
@@ -407,20 +424,20 @@ class ParserOutput extends CacheTime {
         * into account to produce this output or false if not available.
         * @return mixed Array
         */
-        public function getUsedOptions() {
+       public function getUsedOptions() {
                if ( !isset( $this->mAccessedOptions ) ) {
                        return array();
                }
                return array_keys( $this->mAccessedOptions );
-        }
+       }
 
-        /**
-         * Callback passed by the Parser to the ParserOptions to keep track of which options are used.
-         * @access private
-         */
-        function recordOption( $option ) {
-                $this->mAccessedOptions[$option] = true;
-        }
+       /**
+        * Callback passed by the Parser to the ParserOptions to keep track of which options are used.
+        * @access private
+        */
+       function recordOption( $option ) {
+               $this->mAccessedOptions[$option] = true;
+       }
 
        /**
         * Adds an update job to the output. Any update jobs added to the output will eventually bexecuted in order to
@@ -457,13 +474,75 @@ class ParserOutput extends CacheTime {
 
                $linksUpdate = new LinksUpdate( $title, $this, $recursive );
 
-               if ( $this->mSecondaryDataUpdates === array() ) {
-                       return array( $linksUpdate );
+               return array_merge( $this->mSecondaryDataUpdates, array( $linksUpdate ) );
+       }
+
+       /**
+        * Attaches arbitrary data to this ParserObject. This can be used to store some information in
+        * the ParserOutput object for later use during page output. The data will be cached along with
+        * the ParserOutput object, but unlike data set using setProperty(), it is not recorded in the
+        * database.
+        *
+        * This method is provided to overcome the unsafe practice of attaching extra information to a
+        * ParserObject by directly assigning member variables.
+        *
+        * To use setExtensionData() to pass extension information from a hook inside the parser to a
+        * hook in the page output, use this in the parser hook:
+        *
+        * @par Example:
+        * @code
+        *    $parser->getOutput()->setExtensionData( 'my_ext_foo', '...' );
+        * @endcode
+        *
+        * And then later, in OutputPageParserOutput or similar:
+        *
+        * @par Example:
+        * @code
+        *    $output->getExtensionData( 'my_ext_foo' );
+        * @endcode
+        *
+        * In MediaWiki 1.20 and older, you have to use a custom member variable
+        * within the ParserOutput object:
+        *
+        * @par Example:
+        * @code
+        *    $parser->getOutput()->my_ext_foo = '...';
+        * @endcode
+        *
+        * @since 1.21
+        *
+        * @param string $key The key for accessing the data. Extensions should take care to avoid
+        *               conflicts in naming keys. It is suggested to use the extension's name as a
+        *               prefix.
+        *
+        * @param mixed $value The value to set. Setting a value to null is equivalent to removing
+        *              the value.
+        */
+       public function setExtensionData( $key, $value ) {
+               if ( $value === null ) {
+                       unset( $this->mExtensionData[$key] );
                } else {
-                       $updates = array_merge( $this->mSecondaryDataUpdates, array( $linksUpdate ) );
+                       $this->mExtensionData[$key] = $value;
                }
+       }
 
-               return $updates;
-        }
+       /**
+        * Gets extensions data previously attached to this ParserOutput using setExtensionData().
+        * Typically, such data would be set while parsing the page, e.g. by a parser function.
+        *
+        * @since 1.21
+        *
+        * @param string $key The key to look up.
+        *
+        * @return mixed The value previously set for the given key using setExtensionData( $key ),
+        *         or null if no value was set for this key.
+        */
+       public function getExtensionData( $key ) {
+               if ( isset( $this->mExtensionData[$key] ) ) {
+                       return $this->mExtensionData[$key];
+               }
+
+               return null;
+       }
 
 }
index d1ca8aa..b2cdc41 100644 (file)
@@ -105,9 +105,9 @@ class Parser_LinkHooks extends Parser {
         */
        public function setLinkHook( $ns, $callback, $flags = 0 ) {
                if( $flags & SLH_PATTERN && !is_string($ns) )
-                       throw new MWException( __METHOD__.'() expecting a regex string pattern.' );
-               elseif( $flags | ~SLH_PATTERN && !is_int($ns) )
-                       throw new MWException( __METHOD__.'() expecting a namespace index.' );
+                       throw new MWException( __METHOD__ . '() expecting a regex string pattern.' );
+               elseif( $flags | ~SLH_PATTERN && !is_int( $ns ) )
+                       throw new MWException( __METHOD__ . '() expecting a namespace index.' );
                $oldVal = isset( $this->mLinkHooks[$ns] ) ? $this->mLinkHooks[$ns][0] : null;
                $this->mLinkHooks[$ns] = array( $callback, $flags );
                return $oldVal;
@@ -133,8 +133,8 @@ class Parser_LinkHooks extends Parser {
        function replaceInternalLinks2( &$s ) {
                wfProfileIn( __METHOD__ );
 
-               wfProfileIn( __METHOD__.'-setup' );
-               static $tc = FALSE, $titleRegex;//$e1, $e1_img;
+               wfProfileIn( __METHOD__ . '-setup' );
+               static $tc = false, $titleRegex; //$e1, $e1_img;
                if( !$tc ) {
                        # the % is needed to support urlencoded titles as well
                        $tc = Title::legalChars() . '#%';
@@ -149,12 +149,12 @@ class Parser_LinkHooks extends Parser {
                $holders = new LinkHolderArray( $this );
 
                if( is_null( $this->mTitle ) ) {
-                       wfProfileOut( __METHOD__.'-setup' );
+                       wfProfileOut( __METHOD__ . '-setup' );
                        wfProfileOut( __METHOD__ );
-                       throw new MWException( __METHOD__.": \$this->mTitle is null\n" );
+                       throw new MWException( __METHOD__ . ": \$this->mTitle is null\n" );
                }
 
-               wfProfileOut( __METHOD__.'-setup' );
+               wfProfileOut( __METHOD__ . '-setup' );
 
                $offset = 0;
                $offsetStack = array();
@@ -167,7 +167,7 @@ class Parser_LinkHooks extends Parser {
                        # Determine if the bracket is a starting or ending bracket
                        # When we find both, use the first one
                        elseif( $startBracketOffset !== false && $endBracketOffset !== false )
-                            $isStart = $startBracketOffset <= $endBracketOffset;
+                               $isStart = $startBracketOffset <= $endBracketOffset;
                        # When we only found one, check which it is
                        else $isStart = $startBracketOffset !== false;
                        $bracketOffset = $isStart ? $startBracketOffset : $endBracketOffset;
@@ -178,26 +178,26 @@ class Parser_LinkHooks extends Parser {
                        } else {
                                /** Closing bracket **/
                                # Pop the start pos for our current link zone off the stack
-                               $startBracketOffset = array_pop($offsetStack);
+                               $startBracketOffset = array_pop( $offsetStack );
                                # Just to clean up the code, lets place offsets on the outer ends
                                $endBracketOffset += 2;
 
                                # Only do logic if we actually have a opening bracket for this
-                               if( isset($startBracketOffset) ) {
+                               if( isset( $startBracketOffset ) ) {
                                        # Extract text inside the link
-                                       @list( $titleText, $paramText ) = explode('|',
-                                               substr($s, $startBracketOffset+2, $endBracketOffset-$startBracketOffset-4), 2);
+                                       @list( $titleText, $paramText ) = explode( '|',
+                                               substr( $s, $startBracketOffset + 2, $endBracketOffset - $startBracketOffset - 4 ), 2 );
                                        # Create markers only for valid links
                                        if( preg_match( $titleRegex, $titleText ) ) {
                                                # Store the text for the marker
-                                               $marker = $markers->addMarker($titleText, $paramText);
+                                               $marker = $markers->addMarker( $titleText, $paramText );
                                                # Replace the current link with the marker
-                                               $s = substr($s,0,$startBracketOffset).
-                                                       $marker.
-                                                       substr($s, $endBracketOffset);
+                                               $s = substr( $s, 0, $startBracketOffset ) .
+                                                       $marker .
+                                                       substr( $s, $endBracketOffset );
                                                # We have modified $s, because of this we need to set the
                                                # offset manually since the end position is different now
-                                               $offset = $startBracketOffset+strlen($marker);
+                                               $offset = $startBracketOffset+strlen( $marker );
                                                continue;
                                        }
                                        # ToDo: Some LinkHooks may allow recursive links inside of
@@ -212,9 +212,9 @@ class Parser_LinkHooks extends Parser {
                }
 
                # Now expand our tree
-               wfProfileIn( __METHOD__.'-expand' );
+               wfProfileIn( __METHOD__ . '-expand' );
                $s = $markers->expand( $s );
-               wfProfileOut( __METHOD__.'-expand' );
+               wfProfileOut( __METHOD__ . '-expand' );
 
                wfProfileOut( __METHOD__ );
                return $holders;
@@ -222,14 +222,14 @@ class Parser_LinkHooks extends Parser {
 
        function replaceInternalLinksCallback( $parser, $holders, $markers, $titleText, $paramText ) {
                wfProfileIn( __METHOD__ );
-               $wt = isset($paramText) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
-               wfProfileIn( __METHOD__."-misc" );
+               $wt = isset( $paramText ) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
+               wfProfileIn( __METHOD__ . "-misc" );
 
                # Don't allow internal links to pages containing
                # PROTO: where PROTO is a valid URL protocol; these
                # should be external links.
-               if( preg_match('/^\b(?i:' . wfUrlProtocols() . ')/', $titleText) ) {
-                       wfProfileOut( __METHOD__."-misc" );
+               if( preg_match( '/^\b(?i:' . wfUrlProtocols() . ')/', $titleText ) ) {
+                       wfProfileOut( __METHOD__ . "-misc" );
                        wfProfileOut( __METHOD__ );
                        return $wt;
                }
@@ -243,17 +243,17 @@ class Parser_LinkHooks extends Parser {
                $leadingColon = $titleText[0] == ':';
                if( $leadingColon ) $titleText = substr( $titleText, 1 );
 
-               wfProfileOut( __METHOD__."-misc" );
+               wfProfileOut( __METHOD__ . "-misc" );
                # Make title object
-               wfProfileIn( __METHOD__."-title" );
+               wfProfileIn( __METHOD__ . "-title" );
                $title = Title::newFromText( $this->mStripState->unstripNoWiki( $titleText ) );
                if( !$title ) {
-                       wfProfileOut( __METHOD__."-title" );
+                       wfProfileOut( __METHOD__ . "-title" );
                        wfProfileOut( __METHOD__ );
                        return $wt;
                }
                $ns = $title->getNamespace();
-               wfProfileOut( __METHOD__."-title" );
+               wfProfileOut( __METHOD__ . "-title" );
 
                # Default for Namespaces is a default link
                # ToDo: Default for patterns is plain wikitext
@@ -279,7 +279,7 @@ class Parser_LinkHooks extends Parser {
                if( $return === false ) {
                        # False (no link) was returned, output plain wikitext
                        # Build it again as the hook is allowed to modify $paramText
-                       $return = isset($paramText) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
+                       $return = isset( $paramText ) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
                }
                # Content was returned, return it
                wfProfileOut( __METHOD__ );
@@ -300,14 +300,14 @@ class LinkMarkerReplacer {
                $this->callback = $callback;
        }
 
-       function addMarker($titleText, $paramText) {
+       function addMarker( $titleText, $paramText ) {
                $id = $this->nextId++;
                $this->markers[$id] = array( $titleText, $paramText );
                return "<!-- LINKMARKER $id -->";
        }
 
        function findMarker( $string ) {
-               return (bool) preg_match('/<!-- LINKMARKER [0-9]+ -->/', $string );
+               return (bool) preg_match( '/<!-- LINKMARKER [0-9]+ -->/', $string );
        }
 
        function expand( $string ) {
@@ -315,8 +315,8 @@ class LinkMarkerReplacer {
        }
 
        function callback( $m ) {
-               $id = intval($m[1]);
-               if( !array_key_exists($id, $this->markers) ) return $m[0];
+               $id = intval( $m[1] );
+               if( !array_key_exists( $id, $this->markers ) ) return $m[0];
                $args = $this->markers[$id];
                array_unshift( $args, $this );
                array_unshift( $args, $this->holders );
index 53f3feb..468802d 100644 (file)
@@ -137,9 +137,9 @@ class Preprocessor_DOM implements Preprocessor {
                $cacheable = ( $wgPreprocessorCacheThreshold !== false
                        && strlen( $text ) > $wgPreprocessorCacheThreshold );
                if ( $cacheable ) {
-                       wfProfileIn( __METHOD__.'-cacheable' );
+                       wfProfileIn( __METHOD__ . '-cacheable' );
 
-                       $cacheKey = wfMemcKey( 'preprocess-xml', md5($text), $flags );
+                       $cacheKey = wfMemcKey( 'preprocess-xml', md5( $text ), $flags );
                        $cacheValue = $wgMemc->get( $cacheKey );
                        if ( $cacheValue ) {
                                $version = substr( $cacheValue, 0, 8 );
@@ -152,11 +152,11 @@ class Preprocessor_DOM implements Preprocessor {
                }
                if ( $xml === false ) {
                        if ( $cacheable ) {
-                               wfProfileIn( __METHOD__.'-cache-miss' );
+                               wfProfileIn( __METHOD__ . '-cache-miss' );
                                $xml = $this->preprocessToXml( $text, $flags );
                                $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . $xml;
                                $wgMemc->set( $cacheKey, $cacheValue, 86400 );
-                               wfProfileOut( __METHOD__.'-cache-miss' );
+                               wfProfileOut( __METHOD__ . '-cache-miss' );
                                wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" );
                        } else {
                                $xml = $this->preprocessToXml( $text, $flags );
@@ -169,10 +169,10 @@ class Preprocessor_DOM implements Preprocessor {
                $this->parser->mGeneratedPPNodeCount += substr_count( $xml, '<' );
                $max = $this->parser->mOptions->getMaxGeneratedPPNodeCount();
                if ( $this->parser->mGeneratedPPNodeCount > $max ) {
-                       throw new MWException( __METHOD__.': generated node count limit exceeded' );
+                       throw new MWException( __METHOD__ . ': generated node count limit exceeded' );
                }
 
-               wfProfileIn( __METHOD__.'-loadXML' );
+               wfProfileIn( __METHOD__ . '-loadXML' );
                $dom = new DOMDocument;
                wfSuppressWarnings();
                $result = $dom->loadXML( $xml );
@@ -183,13 +183,13 @@ class Preprocessor_DOM implements Preprocessor {
                        // 1 << 19 == XML_PARSE_HUGE, needed so newer versions of libxml2 don't barf when the XML is >256 levels deep
                        $result = $dom->loadXML( $xml, 1 << 19 );
                        if ( !$result ) {
-                               throw new MWException( __METHOD__.' generated invalid XML' );
+                               throw new MWException( __METHOD__ . ' generated invalid XML' );
                        }
                }
                $obj = new PPNode_DOM( $dom->documentElement );
-               wfProfileOut( __METHOD__.'-loadXML' );
+               wfProfileOut( __METHOD__ . '-loadXML' );
                if ( $cacheable ) {
-                       wfProfileOut( __METHOD__.'-cacheable' );
+                       wfProfileOut( __METHOD__ . '-cacheable' );
                }
                wfProfileOut( __METHOD__ );
                return $obj;
@@ -397,7 +397,7 @@ class Preprocessor_DOM implements Preprocessor {
 
                                                if ( $stack->top ) {
                                                        $part = $stack->top->getCurrentPart();
-                                                       if ( ! (isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
+                                                       if ( !(isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
                                                                $part->visualEnd = $wsStart;
                                                        }
                                                        // Else comments abutting, no change in visual end
@@ -658,19 +658,13 @@ class Preprocessor_DOM implements Preprocessor {
                                        $piece->parts = array( new PPDPart );
                                        $piece->count -= $matchingCount;
                                        # do we still qualify for any callback with remaining count?
-                                       $names = $rules[$piece->open]['names'];
-                                       $skippedBraces = 0;
-                                       $enclosingAccum =& $accum;
-                                       while ( $piece->count ) {
-                                               if ( array_key_exists( $piece->count, $names ) ) {
-                                                       $stack->push( $piece );
-                                                       $accum =& $stack->getAccum();
-                                                       break;
-                                               }
-                                               --$piece->count;
-                                               $skippedBraces ++;
+                                       $min = $rules[$piece->open]['min'];
+                                       if ( $piece->count >= $min ) {
+                                               $stack->push( $piece );
+                                               $accum =& $stack->getAccum();
+                                       } else {
+                                               $accum .= str_repeat( $piece->open, $piece->count );
                                        }
-                                       $enclosingAccum .= str_repeat( $piece->open, $skippedBraces );
                                }
                                $flags = $stack->getFlags();
                                extract( $flags );
@@ -758,7 +752,7 @@ class PPDStack {
 
        function pop() {
                if ( !count( $this->stack ) ) {
-                       throw new MWException( __METHOD__.': no elements remaining' );
+                       throw new MWException( __METHOD__ . ': no elements remaining' );
                }
                $temp = array_pop( $this->stack );
 
@@ -815,7 +809,7 @@ class PPDStackElement {
        }
 
        function &getAccum() {
-               return $this->parts[count($this->parts) - 1]->out;
+               return $this->parts[count( $this->parts ) - 1]->out;
        }
 
        function addPart( $s = '' ) {
@@ -824,7 +818,7 @@ class PPDStackElement {
        }
 
        function getCurrentPart() {
-               return $this->parts[count($this->parts) - 1];
+               return $this->parts[count( $this->parts ) - 1];
        }
 
        /**
@@ -1118,7 +1112,7 @@ class PPFrame_DOM implements PPFrame {
                                        }
                                        # Add a strip marker in PST mode so that pstPass2() can run some old-fashioned regexes on the result
                                        # Not in RECOVER_COMMENTS mode (extractSections) though
-                                       elseif ( $this->parser->ot['wiki'] && ! ( $flags & PPFrame::RECOVER_COMMENTS ) ) {
+                                       elseif ( $this->parser->ot['wiki'] && !( $flags & PPFrame::RECOVER_COMMENTS ) ) {
                                                $out .= $this->parser->insertStripItem( $contextNode->textContent );
                                        }
                                        # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
@@ -1175,7 +1169,7 @@ class PPFrame_DOM implements PPFrame {
                                }
                        } else {
                                wfProfileOut( __METHOD__ );
-                               throw new MWException( __METHOD__.': Invalid parameter type' );
+                               throw new MWException( __METHOD__ . ': Invalid parameter type' );
                        }
 
                        if ( $newIterator !== false ) {
@@ -1459,25 +1453,25 @@ class PPTemplateFrame_DOM extends PPFrame_DOM {
        function getArguments() {
                $arguments = array();
                foreach ( array_merge(
-                               array_keys($this->numberedArgs),
-                               array_keys($this->namedArgs)) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+                               array_keys( $this->numberedArgs ),
+                               array_keys( $this->namedArgs ) ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
 
        function getNumberedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->numberedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->numberedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
 
        function getNamedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->namedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->namedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
index a4e408e..c22da64 100644 (file)
@@ -116,9 +116,9 @@ class Preprocessor_Hash implements Preprocessor {
 
                $cacheable = $wgPreprocessorCacheThreshold !== false && strlen( $text ) > $wgPreprocessorCacheThreshold;
                if ( $cacheable ) {
-                       wfProfileIn( __METHOD__.'-cacheable' );
+                       wfProfileIn( __METHOD__ . '-cacheable' );
 
-                       $cacheKey = wfMemcKey( 'preprocess-hash', md5($text), $flags );
+                       $cacheKey = wfMemcKey( 'preprocess-hash', md5( $text ), $flags );
                        $cacheValue = $wgMemc->get( $cacheKey );
                        if ( $cacheValue ) {
                                $version = substr( $cacheValue, 0, 8 );
@@ -127,12 +127,12 @@ class Preprocessor_Hash implements Preprocessor {
                                        // From the cache
                                        wfDebugLog( "Preprocessor",
                                                "Loaded preprocessor hash from memcached (key $cacheKey)" );
-                                       wfProfileOut( __METHOD__.'-cacheable' );
+                                       wfProfileOut( __METHOD__ . '-cacheable' );
                                        wfProfileOut( __METHOD__ );
                                        return $hash;
                                }
                        }
-                       wfProfileIn( __METHOD__.'-cache-miss' );
+                       wfProfileIn( __METHOD__ . '-cache-miss' );
                }
 
                $rules = array(
@@ -332,7 +332,7 @@ class Preprocessor_Hash implements Preprocessor {
 
                                                if ( $stack->top ) {
                                                        $part = $stack->top->getCurrentPart();
-                                                       if ( ! (isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
+                                                       if ( !(isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
                                                                $part->visualEnd = $wsStart;
                                                        }
                                                        // Else comments abutting, no change in visual end
@@ -391,7 +391,7 @@ class Preprocessor_Hash implements Preprocessor {
                                }
                                // <includeonly> and <noinclude> just become <ignore> tags
                                if ( in_array( $lowerName, $ignoredElements ) ) {
-                                       $accum->addNodeWithText(  'ignore', substr( $text, $tagStartPos, $i - $tagStartPos ) );
+                                       $accum->addNodeWithText( 'ignore', substr( $text, $tagStartPos, $i - $tagStartPos ) );
                                        continue;
                                }
 
@@ -549,7 +549,7 @@ class Preprocessor_Hash implements Preprocessor {
                                        }
                                }
 
-                               if ($matchingCount <= 0) {
+                               if ( $matchingCount <= 0 ) {
                                        # No matching element found in callback array
                                        # Output a literal closing brace and continue
                                        $accum->addLiteral( str_repeat( $curChar, $count ) );
@@ -591,10 +591,10 @@ class Preprocessor_Hash implements Preprocessor {
                                                                $lastNode = $node;
                                                        }
                                                        if ( !$node ) {
-                                                               throw new MWException( __METHOD__. ': eqpos not found' );
+                                                               throw new MWException( __METHOD__ . ': eqpos not found' );
                                                        }
                                                        if ( $node->name !== 'equals' ) {
-                                                               throw new MWException( __METHOD__ .': eqpos is not equals' );
+                                                               throw new MWException( __METHOD__ . ': eqpos is not equals' );
                                                        }
                                                        $equalsNode = $node;
 
@@ -639,23 +639,17 @@ class Preprocessor_Hash implements Preprocessor {
                                $accum =& $stack->getAccum();
 
                                # Re-add the old stack element if it still has unmatched opening characters remaining
-                               if ($matchingCount < $piece->count) {
+                               if ( $matchingCount < $piece->count ) {
                                        $piece->parts = array( new PPDPart_Hash );
                                        $piece->count -= $matchingCount;
                                        # do we still qualify for any callback with remaining count?
-                                       $names = $rules[$piece->open]['names'];
-                                       $skippedBraces = 0;
-                                       $enclosingAccum =& $accum;
-                                       while ( $piece->count ) {
-                                               if ( array_key_exists( $piece->count, $names ) ) {
-                                                       $stack->push( $piece );
-                                                       $accum =& $stack->getAccum();
-                                                       break;
-                                               }
-                                               --$piece->count;
-                                               $skippedBraces ++;
+                                       $min = $rules[$piece->open]['min'];
+                                       if ( $piece->count >= $min ) {
+                                               $stack->push( $piece );
+                                               $accum =& $stack->getAccum();
+                                       } else {
+                                               $accum->addLiteral( str_repeat( $piece->open, $piece->count ) );
                                        }
-                                       $enclosingAccum->addLiteral( str_repeat( $piece->open, $skippedBraces ) );
                                }
 
                                extract( $stack->getFlags() );
@@ -696,11 +690,11 @@ class Preprocessor_Hash implements Preprocessor {
                $rootNode->lastChild = $stack->rootAccum->lastNode;
 
                // Cache
-               if ($cacheable) {
+               if ( $cacheable ) {
                        $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . serialize( $rootNode );
                        $wgMemc->set( $cacheKey, $cacheValue, 86400 );
-                       wfProfileOut( __METHOD__.'-cache-miss' );
-                       wfProfileOut( __METHOD__.'-cacheable' );
+                       wfProfileOut( __METHOD__ . '-cache-miss' );
+                       wfProfileOut( __METHOD__ . '-cacheable' );
                        wfDebugLog( "Preprocessor", "Saved preprocessor Hash to memcached (key $cacheKey)" );
                }
 
@@ -1038,7 +1032,7 @@ class PPFrame_Hash implements PPFrame {
                                        }
                                        # Add a strip marker in PST mode so that pstPass2() can run some old-fashioned regexes on the result
                                        # Not in RECOVER_COMMENTS mode (extractSections) though
-                                       elseif ( $this->parser->ot['wiki'] && ! ( $flags & PPFrame::RECOVER_COMMENTS ) ) {
+                                       elseif ( $this->parser->ot['wiki'] && !( $flags & PPFrame::RECOVER_COMMENTS ) ) {
                                                $out .= $this->parser->insertStripItem( $contextNode->firstChild->value );
                                        }
                                        # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
@@ -1085,7 +1079,7 @@ class PPFrame_Hash implements PPFrame {
                                        $newIterator = $contextNode->getChildren();
                                }
                        } else {
-                               throw new MWException( __METHOD__.': Invalid parameter type' );
+                               throw new MWException( __METHOD__ . ': Invalid parameter type' );
                        }
 
                        if ( $newIterator !== false ) {
@@ -1374,9 +1368,9 @@ class PPTemplateFrame_Hash extends PPFrame_Hash {
        function getArguments() {
                $arguments = array();
                foreach ( array_merge(
-                               array_keys($this->numberedArgs),
-                               array_keys($this->namedArgs)) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+                               array_keys( $this->numberedArgs ),
+                               array_keys( $this->namedArgs ) ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
@@ -1386,8 +1380,8 @@ class PPTemplateFrame_Hash extends PPFrame_Hash {
         */
        function getNumberedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->numberedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->numberedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
@@ -1397,8 +1391,8 @@ class PPTemplateFrame_Hash extends PPFrame_Hash {
         */
        function getNamedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->namedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->namedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
diff --git a/includes/parser/Preprocessor_HipHop.hphp b/includes/parser/Preprocessor_HipHop.hphp
deleted file mode 100644 (file)
index 8059e35..0000000
+++ /dev/null
@@ -1,2014 +0,0 @@
-<?php
-/**
- * A preprocessor optimised for HipHop, using HipHop-specific syntax.
- * vim: ft=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
- * @ingroup Parser
- */
-
-/**
- * @ingroup Parser
- */
-class Preprocessor_HipHop implements Preprocessor {
-       /**
-        * @var Parser
-        */
-       var $parser;
-
-       const CACHE_VERSION = 1;
-
-       /**
-        * @param $parser Parser
-        */
-       function __construct( $parser ) {
-               $this->parser = $parser;
-       }
-
-       /**
-        * @return PPFrame_HipHop
-        */
-       function newFrame() {
-               return new PPFrame_HipHop( $this );
-       }
-
-       /**
-        * @param $args array
-        * @return PPCustomFrame_HipHop
-        */
-       function newCustomFrame( $args ) {
-               return new PPCustomFrame_HipHop( $this, $args );
-       }
-
-       /**
-        * @param $values array
-        * @return PPNode_HipHop_Array
-        */
-       function newPartNodeArray( $values ) {
-               $list = array();
-
-               foreach ( $values as $k => $val ) {
-                       $partNode = new PPNode_HipHop_Tree( 'part' );
-                       $nameNode = new PPNode_HipHop_Tree( 'name' );
-
-                       if ( is_int( $k ) ) {
-                               $nameNode->addChild( new PPNode_HipHop_Attr( 'index', $k ) );
-                               $partNode->addChild( $nameNode );
-                       } else {
-                               $nameNode->addChild( new PPNode_HipHop_Text( $k ) );
-                               $partNode->addChild( $nameNode );
-                               $partNode->addChild( new PPNode_HipHop_Text( '=' ) );
-                       }
-
-                       $valueNode = new PPNode_HipHop_Tree( 'value' );
-                       $valueNode->addChild( new PPNode_HipHop_Text( $val ) );
-                       $partNode->addChild( $valueNode );
-
-                       $list[] = $partNode;
-               }
-
-               $node = new PPNode_HipHop_Array( $list );
-               return $node;
-       }
-
-       /**
-        * Preprocess some wikitext and return the document tree.
-        * This is the ghost of Parser::replace_variables().
-        *
-        * @param $text String: the text to parse
-        * @param $flags Integer: bitwise combination of:
-        *          Parser::PTD_FOR_INCLUSION    Handle <noinclude>/<includeonly> as if the text is being
-        *                                     included. Default is to assume a direct page view.
-        *
-        * The generated DOM tree must depend only on the input text and the flags.
-        * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899.
-        *
-        * Any flag added to the $flags parameter here, or any other parameter liable to cause a
-        * change in the DOM tree for a given text, must be passed through the section identifier
-        * in the section edit link and thus back to extractSections().
-        *
-        * The output of this function is currently only cached in process memory, but a persistent
-        * cache may be implemented at a later date which takes further advantage of these strict
-        * dependency requirements.
-        *
-        * @throws MWException
-        * @return PPNode_HipHop_Tree
-        */
-       function preprocessToObj( $text, $flags = 0 ) {
-               wfProfileIn( __METHOD__ );
-
-               // Check cache.
-               global $wgMemc, $wgPreprocessorCacheThreshold;
-
-               $lengthText = strlen( $text );
-
-               $cacheable = ($wgPreprocessorCacheThreshold !== false && $lengthText > $wgPreprocessorCacheThreshold);
-               if ( $cacheable ) {
-                       wfProfileIn( __METHOD__.'-cacheable' );
-
-                       $cacheKey = strval( wfMemcKey( 'preprocess-hash', md5($text), $flags ) );
-                       $cacheValue = strval( $wgMemc->get( $cacheKey ) );
-                       if ( $cacheValue !== '' ) {
-                               $version = substr( $cacheValue, 0, 8 );
-                               if ( intval( $version ) == self::CACHE_VERSION ) {
-                                       $hash = unserialize( substr( $cacheValue, 8 ) );
-                                       // From the cache
-                                       wfDebugLog( "Preprocessor",
-                                               "Loaded preprocessor hash from memcached (key $cacheKey)" );
-                                       wfProfileOut( __METHOD__.'-cacheable' );
-                                       wfProfileOut( __METHOD__ );
-                                       return $hash;
-                               }
-                       }
-                       wfProfileIn( __METHOD__.'-cache-miss' );
-               }
-
-               $rules = array(
-                       '{' => array(
-                               'end' => '}',
-                               'names' => array(
-                                       2 => 'template',
-                                       3 => 'tplarg',
-                               ),
-                               'min' => 2,
-                               'max' => 3,
-                       ),
-                       '[' => array(
-                               'end' => ']',
-                               'names' => array( 2 => 'LITERAL' ),
-                               'min' => 2,
-                               'max' => 2,
-                       )
-               );
-
-               $forInclusion = (bool)( $flags & Parser::PTD_FOR_INCLUSION );
-
-               $xmlishElements = (array)$this->parser->getStripList();
-               $enableOnlyinclude = false;
-               if ( $forInclusion ) {
-                       $ignoredTags = array( 'includeonly', '/includeonly' );
-                       $ignoredElements = array( 'noinclude' );
-                       $xmlishElements[] = 'noinclude';
-                       if ( strpos( $text, '<onlyinclude>' ) !== false && strpos( $text, '</onlyinclude>' ) !== false ) {
-                               $enableOnlyinclude = true;
-                       }
-               } else if ( $this->parser->ot['wiki'] ) {
-                       $ignoredTags = array( 'noinclude', '/noinclude', 'onlyinclude', '/onlyinclude', 'includeonly', '/includeonly' );
-                       $ignoredElements = array();
-               } else {
-                       $ignoredTags = array( 'noinclude', '/noinclude', 'onlyinclude', '/onlyinclude' );
-                       $ignoredElements = array( 'includeonly' );
-                       $xmlishElements[] = 'includeonly';
-               }
-               $xmlishRegex = implode( '|', array_merge( $xmlishElements, $ignoredTags ) );
-
-               // Use "A" modifier (anchored) instead of "^", because ^ doesn't work with an offset
-               $elementsRegex = "~($xmlishRegex)(?:\s|\/>|>)|(!--)~iA";
-
-               $stack = new PPDStack_HipHop;
-
-               $searchBase = "[{<\n";
-               $revText = strrev( $text ); // For fast reverse searches
-
-               $i = 0;                     # Input pointer, starts out pointing to a pseudo-newline before the start
-               $accum = $stack->getAccum();   # Current accumulator
-               $headingIndex = 1;
-               $stackFlags = array(
-                       'findPipe' => false, # True to take notice of pipe characters
-                       'findEquals' => false, # True to find equals signs in arguments
-                       'inHeading' => false, # True if $i is inside a possible heading
-               );
-               $noMoreGT = false;         # True if there are no more greater-than (>) signs right of $i
-               $findOnlyinclude = $enableOnlyinclude; # True to ignore all input up to the next <onlyinclude>
-               $fakeLineStart = true;     # Do a line-start run without outputting an LF character
-
-               while ( true ) {
-                       //$this->memCheck();
-
-                       if ( $findOnlyinclude ) {
-                               // Ignore all input up to the next <onlyinclude>
-                               $variantStartPos = strpos( $text, '<onlyinclude>', $i );
-                               if ( $variantStartPos === false ) {
-                                       // Ignored section runs to the end
-                                       $accum->addNodeWithText( 'ignore', strval( substr( $text, $i ) ) );
-                                       break;
-                               }
-                               $startPos1 = intval( $variantStartPos );
-                               $tagEndPos = $startPos1 + strlen( '<onlyinclude>' ); // past-the-end
-                               $accum->addNodeWithText( 'ignore', strval( substr( $text, $i, $tagEndPos - $i ) ) );
-                               $i = $tagEndPos;
-                               $findOnlyinclude = false;
-                       }
-
-                       if ( $fakeLineStart ) {
-                               $found = 'line-start';
-                               $curChar = '';
-                       } else {
-                               # Find next opening brace, closing brace or pipe
-                               $search = $searchBase;
-                               if ( $stack->top === false ) {
-                                       $currentClosing = '';
-                               } else {
-                                       $currentClosing = strval( $stack->getTop()->close );
-                                       $search .= $currentClosing;
-                               }
-                               if ( $stackFlags['findPipe'] ) {
-                                       $search .= '|';
-                               }
-                               if ( $stackFlags['findEquals'] ) {
-                                       // First equals will be for the template
-                                       $search .= '=';
-                               }
-                               $rule = null;
-                               # Output literal section, advance input counter
-                               $literalLength = intval( strcspn( $text, $search, $i ) );
-                               if ( $literalLength > 0 ) {
-                                       $accum->addLiteral( strval( substr( $text, $i, $literalLength ) ) );
-                                       $i += $literalLength;
-                               }
-                               if ( $i >= $lengthText ) {
-                                       if ( $currentClosing === "\n" ) {
-                                               // Do a past-the-end run to finish off the heading
-                                               $curChar = '';
-                                               $found = 'line-end';
-                                       } else {
-                                               # All done
-                                               break;
-                                       }
-                               } else {
-                                       $curChar = $text[$i];
-                                       if ( $curChar === '|' ) {
-                                               $found = 'pipe';
-                                       } elseif ( $curChar === '=' ) {
-                                               $found = 'equals';
-                                       } elseif ( $curChar === '<' ) {
-                                               $found = 'angle';
-                                       } elseif ( $curChar === "\n" ) {
-                                               if ( $stackFlags['inHeading'] ) {
-                                                       $found = 'line-end';
-                                               } else {
-                                                       $found = 'line-start';
-                                               }
-                                       } elseif ( $curChar === $currentClosing ) {
-                                               $found = 'close';
-                                       } elseif ( isset( $rules[$curChar] ) ) {
-                                               $found = 'open';
-                                               $rule = $rules[$curChar];
-                                       } else {
-                                               # Some versions of PHP have a strcspn which stops on null characters
-                                               # Ignore and continue
-                                               ++$i;
-                                               continue;
-                                       }
-                               }
-                       }
-
-                       if ( $found === 'angle' ) {
-                               $matches = false;
-                               // Handle </onlyinclude>
-                               if ( $enableOnlyinclude
-                                       && substr( $text, $i, strlen( '</onlyinclude>' ) ) === '</onlyinclude>' )
-                               {
-                                       $findOnlyinclude = true;
-                                       continue;
-                               }
-
-                               // Determine element name
-                               if ( !preg_match( $elementsRegex, $text, $matches, 0, $i + 1 ) ) {
-                                       // Element name missing or not listed
-                                       $accum->addLiteral( '<' );
-                                       ++$i;
-                                       continue;
-                               }
-                               // Handle comments
-                               if ( isset( $matches[2] ) && $matches[2] === '!--' ) {
-                                       // To avoid leaving blank lines, when a comment is both preceded
-                                       // and followed by a newline (ignoring spaces), trim leading and
-                                       // trailing spaces and one of the newlines.
-
-                                       // Find the end
-                                       $variantEndPos = strpos( $text, '-->', $i + 4 );
-                                       if ( $variantEndPos === false ) {
-                                               // Unclosed comment in input, runs to end
-                                               $inner = strval( substr( $text, $i ) );
-                                               $accum->addNodeWithText( 'comment', $inner );
-                                               $i = $lengthText;
-                                       } else {
-                                               $endPos = intval( $variantEndPos );
-                                               // Search backwards for leading whitespace
-                                               if ( $i ) {
-                                                       $wsStart = $i - intval( strspn( $revText, ' ', $lengthText - $i ) );
-                                               } else {
-                                                       $wsStart = 0;
-                                               }
-                                               // Search forwards for trailing whitespace
-                                               // $wsEnd will be the position of the last space (or the '>' if there's none)
-                                               $wsEnd = $endPos + 2 + intval( strspn( $text, ' ', $endPos + 3 ) );
-                                               // Eat the line if possible
-                                               // TODO: This could theoretically be done if $wsStart == 0, i.e. for comments at
-                                               // the overall start. That's not how Sanitizer::removeHTMLcomments() did it, but
-                                               // it's a possible beneficial b/c break.
-                                               if ( $wsStart > 0 && substr( $text, $wsStart - 1, 1 ) === "\n"
-                                                       && substr( $text, $wsEnd + 1, 1 ) === "\n" )
-                                               {
-                                                       $startPos2 = $wsStart;
-                                                       $endPos = $wsEnd + 1;
-                                                       // Remove leading whitespace from the end of the accumulator
-                                                       // Sanity check first though
-                                                       $wsLength = $i - $wsStart;
-                                                       if ( $wsLength > 0
-                                                               && $accum->lastNode instanceof PPNode_HipHop_Text
-                                                               && substr( $accum->lastNode->value, -$wsLength ) === str_repeat( ' ', $wsLength ) )
-                                                       {
-                                                               $accum->lastNode->value = strval( substr( $accum->lastNode->value, 0, -$wsLength ) );
-                                                       }
-                                                       // Do a line-start run next time to look for headings after the comment
-                                                       $fakeLineStart = true;
-                                               } else {
-                                                       // No line to eat, just take the comment itself
-                                                       $startPos2 = $i;
-                                                       $endPos += 2;
-                                               }
-
-                                               if ( $stack->top ) {
-                                                       $part = $stack->getTop()->getCurrentPart();
-                                                       if ( ! (isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
-                                                               $part->visualEnd = $wsStart;
-                                                       }
-                                                       // Else comments abutting, no change in visual end
-                                                       $part->commentEnd = $endPos;
-                                               }
-                                               $i = $endPos + 1;
-                                               $inner = strval( substr( $text, $startPos2, $endPos - $startPos2 + 1 ) );
-                                               $accum->addNodeWithText( 'comment', $inner );
-                                       }
-                                       continue;
-                               }
-                               $name = strval( $matches[1] );
-                               $lowerName = strtolower( $name );
-                               $attrStart = $i + strlen( $name ) + 1;
-
-                               // Find end of tag
-                               $variantTagEndPos = $noMoreGT ? false : strpos( $text, '>', $attrStart );
-                               if ( $variantTagEndPos === false ) {
-                                       // Infinite backtrack
-                                       // Disable tag search to prevent worst-case O(N^2) performance
-                                       $noMoreGT = true;
-                                       $accum->addLiteral( '<' );
-                                       ++$i;
-                                       continue;
-                               }
-                               $tagEndPos = intval( $variantTagEndPos );
-
-                               // Handle ignored tags
-                               if ( in_array( $lowerName, $ignoredTags ) ) {
-                                       $accum->addNodeWithText( 'ignore', strval( substr( $text, $i, $tagEndPos - $i + 1 ) ) );
-                                       $i = $tagEndPos + 1;
-                                       continue;
-                               }
-
-                               $tagStartPos = $i;
-                               $close = '';
-                               if ( $text[$tagEndPos-1] === '/' ) {
-                                       // Short end tag
-                                       $attrEnd = $tagEndPos - 1;
-                                       $shortEnd = true;
-                                       $inner = '';
-                                       $i = $tagEndPos + 1;
-                                       $haveClose = false;
-                               } else {
-                                       $attrEnd = $tagEndPos;
-                                       $shortEnd = false;
-                                       // Find closing tag
-                                       if ( preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",
-                                                       $text, $matches, PREG_OFFSET_CAPTURE, $tagEndPos + 1 ) )
-                                       {
-                                               $inner = strval( substr( $text, $tagEndPos + 1, $matches[0][1] - $tagEndPos - 1 ) );
-                                               $i = intval( $matches[0][1] ) + strlen( $matches[0][0] );
-                                               $close = strval( $matches[0][0] );
-                                               $haveClose = true;
-                                       } else {
-                                               // No end tag -- let it run out to the end of the text.
-                                               $inner = strval( substr( $text, $tagEndPos + 1 ) );
-                                               $i = $lengthText;
-                                               $haveClose = false;
-                                       }
-                               }
-                               // <includeonly> and <noinclude> just become <ignore> tags
-                               if ( in_array( $lowerName, $ignoredElements ) ) {
-                                       $accum->addNodeWithText(  'ignore', strval( substr( $text, $tagStartPos, $i - $tagStartPos ) ) );
-                                       continue;
-                               }
-
-                               if ( $attrEnd <= $attrStart ) {
-                                       $attr = '';
-                               } else {
-                                       // Note that the attr element contains the whitespace between name and attribute,
-                                       // this is necessary for precise reconstruction during pre-save transform.
-                                       $attr = strval( substr( $text, $attrStart, $attrEnd - $attrStart ) );
-                               }
-
-                               $extNode = new PPNode_HipHop_Tree( 'ext' );
-                               $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'name', $name ) );
-                               $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'attr', $attr ) );
-                               if ( !$shortEnd ) {
-                                       $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'inner', $inner ) );
-                               }
-                               if ( $haveClose ) {
-                                       $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'close', $close ) );
-                               }
-                               $accum->addNode( $extNode );
-                       }
-
-                       elseif ( $found === 'line-start' ) {
-                               // Is this the start of a heading?
-                               // Line break belongs before the heading element in any case
-                               if ( $fakeLineStart ) {
-                                       $fakeLineStart = false;
-                               } else {
-                                       $accum->addLiteral( $curChar );
-                                       $i++;
-                               }
-
-                               $count = intval( strspn( $text, '=', $i, 6 ) );
-                               if ( $count == 1 && $stackFlags['findEquals'] ) {
-                                       // DWIM: This looks kind of like a name/value separator
-                                       // Let's let the equals handler have it and break the potential heading
-                                       // This is heuristic, but AFAICT the methods for completely correct disambiguation are very complex.
-                               } elseif ( $count > 0 ) {
-                                       $partData = array(
-                                               'open' => "\n",
-                                               'close' => "\n",
-                                               'parts' => array( new PPDPart_HipHop( str_repeat( '=', $count ) ) ),
-                                               'startPos' => $i,
-                                               'count' => $count );
-                                       $stack->push( $partData );
-                                       $accum = $stack->getAccum();
-                                       $stackFlags = $stack->getFlags();
-                                       $i += $count;
-                               }
-                       } elseif ( $found === 'line-end' ) {
-                               $piece = $stack->getTop();
-                               // A heading must be open, otherwise \n wouldn't have been in the search list
-                               assert( $piece->open === "\n" ); // Passing the assert condition directly instead of string, as
-                                                                // HPHP /compiler/ chokes on strings when ASSERT_ACTIVE != 0.
-                               $part = $piece->getCurrentPart();
-                               // Search back through the input to see if it has a proper close
-                               // Do this using the reversed string since the other solutions (end anchor, etc.) are inefficient
-                               $wsLength = intval( strspn( $revText, " \t", $lengthText - $i ) );
-                               $searchStart = $i - $wsLength;
-                               if ( isset( $part->commentEnd ) && $searchStart - 1 == $part->commentEnd ) {
-                                       // Comment found at line end
-                                       // Search for equals signs before the comment
-                                       $searchStart = intval( $part->visualEnd );
-                                       $searchStart -= intval( strspn( $revText, " \t", $lengthText - $searchStart ) );
-                               }
-                               $count = intval( $piece->count );
-                               $equalsLength = intval( strspn( $revText, '=', $lengthText - $searchStart ) );
-                               $isTreeNode = false;
-                               $resultAccum = $accum;
-                               if ( $equalsLength > 0 ) {
-                                       if ( $searchStart - $equalsLength == $piece->startPos ) {
-                                               // This is just a single string of equals signs on its own line
-                                               // Replicate the doHeadings behaviour /={count}(.+)={count}/
-                                               // First find out how many equals signs there really are (don't stop at 6)
-                                               $count = $equalsLength;
-                                               if ( $count < 3 ) {
-                                                       $count = 0;
-                                               } else {
-                                                       $count = intval( ( $count - 1 ) / 2 );
-                                                       if ( $count > 6 ) {
-                                                               $count = 6;
-                                                       }
-                                               }
-                                       } else {
-                                               if ( $count > $equalsLength ) {
-                                                       $count = $equalsLength;
-                                               }
-                                       }
-                                       if ( $count > 0 ) {
-                                               // Normal match, output <h>
-                                               $tree = new PPNode_HipHop_Tree( 'possible-h' );
-                                               $tree->addChild( new PPNode_HipHop_Attr( 'level', $count ) );
-                                               $tree->addChild( new PPNode_HipHop_Attr( 'i', $headingIndex++ ) );
-                                               $tree->lastChild->nextSibling = $accum->firstNode;
-                                               $tree->lastChild = $accum->lastNode;
-                                               $isTreeNode = true;
-                                       } else {
-                                               // Single equals sign on its own line, count=0
-                                               // Output $resultAccum
-                                       }
-                               } else {
-                                       // No match, no <h>, just pass down the inner text
-                                       // Output $resultAccum
-                               }
-                               // Unwind the stack
-                               $stack->pop();
-                               $accum = $stack->getAccum();
-                               $stackFlags = $stack->getFlags();
-
-                               // Append the result to the enclosing accumulator
-                               if ( $isTreeNode ) {
-                                       $accum->addNode( $tree );
-                               } else {
-                                       $accum->addAccum( $resultAccum );
-                               }
-                               // Note that we do NOT increment the input pointer.
-                               // This is because the closing linebreak could be the opening linebreak of
-                               // another heading. Infinite loops are avoided because the next iteration MUST
-                               // hit the heading open case above, which unconditionally increments the
-                               // input pointer.
-                       } elseif ( $found === 'open' ) {
-                               # count opening brace characters
-                               $count = intval( strspn( $text, $curChar, $i ) );
-
-                               # we need to add to stack only if opening brace count is enough for one of the rules
-                               if ( $count >= $rule['min'] ) {
-                                       # Add it to the stack
-                                       $partData = array(
-                                               'open' => $curChar,
-                                               'close' => $rule['end'],
-                                               'count' => $count,
-                                               'lineStart' => ($i == 0 || $text[$i-1] === "\n"),
-                                       );
-
-                                       $stack->push( $partData );
-                                       $accum = $stack->getAccum();
-                                       $stackFlags = $stack->getFlags();
-                               } else {
-                                       # Add literal brace(s)
-                                       $accum->addLiteral( str_repeat( $curChar, $count ) );
-                               }
-                               $i += $count;
-                       } elseif ( $found === 'close' ) {
-                               $piece = $stack->getTop();
-                               # lets check if there are enough characters for closing brace
-                               $maxCount = intval( $piece->count );
-                               $count = intval( strspn( $text, $curChar, $i, $maxCount ) );
-
-                               # check for maximum matching characters (if there are 5 closing
-                               # characters, we will probably need only 3 - depending on the rules)
-                               $rule = $rules[$piece->open];
-                               if ( $count > $rule['max'] ) {
-                                       # The specified maximum exists in the callback array, unless the caller
-                                       # has made an error
-                                       $matchingCount = intval( $rule['max'] );
-                               } else {
-                                       # Count is less than the maximum
-                                       # Skip any gaps in the callback array to find the true largest match
-                                       # Need to use array_key_exists not isset because the callback can be null
-                                       $matchingCount = $count;
-                                       while ( $matchingCount > 0 && !array_key_exists( $matchingCount, $rule['names'] ) ) {
-                                               --$matchingCount;
-                                       }
-                               }
-
-                               if ($matchingCount <= 0) {
-                                       # No matching element found in callback array
-                                       # Output a literal closing brace and continue
-                                       $accum->addLiteral( str_repeat( $curChar, $count ) );
-                                       $i += $count;
-                                       continue;
-                               }
-                               $name = strval( $rule['names'][$matchingCount] );
-                               $isTreeNode = false;
-                               if ( $name === 'LITERAL' ) {
-                                       // No element, just literal text
-                                       $resultAccum = $piece->breakSyntax( $matchingCount );
-                                       $resultAccum->addLiteral( str_repeat( $rule['end'], $matchingCount ) );
-                               } else {
-                                       # Create XML element
-                                       # Note: $parts is already XML, does not need to be encoded further
-                                       $isTreeNode = true;
-                                       $parts = $piece->parts;
-                                       $titleAccum = PPDAccum_HipHop::cast( $parts[0]->out );
-                                       unset( $parts[0] );
-
-                                       $tree = new PPNode_HipHop_Tree( $name );
-
-                                       # The invocation is at the start of the line if lineStart is set in
-                                       # the stack, and all opening brackets are used up.
-                                       if ( $maxCount == $matchingCount && !empty( $piece->lineStart ) ) {
-                                               $tree->addChild( new PPNode_HipHop_Attr( 'lineStart', 1 ) );
-                                       }
-                                       $titleNode = new PPNode_HipHop_Tree( 'title' );
-                                       $titleNode->firstChild = $titleAccum->firstNode;
-                                       $titleNode->lastChild = $titleAccum->lastNode;
-                                       $tree->addChild( $titleNode );
-                                       $argIndex = 1;
-                                       foreach ( $parts as $variantPart ) {
-                                               $part = PPDPart_HipHop::cast( $variantPart );
-                                               if ( isset( $part->eqpos ) ) {
-                                                       // Find equals
-                                                       $lastNode = false;
-                                                       for ( $node = $part->out->firstNode; $node; $node = $node->nextSibling ) {
-                                                               if ( $node === $part->eqpos ) {
-                                                                       break;
-                                                               }
-                                                               $lastNode = $node;
-                                                       }
-                                                       if ( !$node ) {
-                                                               throw new MWException( __METHOD__. ': eqpos not found' );
-                                                       }
-                                                       if ( $node->name !== 'equals' ) {
-                                                               throw new MWException( __METHOD__ .': eqpos is not equals' );
-                                                       }
-                                                       $equalsNode = $node;
-
-                                                       // Construct name node
-                                                       $nameNode = new PPNode_HipHop_Tree( 'name' );
-                                                       if ( $lastNode !== false ) {
-                                                               $lastNode->nextSibling = false;
-                                                               $nameNode->firstChild = $part->out->firstNode;
-                                                               $nameNode->lastChild = $lastNode;
-                                                       }
-
-                                                       // Construct value node
-                                                       $valueNode = new PPNode_HipHop_Tree( 'value' );
-                                                       if ( $equalsNode->nextSibling !== false ) {
-                                                               $valueNode->firstChild = $equalsNode->nextSibling;
-                                                               $valueNode->lastChild = $part->out->lastNode;
-                                                       }
-                                                       $partNode = new PPNode_HipHop_Tree( 'part' );
-                                                       $partNode->addChild( $nameNode );
-                                                       $partNode->addChild( $equalsNode->firstChild );
-                                                       $partNode->addChild( $valueNode );
-                                                       $tree->addChild( $partNode );
-                                               } else {
-                                                       $partNode = new PPNode_HipHop_Tree( 'part' );
-                                                       $nameNode = new PPNode_HipHop_Tree( 'name' );
-                                                       $nameNode->addChild( new PPNode_HipHop_Attr( 'index', $argIndex++ ) );
-                                                       $valueNode = new PPNode_HipHop_Tree( 'value' );
-                                                       $valueNode->firstChild = $part->out->firstNode;
-                                                       $valueNode->lastChild = $part->out->lastNode;
-                                                       $partNode->addChild( $nameNode );
-                                                       $partNode->addChild( $valueNode );
-                                                       $tree->addChild( $partNode );
-                                               }
-                                       }
-                               }
-
-                               # Advance input pointer
-                               $i += $matchingCount;
-
-                               # Unwind the stack
-                               $stack->pop();
-                               $accum = $stack->getAccum();
-
-                               # Re-add the old stack element if it still has unmatched opening characters remaining
-                               if ($matchingCount < $piece->count) {
-                                       $piece->parts = array( new PPDPart_HipHop );
-                                       $piece->count -= $matchingCount;
-                                       # do we still qualify for any callback with remaining count?
-                                       $names = $rules[$piece->open]['names'];
-                                       $skippedBraces = 0;
-                                       $enclosingAccum = $accum;
-                                       while ( $piece->count ) {
-                                               if ( array_key_exists( $piece->count, $names ) ) {
-                                                       $stack->push( $piece );
-                                                       $accum = $stack->getAccum();
-                                                       break;
-                                               }
-                                               --$piece->count;
-                                               $skippedBraces ++;
-                                       }
-                                       $enclosingAccum->addLiteral( str_repeat( $piece->open, $skippedBraces ) );
-                               }
-
-                               $stackFlags = $stack->getFlags();
-
-                               # Add XML element to the enclosing accumulator
-                               if ( $isTreeNode ) {
-                                       $accum->addNode( $tree );
-                               } else {
-                                       $accum->addAccum( $resultAccum );
-                               }
-                       } elseif ( $found === 'pipe' ) {
-                               $stackFlags['findEquals'] = true; // shortcut for getFlags()
-                               $stack->addPart();
-                               $accum = $stack->getAccum();
-                               ++$i;
-                       } elseif ( $found === 'equals' ) {
-                               $stackFlags['findEquals'] = false; // shortcut for getFlags()
-                               $accum->addNodeWithText( 'equals', '=' );
-                               $stack->getCurrentPart()->eqpos = $accum->lastNode;
-                               ++$i;
-                       }
-               }
-
-               # Output any remaining unclosed brackets
-               foreach ( $stack->stack as $variantPiece ) {
-                       $piece = PPDStackElement_HipHop::cast( $variantPiece );
-                       $stack->rootAccum->addAccum( $piece->breakSyntax() );
-               }
-
-               # Enable top-level headings
-               for ( $node = $stack->rootAccum->firstNode; $node; $node = $node->nextSibling ) {
-                       if ( isset( $node->name ) && $node->name === 'possible-h' ) {
-                               $node->name = 'h';
-                       }
-               }
-
-               $rootNode = new PPNode_HipHop_Tree( 'root' );
-               $rootNode->firstChild = $stack->rootAccum->firstNode;
-               $rootNode->lastChild = $stack->rootAccum->lastNode;
-
-               // Cache
-               if ($cacheable) {
-                       $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . serialize( $rootNode );
-                       $wgMemc->set( $cacheKey, $cacheValue, 86400 );
-                       wfProfileOut( __METHOD__.'-cache-miss' );
-                       wfProfileOut( __METHOD__.'-cacheable' );
-                       wfDebugLog( "Preprocessor", "Saved preprocessor Hash to memcached (key $cacheKey)" );
-               }
-
-               wfProfileOut( __METHOD__ );
-               return $rootNode;
-       }
-}
-
-
-
-/**
- * Stack class to help Preprocessor::preprocessToObj()
- * @ingroup Parser
- */
-class PPDStack_HipHop {
-       var $stack, $rootAccum;
-
-       /**
-        * @var PPDStack
-        */
-       var $top;
-       var $out;
-
-       static $false = false;
-
-       function __construct() {
-               $this->stack = array();
-               $this->top = false;
-               $this->rootAccum = new PPDAccum_HipHop;
-               $this->accum = $this->rootAccum;
-       }
-
-       /**
-        * @return int
-        */
-       function count() {
-               return count( $this->stack );
-       }
-
-       function getAccum() {
-               return PPDAccum_HipHop::cast( $this->accum );
-       }
-
-       function getCurrentPart() {
-               return $this->getTop()->getCurrentPart();
-       }
-
-       function getTop() {
-               return PPDStackElement_HipHop::cast( $this->top );
-       }
-
-       function push( $data ) {
-               if ( $data instanceof PPDStackElement_HipHop ) {
-                       $this->stack[] = $data;
-               } else {
-                       $this->stack[] = new PPDStackElement_HipHop( $data );
-               }
-               $this->top = $this->stack[ count( $this->stack ) - 1 ];
-               $this->accum = $this->top->getAccum();
-       }
-
-       function pop() {
-               if ( !count( $this->stack ) ) {
-                       throw new MWException( __METHOD__.': no elements remaining' );
-               }
-               $temp = array_pop( $this->stack );
-
-               if ( count( $this->stack ) ) {
-                       $this->top = $this->stack[ count( $this->stack ) - 1 ];
-                       $this->accum = $this->top->getAccum();
-               } else {
-                       $this->top = self::$false;
-                       $this->accum = $this->rootAccum;
-               }
-               return $temp;
-       }
-
-       function addPart( $s = '' ) {
-               $this->top->addPart( $s );
-               $this->accum = $this->top->getAccum();
-       }
-
-       /**
-        * @return array
-        */
-       function getFlags() {
-               if ( !count( $this->stack ) ) {
-                       return array(
-                               'findEquals' => false,
-                               'findPipe' => false,
-                               'inHeading' => false,
-                       );
-               } else {
-                       return $this->top->getFlags();
-               }
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPDStackElement_HipHop {
-       var $open,              // Opening character (\n for heading)
-               $close,             // Matching closing character
-               $count,             // Number of opening characters found (number of "=" for heading)
-               $parts,             // Array of PPDPart objects describing pipe-separated parts.
-               $lineStart;         // True if the open char appeared at the start of the input line. Not set for headings.
-
-       /**
-        * @param $obj PPDStackElement_HipHop
-        * @return PPDStackElement_HipHop
-        */
-       static function cast( PPDStackElement_HipHop $obj ) {
-               return $obj;
-       }
-
-       /**
-        * @param $data array
-        */
-       function __construct( $data = array() ) {
-               $this->parts = array( new PPDPart_HipHop );
-
-               foreach ( $data as $name => $value ) {
-                       $this->$name = $value;
-               }
-       }
-
-       /**
-        * @return PPDAccum_HipHop
-        */
-       function getAccum() {
-               return PPDAccum_HipHop::cast( $this->parts[count($this->parts) - 1]->out );
-       }
-
-       /**
-        * @param $s string
-        */
-       function addPart( $s = '' ) {
-               $this->parts[] = new PPDPart_HipHop( $s );
-       }
-
-       /**
-        * @return PPDPart_HipHop
-        */
-       function getCurrentPart() {
-               return PPDPart_HipHop::cast( $this->parts[count($this->parts) - 1] );
-       }
-
-       /**
-        * @return array
-        */
-       function getFlags() {
-               $partCount = count( $this->parts );
-               $findPipe = $this->open !== "\n" && $this->open !== '[';
-               return array(
-                       'findPipe' => $findPipe,
-                       'findEquals' => $findPipe && $partCount > 1 && !isset( $this->parts[$partCount - 1]->eqpos ),
-                       'inHeading' => $this->open === "\n",
-               );
-       }
-
-       /**
-        * Get the accumulator that would result if the close is not found.
-        *
-        * @param $openingCount bool
-        * @return PPDAccum_HipHop
-        */
-       function breakSyntax( $openingCount = false ) {
-               if ( $this->open === "\n" ) {
-                       $accum = PPDAccum_HipHop::cast( $this->parts[0]->out );
-               } else {
-                       if ( $openingCount === false ) {
-                               $openingCount = $this->count;
-                       }
-                       $accum = new PPDAccum_HipHop;
-                       $accum->addLiteral( str_repeat( $this->open, $openingCount ) );
-                       $first = true;
-                       foreach ( $this->parts as $part ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $accum->addLiteral( '|' );
-                               }
-                               $accum->addAccum( $part->out );
-                       }
-               }
-               return $accum;
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPDPart_HipHop {
-       var $out; // Output accumulator object
-
-       // Optional member variables:
-       //   eqpos        Position of equals sign in output accumulator
-       //   commentEnd   Past-the-end input pointer for the last comment encountered
-       //   visualEnd    Past-the-end input pointer for the end of the accumulator minus comments
-
-       function __construct( $out = '' ) {
-               $this->out = new PPDAccum_HipHop;
-               if ( $out !== '' ) {
-                       $this->out->addLiteral( $out );
-               }
-       }
-
-       static function cast( PPDPart_HipHop $obj ) {
-               return $obj;
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPDAccum_HipHop {
-       var $firstNode, $lastNode;
-
-       function __construct() {
-               $this->firstNode = $this->lastNode = false;
-       }
-
-       static function cast( PPDAccum_HipHop $obj ) {
-               return $obj;
-       }
-
-       /**
-        * Append a string literal
-        */
-       function addLiteral( string $s ) {
-               if ( $this->lastNode === false ) {
-                       $this->firstNode = $this->lastNode = new PPNode_HipHop_Text( $s );
-               } elseif ( $this->lastNode instanceof PPNode_HipHop_Text ) {
-                       $this->lastNode->value .= $s;
-               } else {
-                       $this->lastNode->nextSibling = new PPNode_HipHop_Text( $s );
-                       $this->lastNode = $this->lastNode->nextSibling;
-               }
-       }
-
-       /**
-        * Append a PPNode
-        */
-       function addNode( PPNode $node ) {
-               if ( $this->lastNode === false ) {
-                       $this->firstNode = $this->lastNode = $node;
-               } else {
-                       $this->lastNode->nextSibling = $node;
-                       $this->lastNode = $node;
-               }
-       }
-
-       /**
-        * Append a tree node with text contents
-        */
-       function addNodeWithText( string $name, string $value ) {
-               $node = PPNode_HipHop_Tree::newWithText( $name, $value );
-               $this->addNode( $node );
-       }
-
-       /**
-        * Append a PPDAccum_HipHop
-        * Takes over ownership of the nodes in the source argument. These nodes may
-        * subsequently be modified, especially nextSibling.
-        */
-       function addAccum( PPDAccum_HipHop $accum ) {
-               if ( $accum->lastNode === false ) {
-                       // nothing to add
-               } elseif ( $this->lastNode === false ) {
-                       $this->firstNode = $accum->firstNode;
-                       $this->lastNode = $accum->lastNode;
-               } else {
-                       $this->lastNode->nextSibling = $accum->firstNode;
-                       $this->lastNode = $accum->lastNode;
-               }
-       }
-}
-
-/**
- * An expansion frame, used as a context to expand the result of preprocessToObj()
- * @ingroup Parser
- */
-class PPFrame_HipHop implements PPFrame {
-
-       /**
-        * @var Parser
-        */
-       var $parser;
-
-       /**
-        * @var Preprocessor
-        */
-       var $preprocessor;
-
-       /**
-        * @var Title
-        */
-       var $title;
-       var $titleCache;
-
-       /**
-        * Hashtable listing templates which are disallowed for expansion in this frame,
-        * having been encountered previously in parent frames.
-        */
-       var $loopCheckHash;
-
-       /**
-        * Recursion depth of this frame, top = 0
-        * Note that this is NOT the same as expansion depth in expand()
-        */
-       var $depth;
-
-       /**
-        * Construct a new preprocessor frame.
-        * @param $preprocessor Preprocessor: the parent preprocessor
-        */
-       function __construct( $preprocessor ) {
-               $this->preprocessor = $preprocessor;
-               $this->parser = $preprocessor->parser;
-               $this->title = $this->parser->mTitle;
-               $this->titleCache = array( $this->title ? $this->title->getPrefixedDBkey() : false );
-               $this->loopCheckHash = array();
-               $this->depth = 0;
-       }
-
-       /**
-        * Create a new child frame
-        * $args is optionally a multi-root PPNode or array containing the template arguments
-        *
-        * @param $args PPNode_HipHop_Array|array|bool
-        * @param $title Title|bool
-        * @param $indexOffset A number subtracted from the index attributes of the arguments
-        *
-        * @throws MWException
-        * @return PPTemplateFrame_HipHop
-        */
-       function newChild( $args = false, $title = false, $indexOffset = 0 ) {
-               $namedArgs = array();
-               $numberedArgs = array();
-               if ( $title === false ) {
-                       $title = $this->title;
-               }
-               if ( $args !== false ) {
-                       if ( $args instanceof PPNode_HipHop_Array ) {
-                               $args = $args->value;
-                       } elseif ( !is_array( $args ) ) {
-                               throw new MWException( __METHOD__ . ': $args must be array or PPNode_HipHop_Array' );
-                       }
-                       foreach ( $args as $arg ) {
-                               $bits = $arg->splitArg();
-                               if ( $bits['index'] !== '' ) {
-                                       // Numbered parameter
-                                       $numberedArgs[$bits['index']] = $bits['value'];
-                                       unset( $namedArgs[$bits['index']] );
-                               } else {
-                                       // Named parameter
-                                       $name = trim( $this->expand( $bits['name'], PPFrame::STRIP_COMMENTS ) );
-                                       $namedArgs[$name] = $bits['value'];
-                                       unset( $numberedArgs[$name] );
-                               }
-                       }
-               }
-               return new PPTemplateFrame_HipHop( $this->preprocessor, $this, $numberedArgs, $namedArgs, $title );
-       }
-
-       /**
-        * @throws MWException
-        * @param $root
-        * @param $flags int
-        * @return string
-        */
-       function expand( $root, $flags = 0 ) {
-               static $expansionDepth = 0;
-               if ( is_string( $root ) ) {
-                       return $root;
-               }
-
-               if ( ++$this->parser->mPPNodeCount > $this->parser->mOptions->getMaxPPNodeCount() ) {
-                       $this->parser->limitationWarn( 'node-count-exceeded',
-                                       $this->parser->mPPNodeCount,
-                                       $this->parser->mOptions->getMaxPPNodeCount()
-                       );
-                       return '<span class="error">Node-count limit exceeded</span>';
-               }
-               if ( $expansionDepth > $this->parser->mOptions->getMaxPPExpandDepth() ) {
-                       $this->parser->limitationWarn( 'expansion-depth-exceeded',
-                                       $expansionDepth,
-                                       $this->parser->mOptions->getMaxPPExpandDepth()
-                       );
-                       return '<span class="error">Expansion depth limit exceeded</span>';
-               }
-               ++$expansionDepth;
-               if ( $expansionDepth > $this->parser->mHighestExpansionDepth ) {
-                       $this->parser->mHighestExpansionDepth = $expansionDepth;
-               }
-
-               $outStack = array( '', '' );
-               $iteratorStack = array( false, $root );
-               $indexStack = array( 0, 0 );
-
-               while ( count( $iteratorStack ) > 1 ) {
-                       $level = count( $outStack ) - 1;
-                       $iteratorNode =& $iteratorStack[ $level ];
-                       $out =& $outStack[$level];
-                       $index =& $indexStack[$level];
-
-                       if ( is_array( $iteratorNode ) ) {
-                               if ( $index >= count( $iteratorNode ) ) {
-                                       // All done with this iterator
-                                       $iteratorStack[$level] = false;
-                                       $contextNode = false;
-                               } else {
-                                       $contextNode = $iteratorNode[$index];
-                                       $index++;
-                               }
-                       } elseif ( $iteratorNode instanceof PPNode_HipHop_Array ) {
-                               if ( $index >= $iteratorNode->getLength() ) {
-                                       // All done with this iterator
-                                       $iteratorStack[$level] = false;
-                                       $contextNode = false;
-                               } else {
-                                       $contextNode = $iteratorNode->item( $index );
-                                       $index++;
-                               }
-                       } else {
-                               // Copy to $contextNode and then delete from iterator stack,
-                               // because this is not an iterator but we do have to execute it once
-                               $contextNode = $iteratorStack[$level];
-                               $iteratorStack[$level] = false;
-                       }
-
-                       $newIterator = false;
-
-                       if ( $contextNode === false ) {
-                               // nothing to do
-                       } elseif ( is_string( $contextNode ) ) {
-                               $out .= $contextNode;
-                       } elseif ( is_array( $contextNode ) || $contextNode instanceof PPNode_HipHop_Array ) {
-                               $newIterator = $contextNode;
-                       } elseif ( $contextNode instanceof PPNode_HipHop_Attr ) {
-                               // No output
-                       } elseif ( $contextNode instanceof PPNode_HipHop_Text ) {
-                               $out .= $contextNode->value;
-                       } elseif ( $contextNode instanceof PPNode_HipHop_Tree ) {
-                               if ( $contextNode->name === 'template' ) {
-                                       # Double-brace expansion
-                                       $bits = $contextNode->splitTemplate();
-                                       if ( $flags & PPFrame::NO_TEMPLATES ) {
-                                               $newIterator = $this->virtualBracketedImplode( '{{', '|', '}}', $bits['title'], $bits['parts'] );
-                                       } else {
-                                               $ret = $this->parser->braceSubstitution( $bits, $this );
-                                               if ( isset( $ret['object'] ) ) {
-                                                       $newIterator = $ret['object'];
-                                               } else {
-                                                       $out .= $ret['text'];
-                                               }
-                                       }
-                               } elseif ( $contextNode->name === 'tplarg' ) {
-                                       # Triple-brace expansion
-                                       $bits = $contextNode->splitTemplate();
-                                       if ( $flags & PPFrame::NO_ARGS ) {
-                                               $newIterator = $this->virtualBracketedImplode( '{{{', '|', '}}}', $bits['title'], $bits['parts'] );
-                                       } else {
-                                               $ret = $this->parser->argSubstitution( $bits, $this );
-                                               if ( isset( $ret['object'] ) ) {
-                                                       $newIterator = $ret['object'];
-                                               } else {
-                                                       $out .= $ret['text'];
-                                               }
-                                       }
-                               } elseif ( $contextNode->name === 'comment' ) {
-                                       # HTML-style comment
-                                       # Remove it in HTML, pre+remove and STRIP_COMMENTS modes
-                                       if ( $this->parser->ot['html']
-                                               || ( $this->parser->ot['pre'] && $this->parser->mOptions->getRemoveComments() )
-                                               || ( $flags & PPFrame::STRIP_COMMENTS ) )
-                                       {
-                                               $out .= '';
-                                       }
-                                       # Add a strip marker in PST mode so that pstPass2() can run some old-fashioned regexes on the result
-                                       # Not in RECOVER_COMMENTS mode (extractSections) though
-                                       elseif ( $this->parser->ot['wiki'] && ! ( $flags & PPFrame::RECOVER_COMMENTS ) ) {
-                                               $out .= $this->parser->insertStripItem( $contextNode->firstChild->value );
-                                       }
-                                       # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
-                                       else {
-                                               $out .= $contextNode->firstChild->value;
-                                       }
-                               } elseif ( $contextNode->name === 'ignore' ) {
-                                       # Output suppression used by <includeonly> etc.
-                                       # OT_WIKI will only respect <ignore> in substed templates.
-                                       # The other output types respect it unless NO_IGNORE is set.
-                                       # extractSections() sets NO_IGNORE and so never respects it.
-                                       if ( ( !isset( $this->parent ) && $this->parser->ot['wiki'] ) || ( $flags & PPFrame::NO_IGNORE ) ) {
-                                               $out .= $contextNode->firstChild->value;
-                                       } else {
-                                               //$out .= '';
-                                       }
-                               } elseif ( $contextNode->name === 'ext' ) {
-                                       # Extension tag
-                                       $bits = $contextNode->splitExt() + array( 'attr' => null, 'inner' => null, 'close' => null );
-                                       $out .= $this->parser->extensionSubstitution( $bits, $this );
-                               } elseif ( $contextNode->name === 'h' ) {
-                                       # Heading
-                                       if ( $this->parser->ot['html'] ) {
-                                               # Expand immediately and insert heading index marker
-                                               $s = '';
-                                               for ( $node = $contextNode->firstChild; $node; $node = $node->nextSibling ) {
-                                                       $s .= $this->expand( $node, $flags );
-                                               }
-
-                                               $bits = $contextNode->splitHeading();
-                                               $titleText = $this->title->getPrefixedDBkey();
-                                               $this->parser->mHeadings[] = array( $titleText, $bits['i'] );
-                                               $serial = count( $this->parser->mHeadings ) - 1;
-                                               $marker = "{$this->parser->mUniqPrefix}-h-$serial-" . Parser::MARKER_SUFFIX;
-                                               $s = substr( $s, 0, $bits['level'] ) . $marker . substr( $s, $bits['level'] );
-                                               $this->parser->mStripState->addGeneral( $marker, '' );
-                                               $out .= $s;
-                                       } else {
-                                               # Expand in virtual stack
-                                               $newIterator = $contextNode->getChildren();
-                                       }
-                               } else {
-                                       # Generic recursive expansion
-                                       $newIterator = $contextNode->getChildren();
-                               }
-                       } else {
-                               throw new MWException( __METHOD__.': Invalid parameter type' );
-                       }
-
-                       if ( $newIterator !== false ) {
-                               $outStack[] = '';
-                               $iteratorStack[] = $newIterator;
-                               $indexStack[] = 0;
-                       } elseif ( $iteratorStack[$level] === false ) {
-                               // Return accumulated value to parent
-                               // With tail recursion
-                               while ( $iteratorStack[$level] === false && $level > 0 ) {
-                                       $outStack[$level - 1] .= $out;
-                                       array_pop( $outStack );
-                                       array_pop( $iteratorStack );
-                                       array_pop( $indexStack );
-                                       $level--;
-                               }
-                       }
-               }
-               --$expansionDepth;
-               return $outStack[0];
-       }
-
-       /**
-        * @param $sep
-        * @param $flags
-        * @return string
-        */
-       function implodeWithFlags( $sep, $flags /*, ... */ ) {
-               $args = array_slice( func_get_args(), 2 );
-
-               $first = true;
-               $s = '';
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $s .= $sep;
-                               }
-                               $s .= $this->expand( $node, $flags );
-                       }
-               }
-               return $s;
-       }
-
-       /**
-        * Implode with no flags specified
-        * This previously called implodeWithFlags but has now been inlined to reduce stack depth
-        * @param $sep
-        * @return string
-        */
-       function implode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
-
-               $first = true;
-               $s = '';
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $s .= $sep;
-                               }
-                               $s .= $this->expand( $node );
-                       }
-               }
-               return $s;
-       }
-
-       /**
-        * Makes an object that, when expand()ed, will be the same as one obtained
-        * with implode()
-        *
-        * @param $sep
-        * @return PPNode_HipHop_Array
-        */
-       function virtualImplode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
-               $out = array();
-               $first = true;
-
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $out[] = $sep;
-                               }
-                               $out[] = $node;
-                       }
-               }
-               return new PPNode_HipHop_Array( $out );
-       }
-
-       /**
-        * Virtual implode with brackets
-        *
-        * @param $start
-        * @param $sep
-        * @param $end
-        * @return PPNode_HipHop_Array
-        */
-       function virtualBracketedImplode( $start, $sep, $end /*, ... */ ) {
-               $args = array_slice( func_get_args(), 3 );
-               $out = array( $start );
-               $first = true;
-
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $out[] = $sep;
-                               }
-                               $out[] = $node;
-                       }
-               }
-               $out[] = $end;
-               return new PPNode_HipHop_Array( $out );
-       }
-
-       function __toString() {
-               return 'frame{}';
-       }
-
-       /**
-        * @param $level bool
-        * @return array|bool|String
-        */
-       function getPDBK( $level = false ) {
-               if ( $level === false ) {
-                       return $this->title->getPrefixedDBkey();
-               } else {
-                       return isset( $this->titleCache[$level] ) ? $this->titleCache[$level] : false;
-               }
-       }
-
-       /**
-        * @return array
-        */
-       function getArguments() {
-               return array();
-       }
-
-       /**
-        * @return array
-        */
-       function getNumberedArguments() {
-               return array();
-       }
-
-       /**
-        * @return array
-        */
-       function getNamedArguments() {
-               return array();
-       }
-
-       /**
-        * Returns true if there are no arguments in this frame
-        *
-        * @return bool
-        */
-       function isEmpty() {
-               return true;
-       }
-
-       /**
-        * @param $name
-        * @return bool
-        */
-       function getArgument( $name ) {
-               return false;
-       }
-
-       /**
-        * Returns true if the infinite loop check is OK, false if a loop is detected
-        *
-        * @param $title Title
-        *
-        * @return bool
-        */
-       function loopCheck( $title ) {
-               return !isset( $this->loopCheckHash[$title->getPrefixedDBkey()] );
-       }
-
-       /**
-        * Return true if the frame is a template frame
-        *
-        * @return bool
-        */
-       function isTemplate() {
-               return false;
-       }
-
-       /**
-        * Get a title of frame
-        *
-        * @return Title
-        */
-       function getTitle() {
-               return $this->title;
-       }
-}
-
-/**
- * Expansion frame with template arguments
- * @ingroup Parser
- */
-class PPTemplateFrame_HipHop extends PPFrame_HipHop {
-       var $numberedArgs, $namedArgs, $parent;
-       var $numberedExpansionCache, $namedExpansionCache;
-
-       /**
-        * @param $preprocessor Preprocessor_HipHop
-        * @param $parent bool
-        * @param $numberedArgs array
-        * @param $namedArgs array
-        * @param $title Title|bool
-        */
-       function __construct( $preprocessor, $parent = false, $numberedArgs = array(), $namedArgs = array(), $title = false ) {
-               parent::__construct( $preprocessor );
-
-               $this->parent = $parent;
-               $this->numberedArgs = $numberedArgs;
-               $this->namedArgs = $namedArgs;
-               $this->title = $title;
-               $pdbk = $title ? $title->getPrefixedDBkey() : false;
-               $this->titleCache = $parent->titleCache;
-               $this->titleCache[] = $pdbk;
-               $this->loopCheckHash = /*clone*/ $parent->loopCheckHash;
-               if ( $pdbk !== false ) {
-                       $this->loopCheckHash[$pdbk] = true;
-               }
-               $this->depth = $parent->depth + 1;
-               $this->numberedExpansionCache = $this->namedExpansionCache = array();
-       }
-
-       function __toString() {
-               $s = 'tplframe{';
-               $first = true;
-               $args = $this->numberedArgs + $this->namedArgs;
-               foreach ( $args as $name => $value ) {
-                       if ( $first ) {
-                               $first = false;
-                       } else {
-                               $s .= ', ';
-                       }
-                       $s .= "\"$name\":\"" .
-                               str_replace( '"', '\\"', $value->__toString() ) . '"';
-               }
-               $s .= '}';
-               return $s;
-       }
-       /**
-        * Returns true if there are no arguments in this frame
-        *
-        * @return bool
-        */
-       function isEmpty() {
-               return !count( $this->numberedArgs ) && !count( $this->namedArgs );
-       }
-
-       /**
-        * @return array
-        */
-       function getArguments() {
-               $arguments = array();
-               foreach ( array_merge(
-                               array_keys($this->numberedArgs),
-                               array_keys($this->namedArgs)) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
-               }
-               return $arguments;
-       }
-
-       /**
-        * @return array
-        */
-       function getNumberedArguments() {
-               $arguments = array();
-               foreach ( array_keys($this->numberedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
-               }
-               return $arguments;
-       }
-
-       /**
-        * @return array
-        */
-       function getNamedArguments() {
-               $arguments = array();
-               foreach ( array_keys($this->namedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
-               }
-               return $arguments;
-       }
-
-       /**
-        * @param $index
-        * @return array|bool
-        */
-       function getNumberedArgument( $index ) {
-               if ( !isset( $this->numberedArgs[$index] ) ) {
-                       return false;
-               }
-               if ( !isset( $this->numberedExpansionCache[$index] ) ) {
-                       # No trimming for unnamed arguments
-                       $this->numberedExpansionCache[$index] = $this->parent->expand( $this->numberedArgs[$index], PPFrame::STRIP_COMMENTS );
-               }
-               return $this->numberedExpansionCache[$index];
-       }
-
-       /**
-        * @param $name
-        * @return bool
-        */
-       function getNamedArgument( $name ) {
-               if ( !isset( $this->namedArgs[$name] ) ) {
-                       return false;
-               }
-               if ( !isset( $this->namedExpansionCache[$name] ) ) {
-                       # Trim named arguments post-expand, for backwards compatibility
-                       $this->namedExpansionCache[$name] = trim(
-                               $this->parent->expand( $this->namedArgs[$name], PPFrame::STRIP_COMMENTS ) );
-               }
-               return $this->namedExpansionCache[$name];
-       }
-
-       /**
-        * @param $name
-        * @return array|bool
-        */
-       function getArgument( $name ) {
-               $text = $this->getNumberedArgument( $name );
-               if ( $text === false ) {
-                       $text = $this->getNamedArgument( $name );
-               }
-               return $text;
-       }
-
-       /**
-        * Return true if the frame is a template frame
-        *
-        * @return bool
-        */
-       function isTemplate() {
-               return true;
-       }
-}
-
-/**
- * Expansion frame with custom arguments
- * @ingroup Parser
- */
-class PPCustomFrame_HipHop extends PPFrame_HipHop {
-       var $args;
-
-       function __construct( $preprocessor, $args ) {
-               parent::__construct( $preprocessor );
-               $this->args = $args;
-       }
-
-       function __toString() {
-               $s = 'cstmframe{';
-               $first = true;
-               foreach ( $this->args as $name => $value ) {
-                       if ( $first ) {
-                               $first = false;
-                       } else {
-                               $s .= ', ';
-                       }
-                       $s .= "\"$name\":\"" .
-                               str_replace( '"', '\\"', $value->__toString() ) . '"';
-               }
-               $s .= '}';
-               return $s;
-       }
-
-       /**
-        * @return bool
-        */
-       function isEmpty() {
-               return !count( $this->args );
-       }
-
-       /**
-        * @param $index
-        * @return bool
-        */
-       function getArgument( $index ) {
-               if ( !isset( $this->args[$index] ) ) {
-                       return false;
-               }
-               return $this->args[$index];
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Tree implements PPNode {
-       var $name, $firstChild, $lastChild, $nextSibling;
-
-       function __construct( $name ) {
-               $this->name = $name;
-               $this->firstChild = $this->lastChild = $this->nextSibling = false;
-       }
-
-       function __toString() {
-               $inner = '';
-               $attribs = '';
-               for ( $node = $this->firstChild; $node; $node = $node->nextSibling ) {
-                       if ( $node instanceof PPNode_HipHop_Attr ) {
-                               $attribs .= ' ' . $node->name . '="' . htmlspecialchars( $node->value ) . '"';
-                       } else {
-                               $inner .= $node->__toString();
-                       }
-               }
-               if ( $inner === '' ) {
-                       return "<{$this->name}$attribs/>";
-               } else {
-                       return "<{$this->name}$attribs>$inner</{$this->name}>";
-               }
-       }
-
-       /**
-        * @param $name
-        * @param $text
-        * @return PPNode_HipHop_Tree
-        */
-       static function newWithText( $name, $text ) {
-               $obj = new self( $name );
-               $obj->addChild( new PPNode_HipHop_Text( $text ) );
-               return $obj;
-       }
-
-       function addChild( $node ) {
-               if ( $this->lastChild === false ) {
-                       $this->firstChild = $this->lastChild = $node;
-               } else {
-                       $this->lastChild->nextSibling = $node;
-                       $this->lastChild = $node;
-               }
-       }
-
-       /**
-        * @return PPNode_HipHop_Array
-        */
-       function getChildren() {
-               $children = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       $children[] = $child;
-               }
-               return new PPNode_HipHop_Array( $children );
-       }
-
-       function getFirstChild() {
-               return $this->firstChild;
-       }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       /**
-        * @param $name string
-        * @return array
-        */
-       function getChildrenOfType( $name ) {
-               $children = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( isset( $child->name ) && $child->name === $name ) {
-                               $children[] = $child;
-                       }
-               }
-               return $children;
-       }
-
-       /**
-        * @return bool
-        */
-       function getLength() {
-               return false;
-       }
-
-       /**
-        * @param  $i
-        * @return bool
-        */
-       function item( $i ) {
-               return false;
-       }
-
-       /**
-        * @return string
-        */
-       function getName() {
-               return $this->name;
-       }
-
-       /**
-        * Split a <part> node into an associative array containing:
-        *    name          PPNode name
-        *    index         String index
-        *    value         PPNode value
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitArg() {
-               $bits = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'name' ) {
-                               $bits['name'] = $child;
-                               if ( $child->firstChild instanceof PPNode_HipHop_Attr
-                                       && $child->firstChild->name === 'index' )
-                               {
-                                       $bits['index'] = $child->firstChild->value;
-                               }
-                       } elseif ( $child->name === 'value' ) {
-                               $bits['value'] = $child;
-                       }
-               }
-
-               if ( !isset( $bits['name'] ) ) {
-                       throw new MWException( 'Invalid brace node passed to ' . __METHOD__ );
-               }
-               if ( !isset( $bits['index'] ) ) {
-                       $bits['index'] = '';
-               }
-               return $bits;
-       }
-
-       /**
-        * Split an <ext> node into an associative array containing name, attr, inner and close
-        * All values in the resulting array are PPNodes. Inner and close are optional.
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitExt() {
-               $bits = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'name' ) {
-                               $bits['name'] = $child;
-                       } elseif ( $child->name === 'attr' ) {
-                               $bits['attr'] = $child;
-                       } elseif ( $child->name === 'inner' ) {
-                               $bits['inner'] = $child;
-                       } elseif ( $child->name === 'close' ) {
-                               $bits['close'] = $child;
-                       }
-               }
-               if ( !isset( $bits['name'] ) ) {
-                       throw new MWException( 'Invalid ext node passed to ' . __METHOD__ );
-               }
-               return $bits;
-       }
-
-       /**
-        * Split an <h> node
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitHeading() {
-               if ( $this->name !== 'h' ) {
-                       throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
-               }
-               $bits = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'i' ) {
-                               $bits['i'] = $child->value;
-                       } elseif ( $child->name === 'level' ) {
-                               $bits['level'] = $child->value;
-                       }
-               }
-               if ( !isset( $bits['i'] ) ) {
-                       throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
-               }
-               return $bits;
-       }
-
-       /**
-        * Split a <template> or <tplarg> node
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitTemplate() {
-               $parts = array();
-               $bits = array( 'lineStart' => '' );
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'title' ) {
-                               $bits['title'] = $child;
-                       }
-                       if ( $child->name === 'part' ) {
-                               $parts[] = $child;
-                       }
-                       if ( $child->name === 'lineStart' ) {
-                               $bits['lineStart'] = '1';
-                       }
-               }
-               if ( !isset( $bits['title'] ) ) {
-                       throw new MWException( 'Invalid node passed to ' . __METHOD__ );
-               }
-               $bits['parts'] = new PPNode_HipHop_Array( $parts );
-               return $bits;
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Text implements PPNode {
-       var $value, $nextSibling;
-
-       function __construct( $value ) {
-               if ( is_object( $value ) ) {
-                       throw new MWException( __CLASS__ . ' given object instead of string' );
-               }
-               $this->value = $value;
-       }
-
-       function __toString() {
-               return htmlspecialchars( $this->value );
-       }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       function getChildren() { return false; }
-       function getFirstChild() { return false; }
-       function getChildrenOfType( $name ) { return false; }
-       function getLength() { return false; }
-       function item( $i ) { return false; }
-       function getName() { return '#text'; }
-       function splitArg() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitExt() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitHeading() { throw new MWException( __METHOD__ . ': not supported' ); }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Array implements PPNode {
-       var $value, $nextSibling;
-
-       function __construct( $value ) {
-               $this->value = $value;
-       }
-
-       function __toString() {
-               return var_export( $this, true );
-       }
-
-       function getLength() {
-               return count( $this->value );
-       }
-
-       function item( $i ) {
-               return $this->value[$i];
-       }
-
-       function getName() { return '#nodelist'; }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       function getChildren() { return false; }
-       function getFirstChild() { return false; }
-       function getChildrenOfType( $name ) { return false; }
-       function splitArg() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitExt() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitHeading() { throw new MWException( __METHOD__ . ': not supported' ); }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Attr implements PPNode {
-       var $name, $value, $nextSibling;
-
-       function __construct( $name, $value ) {
-               $this->name = $name;
-               $this->value = $value;
-       }
-
-       function __toString() {
-               return "<@{$this->name}>" . htmlspecialchars( $this->value ) . "</@{$this->name}>";
-       }
-
-       function getName() {
-               return $this->name;
-       }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       function getChildren() { return false; }
-       function getFirstChild() { return false; }
-       function getChildrenOfType( $name ) { return false; }
-       function getLength() { return false; }
-       function item( $i ) { return false; }
-       function splitArg() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitExt() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitHeading() { throw new MWException( __METHOD__ . ': not supported' ); }
-}
index 57f623d..5f3f18e 100644 (file)
@@ -233,4 +233,3 @@ class StripState {
                return preg_replace( $this->regex, '', $text );
        }
 }
-
index dd7e965..4994d3e 100644 (file)
@@ -68,9 +68,9 @@ class MWTidyWrapper {
                $wrappedtext = preg_replace( '!<(link|meta)([^>]*?)(/{0,1}>)!', '<html-$1$2$3', $wrappedtext );
 
                // Wrap the whole thing in a doctype and body for Tidy.
-               $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.
-                       ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>'.
-                       '<head><title>test</title></head><body>'.$wrappedtext.'</body></html>';
+               $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' .
+                       ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>' .
+                       '<head><title>test</title></head><body>' . $wrappedtext . '</body></html>';
 
                return $wrappedtext;
        }
index baffcd8..1ead836 100644 (file)
@@ -157,7 +157,7 @@ class Profiler {
         */
        public function profileIn( $functionname ) {
                global $wgDebugFunctionEntry;
-               if( $wgDebugFunctionEntry ){
+               if( $wgDebugFunctionEntry ) {
                        $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" );
                }
 
@@ -174,22 +174,22 @@ class Profiler {
                $memory = memory_get_usage();
                $time = $this->getTime();
 
-               if( $wgDebugFunctionEntry ){
+               if( $wgDebugFunctionEntry ) {
                        $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
                }
 
-               $bit = array_pop($this->mWorkStack);
+               $bit = array_pop( $this->mWorkStack );
 
-               if (!$bit) {
-                       $this->debug("Profiling error, !\$bit: $functionname\n");
+               if ( !$bit ) {
+                       $this->debug( "Profiling error, !\$bit: $functionname\n" );
                } else {
-                       //if( $wgDebugProfiling ){
-                               if( $functionname == 'close' ){
+                       //if( $wgDebugProfiling ) {
+                               if( $functionname == 'close' ) {
                                        $message = "Profile section ended by close(): {$bit[0]}";
                                        $this->debug( "$message\n" );
                                        $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 );
                                }
-                               elseif( $bit[0] != $functionname ){
+                               elseif( $bit[0] != $functionname ) {
                                        $message = "Profiling error: in({$bit[0]}), out($functionname)";
                                        $this->debug( "$message\n" );
                                        $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 );
@@ -205,7 +205,7 @@ class Profiler {
         * Close opened profiling sections
         */
        public function close() {
-               while( count( $this->mWorkStack ) ){
+               while( count( $this->mWorkStack ) ) {
                        $this->profileOut( 'close' );
                }
        }
@@ -228,7 +228,7 @@ class Profiler {
                global $wgDebugFunctionEntry, $wgProfileCallTree;
                $wgDebugFunctionEntry = false;
 
-               if( !count( $this->mStack ) && !count( $this->mCollated ) ){
+               if( !count( $this->mStack ) && !count( $this->mCollated ) ) {
                        return "No profiling output\n";
                }
 
@@ -254,16 +254,16 @@ class Profiler {
         * @return array
         */
        function remapCallTree( $stack ) {
-               if( count( $stack ) < 2 ){
+               if( count( $stack ) < 2 ) {
                        return $stack;
                }
                $outputs = array ();
-               for( $max = count( $stack ) - 1; $max > 0; ){
+               for( $max = count( $stack ) - 1; $max > 0; ) {
                        /* Find all items under this entry */
                        $level = $stack[$max][1];
                        $working = array ();
-                       for( $i = $max -1; $i >= 0; $i-- ){
-                               if( $stack[$i][1] > $level ){
+                       for( $i = $max -1; $i >= 0; $i-- ) {
+                               if( $stack[$i][1] > $level ) {
                                        $working[] = $stack[$i];
                                } else {
                                        break;
@@ -271,7 +271,7 @@ class Profiler {
                        }
                        $working = $this->remapCallTree( array_reverse( $working ) );
                        $output = array();
-                       foreach( $working as $item ){
+                       foreach( $working as $item ) {
                                array_push( $output, $item );
                        }
                        array_unshift( $output, $stack[$max] );
@@ -280,8 +280,8 @@ class Profiler {
                        array_unshift( $outputs, $output );
                }
                $final = array();
-               foreach( $outputs as $output ){
-                       foreach( $output as $item ){
+               foreach( $outputs as $output ) {
+                       foreach( $output as $item ) {
                                $final[] = $item;
                        }
                }
@@ -293,9 +293,9 @@ class Profiler {
         * @return string
         */
        function getCallTreeLine( $entry ) {
-               list( $fname, $level, $start, /* $x */, $end = $entry;
+               list( $fname, $level, $start, /* $x */, $end ) = $entry;
                $delta = $end - $start;
-               $space = str_repeat(' ', $level);
+               $space = str_repeat( ' ', $level );
                # The ugly double sprintf is to work around a PHP bug,
                # which has been fixed in recent releases.
                return sprintf( "%10s %s %s\n", trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname );
@@ -386,23 +386,23 @@ class Profiler {
                $this->mMemory = array();
 
                # Estimate profiling overhead
-               $profileCount = count($this->mStack);
+               $profileCount = count( $this->mStack );
                self::calculateOverhead( $profileCount );
 
                # First, subtract the overhead!
                $overheadTotal = $overheadMemory = $overheadInternal = array();
-               foreach( $this->mStack as $entry ){
+               foreach( $this->mStack as $entry ) {
                        $fname = $entry[0];
                        $start = $entry[2];
                        $end = $entry[4];
                        $elapsed = $end - $start;
                        $memory = $entry[5] - $entry[3];
 
-                       if( $fname == '-overhead-total' ){
+                       if( $fname == '-overhead-total' ) {
                                $overheadTotal[] = $elapsed;
                                $overheadMemory[] = $memory;
                        }
-                       elseif( $fname == '-overhead-internal' ){
+                       elseif( $fname == '-overhead-internal' ) {
                                $overheadInternal[] = $elapsed;
                        }
                }
@@ -411,7 +411,7 @@ class Profiler {
                $overheadInternal = $overheadInternal ? array_sum( $overheadInternal ) / count( $overheadInternal ) : 0;
 
                # Collate
-               foreach( $this->mStack as $index => $entry ){
+               foreach( $this->mStack as $index => $entry ) {
                        $fname = $entry[0];
                        $start = $entry[2];
                        $end = $entry[4];
@@ -420,7 +420,7 @@ class Profiler {
                        $memory = $entry[5] - $entry[3];
                        $subcalls = $this->calltreeCount( $this->mStack, $index );
 
-                       if( !preg_match( '/^-overhead/', $fname ) ){
+                       if( !preg_match( '/^-overhead/', $fname ) ) {
                                # Adjust for profiling overhead (except special values with elapsed=0
                                if( $elapsed ) {
                                        $elapsed -= $overheadInternal;
@@ -429,7 +429,7 @@ class Profiler {
                                }
                        }
 
-                       if( !array_key_exists( $fname, $this->mCollated ) ){
+                       if( !array_key_exists( $fname, $this->mCollated ) ) {
                                $this->mCollated[$fname] = 0;
                                $this->mCalls[$fname] = 0;
                                $this->mMemory[$fname] = 0;
@@ -441,8 +441,8 @@ class Profiler {
                        $this->mCollated[$fname] += $elapsed;
                        $this->mCalls[$fname]++;
                        $this->mMemory[$fname] += $memory;
-                       $this->mMin[$fname] = min($this->mMin[$fname], $elapsed);
-                       $this->mMax[$fname] = max($this->mMax[$fname], $elapsed);
+                       $this->mMin[$fname] = min( $this->mMin[$fname], $elapsed );
+                       $this->mMax[$fname] = max( $this->mMax[$fname], $elapsed );
                        $this->mOverhead[$fname] += $subcalls;
                }
 
@@ -467,11 +467,11 @@ class Profiler {
 
                $total = isset( $this->mCollated['-total'] ) ? $this->mCollated['-total'] : 0;
 
-               foreach( $this->mCollated as $fname => $elapsed ){
+               foreach( $this->mCollated as $fname => $elapsed ) {
                        $calls = $this->mCalls[$fname];
                        $percent = $total ? 100. * $elapsed / $total : 0;
                        $memory = $this->mMemory[$fname];
-                       $prof .= sprintf($format, substr($fname, 0, $nameWidth), $calls, (float) ($elapsed * 1000), (float) ($elapsed * 1000) / $calls, $percent, $memory, ($this->mMin[$fname] * 1000.0), ($this->mMax[$fname] * 1000.0), $this->mOverhead[$fname]);
+                       $prof .= sprintf( $format, substr( $fname, 0, $nameWidth ), $calls, (float) ($elapsed * 1000), (float) ($elapsed * 1000) / $calls, $percent, $memory, ( $this->mMin[$fname] * 1000.0 ), ( $this->mMax[$fname] * 1000.0 ), $this->mOverhead[$fname] );
                }
                $prof .= "\nTotal: $total\n\n";
 
@@ -483,7 +483,7 @@ class Profiler {
         */
        protected static function calculateOverhead( $profileCount ) {
                wfProfileIn( '-overhead-total' );
-               for( $i = 0; $i < $profileCount; $i++ ){
+               for( $i = 0; $i < $profileCount; $i++ ) {
                        wfProfileIn( '-overhead-internal' );
                        wfProfileOut( '-overhead-internal' );
                }
@@ -499,10 +499,10 @@ class Profiler {
         * @return Integer
         * @private
         */
-       function calltreeCount($stack, $start) {
+       function calltreeCount( $stack, $start ) {
                $level = $stack[$start][1];
                $count = 0;
-               for ($i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i --) {
+               for ( $i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i-- ) {
                        $count ++;
                }
                return $count;
@@ -524,7 +524,7 @@ class Profiler {
                        return;
                }
 
-               if( $wgProfilePerHost ){
+               if( $wgProfilePerHost ) {
                        $pfhost = wfHostname();
                } else {
                        $pfhost = '';
@@ -533,7 +533,7 @@ class Profiler {
                try {
                        $this->collateData();
 
-                       foreach( $this->mCollated as $name => $elapsed ){
+                       foreach( $this->mCollated as $name => $elapsed ) {
                                $eventCount = $this->mCalls[$name];
                                $timeSum = (float) ($elapsed * 1000);
                                $memorySum = (float)$this->mMemory[$name];
@@ -557,9 +557,9 @@ class Profiler {
 
                                $rc = $dbw->affectedRows();
                                if ( $rc == 0 ) {
-                                       $dbw->insert('profiling', array ('pf_name' => $name, 'pf_count' => $eventCount,
+                                       $dbw->insert( 'profiling', array ( 'pf_name' => $name, 'pf_count' => $eventCount,
                                                'pf_time' => $timeSum, 'pf_memory' => $memorySum, 'pf_server' => $pfhost ),
-                                               __METHOD__, array ('IGNORE'));
+                                               __METHOD__, array ( 'IGNORE' ) );
                                }
                                // When we upgrade to mysql 4.1, the insert+update
                                // can be merged into just a insert with this construct added:
index d1d1c5d..1322e47 100644 (file)
@@ -29,7 +29,7 @@
 class ProfilerSimple extends Profiler {
        var $mMinimumTime = 0;
 
-       var $zeroEntry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0);
+       var $zeroEntry = array( 'cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0 );
        var $errorEntry;
 
        public function isPersistent() {
@@ -57,33 +57,33 @@ class ProfilerSimple extends Profiler {
                $this->mMinimumTime = $min;
        }
 
-       function profileIn($functionname) {
+       function profileIn( $functionname ) {
                global $wgDebugFunctionEntry;
-               if ($wgDebugFunctionEntry) {
-                       $this->debug(str_repeat(' ', count($this->mWorkStack)).'Entering '.$functionname."\n");
+               if ( $wgDebugFunctionEntry ) {
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" );
                }
                $this->mWorkStack[] = array( $functionname, count( $this->mWorkStack ), $this->getTime(), $this->getTime( 'cpu' ) );
        }
 
-       function profileOut($functionname) {
+       function profileOut( $functionname ) {
                global $wgDebugFunctionEntry;
 
-               if ($wgDebugFunctionEntry) {
-                       $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n");
+               if ( $wgDebugFunctionEntry ) {
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
                }
 
-               list($ofname, /* $ocount */ ,$ortime,$octime) = array_pop($this->mWorkStack);
+               list( $ofname, /* $ocount */, $ortime, $octime ) = array_pop( $this->mWorkStack );
 
-               if (!$ofname) {
-                       $this->debug("Profiling error: $functionname\n");
+               if ( !$ofname ) {
+                       $this->debug( "Profiling error: $functionname\n" );
                } else {
-                       if ($functionname == 'close') {
+                       if ( $functionname == 'close' ) {
                                $message = "Profile section ended by close(): {$ofname}";
                                $functionname = $ofname;
                                $this->debug( "$message\n" );
                                $this->mCollated[$message] = $this->errorEntry;
                        }
-                       elseif ($ofname != $functionname) {
+                       elseif ( $ofname != $functionname ) {
                                $message = "Profiling error: in({$ofname}), out($functionname)";
                                $this->debug( "$message\n" );
                                $this->mCollated[$message] = $this->errorEntry;
@@ -91,7 +91,7 @@ class ProfilerSimple extends Profiler {
                        $entry =& $this->mCollated[$functionname];
                        $elapsedcpu = $this->getTime( 'cpu' ) - $octime;
                        $elapsedreal = $this->getTime() - $ortime;
-                       if (!is_array($entry)) {
+                       if ( !is_array( $entry ) ) {
                                $entry = $this->zeroEntry;
                                $this->mCollated[$functionname] =& $entry;
                        }
index e62622f..37350bf 100644 (file)
@@ -48,9 +48,9 @@ class ProfilerSimpleText extends ProfilerSimple {
                        $totalReal = isset( $this->mCollated['-total'] )
                                ? $this->mCollated['-total']['real']
                                : 0; // profiling mismatch error?
-                       uasort( $this->mCollated, array('self','sort') );
-                       array_walk( $this->mCollated, array('self','format'), $totalReal );
-                       if ( php_sapi_name() === 'cli' ) {
+                       uasort( $this->mCollated, array( 'self', 'sort' ) );
+                       array_walk( $this->mCollated, array( 'self', 'format' ), $totalReal );
+                       if ( PHP_SAPI === 'cli' ) {
                                print "<!--\n".self::$out."\n-->\n";
                        } elseif ( $this->getContentType() === 'text/html' ) {
                                if ( $this->visible ) {
index 017e135..d44dfe1 100644 (file)
@@ -32,18 +32,18 @@ class ProfilerSimpleTrace extends ProfilerSimple {
 
        function profileIn( $functionname ) {
                parent::profileIn( $functionname );
-               $this->trace .= "         " . sprintf("%6.1f",$this->memoryDiff()) .
-                               str_repeat( " ", count($this->mWorkStack)) . " > " . $functionname . "\n";
+               $this->trace .= "         " . sprintf( "%6.1f", $this->memoryDiff() ) .
+                               str_repeat( " ", count( $this->mWorkStack ) ) . " > " . $functionname . "\n";
        }
 
-       function profileOut($functionname) {
+       function profileOut( $functionname ) {
                global $wgDebugFunctionEntry;
 
                if ( $wgDebugFunctionEntry ) {
-                       $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n");
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
                }
 
-               list( $ofname, /* $ocount */ , $ortime ) = array_pop( $this->mWorkStack );
+               list( $ofname, /* $ocount */, $ortime ) = array_pop( $this->mWorkStack );
 
                if ( !$ofname ) {
                        $this->trace .= "Profiling error: $functionname\n";
@@ -58,7 +58,7 @@ class ProfilerSimpleTrace extends ProfilerSimple {
                        }
                        $elapsedreal = $this->getTime() - $ortime;
                        $this->trace .= sprintf( "%03.6f %6.1f", $elapsedreal, $this->memoryDiff() ) .
-                                       str_repeat(" ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n";
+                                       str_repeat( " ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n";
                }
        }
 
@@ -69,7 +69,7 @@ class ProfilerSimpleTrace extends ProfilerSimple {
        }
 
        function logData() {
-               if ( php_sapi_name() === 'cli' ) {
+               if ( PHP_SAPI === 'cli' ) {
                        print "<!-- \n {$this->trace} \n -->";
                } elseif ( $this->getContentType() === 'text/html' ) {
                        print "<!-- \n {$this->trace} \n -->";
index a95ccb0..abefa81 100644 (file)
@@ -50,7 +50,7 @@ class ProfilerSimpleUDP extends ProfilerSimple {
                $plength = 0;
                $packet = "";
                foreach ( $this->mCollated as $entry => $pfdata ) {
-                       if( !isset($pfdata['count'])
+                       if( !isset( $pfdata['count'] )
                                || !isset( $pfdata['cpu'] )
                                || !isset( $pfdata['cpu_sq'] )
                                || !isset( $pfdata['real'] )
index fad0027..9904107 100644 (file)
@@ -441,9 +441,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        return $this->modifiedTime[$context->getHash()] = 1;
                }
 
-               wfProfileIn( __METHOD__.'-filemtime' );
+               wfProfileIn( __METHOD__ . '-filemtime' );
                $filesMtime = max( array_map( array( __CLASS__, 'safeFilemtime' ), $files ) );
-               wfProfileOut( __METHOD__.'-filemtime' );
+               wfProfileOut( __METHOD__ . '-filemtime' );
                $this->modifiedTime[$context->getHash()] = max(
                        $filesMtime,
                        $this->getMsgBlobMtime( $context->getLanguage() ) );
@@ -571,7 +571,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                foreach ( array_unique( $scripts ) as $fileName ) {
                        $localPath = $this->getLocalPath( $fileName );
                        if ( !file_exists( $localPath ) ) {
-                               throw new MWException( __METHOD__.": script file not found: \"$localPath\"" );
+                               throw new MWException( __METHOD__ . ": script file not found: \"$localPath\"" );
                        }
                        $contents = file_get_contents( $localPath );
                        if ( $wgResourceLoaderValidateStaticJS ) {
@@ -628,7 +628,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        protected function readStyleFile( $path, $flip ) {
                $localPath = $this->getLocalPath( $path );
                if ( !file_exists( $localPath ) ) {
-                       $msg = __METHOD__.": style file not found: \"$localPath\"";
+                       $msg = __METHOD__ . ": style file not found: \"$localPath\"";
                        wfDebugLog( 'resourceloader', $msg );
                        throw new MWException( $msg );
                }
index 1d36911..32cf6b2 100644 (file)
@@ -224,7 +224,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                                "};\n";
 
                        // Conditional script injection
-                       $scriptTag = Html::linkedScript( $wgLoadScript . '?' . wfArrayToCGI( $query ) );
+                       $scriptTag = Html::linkedScript( $wgLoadScript . '?' . wfArrayToCgi( $query ) );
                        $out .= "if ( isCompatible() ) {\n" .
                                "\t" . Xml::encodeJsCall( 'document.write', array( $scriptTag ) ) .
                                "}\n" .
index b85da16..4ea9f4e 100644 (file)
@@ -147,7 +147,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                                continue;
                        }
                        $title = Title::newFromText( $titleText );
-                       if ( !$title || $title->isRedirect()  ) {
+                       if ( !$title || $title->isRedirect() ) {
                                continue;
                        }
                        $media = isset( $options['media'] ) ? $options['media'] : 'all';
index 6ceadff..d64201c 100644 (file)
@@ -424,7 +424,7 @@ class RevDel_ArchivedRevisionItem extends RevDel_ArchiveItem {
                $dbw->update( 'archive',
                        array( 'ar_deleted' => $bits ),
                        array( 'ar_rev_id' => $this->row->ar_rev_id,
-                                  'ar_deleted' => $this->getBits()
+                               'ar_deleted' => $this->getBits()
                        ),
                        __METHOD__ );
                return (bool)$dbw->affectedRows();
@@ -454,7 +454,9 @@ class RevDel_FileList extends RevDel_List {
                foreach( $this->ids as $timestamp ) {
                        $archiveNames[] = $timestamp . '!' . $this->title->getDBkey();
                }
-               return $db->select( 'oldimage', '*',
+               return $db->select(
+                       'oldimage',
+                       OldLocalFile::selectFields(),
                        array(
                                'oi_name'         => $this->title->getDBkey(),
                                'oi_archive_name' => $archiveNames
@@ -695,7 +697,9 @@ class RevDel_ArchivedFileList extends RevDel_FileList {
         */
        public function doQuery( $db ) {
                $ids = array_map( 'intval', $this->ids );
-               return $db->select( 'filearchive', '*',
+               return $db->select(
+                       'filearchive',
+                       ArchivedFile::selectFields(),
                        array(
                                'fa_name' => $this->title->getDBkey(),
                                'fa_id'   => $ids
@@ -899,7 +903,7 @@ class RevDel_LogItem extends RevDel_Item {
                $action = $formatter->getActionText();
                // Comment
                $comment = $this->list->getLanguage()->getDirMark() . Linker::commentBlock( $this->row->log_comment );
-               if( LogEventsList::isDeleted($this->row,LogPage::DELETED_COMMENT) ) {
+               if( LogEventsList::isDeleted( $this->row, LogPage::DELETED_COMMENT ) ) {
                        $comment = '<span class="history-deleted">' . $comment . '</span>';
                }
 
index 0199edb..5e5755c 100644 (file)
@@ -45,7 +45,7 @@ class SearchEngine {
         */
        protected $db;
 
-       function __construct($db = null) {
+       function __construct( $db = null ) {
                if ( $db ) {
                        $this->db = $db;
                } else {
@@ -183,7 +183,7 @@ class SearchEngine {
 
                        # Exact match? No need to look further.
                        $title = Title::newFromText( $term );
-                       if ( is_null( $title ) ){
+                       if ( is_null( $title ) ) {
                                return null;
                        }
 
@@ -1142,8 +1142,8 @@ class SearchHighlighter {
                                // add more lines
                                $add = $index + 1;
                                while ( $len < $targetchars - 20
-                                          && array_key_exists( $add, $all )
-                                          && !array_key_exists( $add, $snippets ) ) {
+                                               && array_key_exists( $add, $all )
+                                               && !array_key_exists( $add, $snippets ) ) {
                                        $offsets[$add] = 0;
                                        $tt = "\n" . $this->extract( $all[$add], 0, $targetchars - $len, $offsets[$add] );
                                        $extended[$add] = $tt;
@@ -1153,7 +1153,7 @@ class SearchHighlighter {
                        }
                }
 
-               // $snippets = array_map('htmlspecialchars', $extended);
+               // $snippets = array_map( 'htmlspecialchars', $extended );
                $snippets = $extended;
                $last = - 1;
                $extract = '';
@@ -1243,7 +1243,7 @@ class SearchHighlighter {
                        $posEnd = $end;
                }
 
-               if ( $end > $start )  {
+               if ( $end > $start ) {
                        return substr( $text, $start, $end - $start );
                } else {
                        return '';
@@ -1332,12 +1332,12 @@ class SearchHighlighter {
                $fname = __METHOD__;
                wfProfileIn( $fname );
 
-               // $text = preg_replace("/'{2,5}/", "", $text);
-               // $text = preg_replace("/\[[a-z]+:\/\/[^ ]+ ([^]]+)\]/", "\\2", $text);
-               // $text = preg_replace("/\[\[([^]|]+)\]\]/", "\\1", $text);
-               // $text = preg_replace("/\[\[([^]]+\|)?([^|]]+)\]\]/", "\\2", $text);
-               // $text = preg_replace("/\\{\\|(.*?)\\|\\}/", "", $text);
-               // $text = preg_replace("/\\[\\[[A-Za-z_-]+:([^|]+?)\\]\\]/", "", $text);
+               // $text = preg_replace( "/'{2,5}/", "", $text );
+               // $text = preg_replace( "/\[[a-z]+:\/\/[^ ]+ ([^]]+)\]/", "\\2", $text );
+               // $text = preg_replace( "/\[\[([^]|]+)\]\]/", "\\1", $text );
+               // $text = preg_replace( "/\[\[([^]]+\|)?([^|]]+)\]\]/", "\\2", $text );
+               // $text = preg_replace( "/\\{\\|(.*?)\\|\\}/", "", $text );
+               // $text = preg_replace( "/\\[\\[[A-Za-z_-]+:([^|]+?)\\]\\]/", "", $text );
                $text = preg_replace( "/\\{\\{([^|]+?)\\}\\}/", "", $text );
                $text = preg_replace( "/\\{\\{([^|]+\\|)(.*?)\\}\\}/", "\\2", $text );
                $text = preg_replace( "/\\[\\[([^|]+?)\\]\\]/", "\\1", $text );
@@ -1419,8 +1419,7 @@ class SearchHighlighter {
 
                        $line = htmlspecialchars( $pre . $found . $post );
                        $pat2 = '/(' . $terms . ")/i";
-                       $line = preg_replace( $pat2,
-                         "<span class='searchmatch'>\\1</span>", $line );
+                       $line = preg_replace( $pat2, "<span class='searchmatch'>\\1</span>", $line );
 
                        $extract .= "${line}\n";
                }
index 368d900..ebc9d5a 100644 (file)
@@ -34,7 +34,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * Creates an instance of this class
         * @param $db DatabaseIbm_db2: database object
         */
-       function __construct($db) {
+       function __construct( $db ) {
                parent::__construct( $db );
        }
 
@@ -45,8 +45,8 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return SqlSearchResultSet
         */
        function searchText( $term ) {
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), true)));
-               return new SqlSearchResultSet($resultSet, $this->searchTerms);
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), true ) ) );
+               return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
        /**
@@ -55,9 +55,9 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $term String: taw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle($term) {
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), false)));
-               return new SqlSearchResultSet($resultSet, $this->searchTerms);
+       function searchTitle( $term ) {
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), false ) ) );
+               return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
 
@@ -66,7 +66,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryRedirect() {
-               if ($this->showRedirects) {
+               if ( $this->showRedirects ) {
                        return '';
                } else {
                        return 'AND page_is_redirect=0';
@@ -78,10 +78,10 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryNamespaces() {
-               if( is_null($this->namespaces) )
+               if( is_null( $this->namespaces ) )
                        return '';
-               $namespaces = implode(',', $this->namespaces);
-               if ($namespaces == '') {
+               $namespaces = implode( ',', $this->namespaces );
+               if ( $namespaces == '' ) {
                        $namespaces = '0';
                }
                return 'AND page_namespace IN (' . $namespaces . ')';
@@ -92,7 +92,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryLimit( $sql ) {
-               return $this->db->limitResult($sql, $this->limit, $this->offset);
+               return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
        /**
@@ -100,7 +100,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * subclasses may define this though
         * @return String
         */
-       function queryRanking($filteredTerm, $fulltext) {
+       function queryRanking( $filteredTerm, $fulltext ) {
                // requires Net Search Extender or equivalent
                // return ' ORDER BY score(1)';
                return '';
@@ -114,10 +114,10 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function getQuery( $filteredTerm, $fulltext ) {
-               return $this->queryLimit($this->queryMain($filteredTerm, $fulltext) . ' ' .
+               return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryRedirect() . ' ' .
                        $this->queryNamespaces() . ' ' .
-                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ');
+                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ' );
        }
 
 
@@ -126,7 +126,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $fulltext Boolean
         * @return String
         */
-       function getIndexField($fulltext) {
+       function getIndexField( $fulltext ) {
                return $fulltext ? 'si_text' : 'si_title';
        }
 
@@ -138,9 +138,9 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryMain( $filteredTerm, $fulltext ) {
-               $match = $this->parseQuery($filteredTerm, $fulltext);
-               $page        = $this->db->tableName('page');
-               $searchindex = $this->db->tableName('searchindex');
+               $match = $this->parseQuery( $filteredTerm, $fulltext );
+               $page = $this->db->tableName( 'page' );
+               $searchindex = $this->db->tableName( 'searchindex' );
                return 'SELECT page_id, page_namespace, page_title ' .
                        "FROM $page,$searchindex " .
                        'WHERE page_id=si_page AND ' . $match;
@@ -149,7 +149,7 @@ class SearchIBM_DB2 extends SearchEngine {
        /** @todo document
         * @return string
         */
-       function parseQuery($filteredText, $fulltext) {
+       function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
                $lc = SearchEngine::legalSearchChars();
                $this->searchTerms = array();
@@ -158,9 +158,9 @@ class SearchIBM_DB2 extends SearchEngine {
                $m = array();
                $q = array();
 
-               if (preg_match_all('/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER)) {
-                       foreach($m as $terms) {
+               if ( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
+                       foreach( $m as $terms ) {
 
                                // Search terms in all variant forms, only
                                // apply on wiki with LanguageConverter
@@ -173,19 +173,19 @@ class SearchIBM_DB2 extends SearchEngine {
                                else
                                        $q[] = $terms[1] . $wgContLang->normalizeForSearch( $terms[2] );
 
-                               if (!empty($terms[3])) {
+                               if ( !empty( $terms[3] ) ) {
                                        $regexp = preg_quote( $terms[3], '/' );
-                                       if ($terms[4])
+                                       if ( $terms[4] )
                                                $regexp .= "[0-9A-Za-z_]+";
                                } else {
-                                       $regexp = preg_quote(str_replace('"', '', $terms[2]), '/');
+                                       $regexp = preg_quote(str_replace( '"', '', $terms[2]), '/' );
                                }
                                $this->searchTerms[] = $regexp;
                        }
                }
 
-               $searchon = $this->db->strencode(join(',', $q));
-               $field = $this->getIndexField($fulltext);
+               $searchon = $this->db->strencode( join( ',', $q ) );
+               $field = $this->getIndexField( $fulltext );
 
                // requires Net Search Extender or equivalent
                //return " CONTAINS($field, '$searchon') > 0 ";
@@ -201,18 +201,18 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $title String
         * @param $text String
         */
-       function update($id, $title, $text) {
-               $dbw = wfGetDB(DB_MASTER);
-               $dbw->replace('searchindex',
-                       array('si_page'),
+       function update( $id, $title, $text ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->replace( 'searchindex',
+                       array( 'si_page' ),
                        array(
                                'si_page' => $id,
                                'si_title' => $title,
                                'si_text' => $text
                        ), 'SearchIBM_DB2::update' );
                // ?
-               //$dbw->query("CALL ctx_ddl.sync_index('si_text_idx')");
-               //$dbw->query("CALL ctx_ddl.sync_index('si_title_idx')");
+               //$dbw->query( "CALL ctx_ddl.sync_index('si_text_idx')" );
+               //$dbw->query( "CALL ctx_ddl.sync_index('si_title_idx')" );
        }
 
        /**
@@ -222,13 +222,13 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $id Integer
         * @param $title String
         */
-       function updateTitle($id, $title) {
-               $dbw = wfGetDB(DB_MASTER);
+       function updateTitle( $id, $title ) {
+               $dbw = wfGetDB( DB_MASTER );
 
-               $dbw->update('searchindex',
-                       array('si_title' => $title),
-                       array('si_page'  => $id),
+               $dbw->update( 'searchindex',
+                       array( 'si_title' => $title ),
+                       array( 'si_page'  => $id ),
                        'SearchIBM_DB2::updateTitle',
-                       array());
+                       array() );
        }
 }
index 23dd479..85fe148 100644 (file)
@@ -253,5 +253,3 @@ class MssqlSearchResultSet extends SearchResultSet {
                return new SearchResult( $row );
        }
 }
-
-
index 5cee03e..a76662b 100644 (file)
@@ -58,7 +58,7 @@ class SearchMySQL extends SearchEngine {
                # @todo FIXME: This doesn't handle parenthetical expressions.
                $m = array();
                if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER ) ) {
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
                        foreach( $m as $bits ) {
                                @list( /* all */, $modifier, $term, $nonQuoted, $wildcard ) = $bits;
 
@@ -221,7 +221,7 @@ class SearchMySQL extends SearchEngine {
         */
        protected function queryFeatures( &$query ) {
                foreach ( $this->features as $feature => $value ) {
-                       if ( $feature ===  'list-redirects' && !$value ) {
+                       if ( $feature === 'list-redirects' && !$value ) {
                                $query['conds']['page_is_redirect'] = 0;
                        } elseif( $feature === 'title-suffix-filter' && $value ) {
                                $query['conds'][] = 'page_title' . $this->db->buildLike( $this->db->anyString(), $value );
index 29070e1..009502b 100644 (file)
@@ -61,7 +61,7 @@ class SearchOracle extends SearchEngine {
         * Creates an instance of this class
         * @param $db DatabasePostgres: database object
         */
-       function __construct($db) {
+       function __construct( $db ) {
                parent::__construct( $db );
        }
 
@@ -72,11 +72,11 @@ class SearchOracle extends SearchEngine {
         * @return SqlSearchResultSet
         */
        function searchText( $term ) {
-               if ($term == '')
-                       return new SqlSearchResultSet(false, '');
+               if ( $term == '' )
+                       return new SqlSearchResultSet( false, '' );
 
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), true)));
-               return new SqlSearchResultSet($resultSet, $this->searchTerms);
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), true ) ) );
+               return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
        /**
@@ -85,12 +85,12 @@ class SearchOracle extends SearchEngine {
         * @param $term String: raw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle($term) {
-               if ($term == '')
-                       return new SqlSearchResultSet(false, '');
+       function searchTitle( $term ) {
+               if ( $term == '' )
+                       return new SqlSearchResultSet( false, '' );
 
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), false)));
-               return new MySQLSearchResultSet($resultSet, $this->searchTerms);
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), false ) ) );
+               return new MySQLSearchResultSet( $resultSet, $this->searchTerms );
        }
 
 
@@ -99,7 +99,7 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryRedirect() {
-               if ($this->showRedirects) {
+               if ( $this->showRedirects ) {
                        return '';
                } else {
                        return 'AND page_is_redirect=0';
@@ -111,7 +111,7 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryNamespaces() {
-               if( is_null($this->namespaces) )
+               if( is_null( $this->namespaces ) )
                        return '';
                if ( !count( $this->namespaces ) ) {
                        $namespaces = '0';
@@ -129,7 +129,7 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryLimit( $sql ) {
-               return $this->db->limitResult($sql, $this->limit, $this->offset);
+               return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
        /**
@@ -150,10 +150,10 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function getQuery( $filteredTerm, $fulltext ) {
-               return $this->queryLimit($this->queryMain($filteredTerm, $fulltext) . ' ' .
+               return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryRedirect() . ' ' .
                        $this->queryNamespaces() . ' ' .
-                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ');
+                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ' );
        }
 
 
@@ -162,7 +162,7 @@ class SearchOracle extends SearchEngine {
         * @param $fulltext Boolean
         * @return String
         */
-       function getIndexField($fulltext) {
+       function getIndexField( $fulltext ) {
                return $fulltext ? 'si_text' : 'si_title';
        }
 
@@ -174,9 +174,9 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryMain( $filteredTerm, $fulltext ) {
-               $match = $this->parseQuery($filteredTerm, $fulltext);
-               $page        = $this->db->tableName('page');
-               $searchindex = $this->db->tableName('searchindex');
+               $match = $this->parseQuery( $filteredTerm, $fulltext );
+               $page = $this->db->tableName( 'page' );
+               $searchindex = $this->db->tableName( 'searchindex' );
                return 'SELECT page_id, page_namespace, page_title ' .
                        "FROM $page,$searchindex " .
                        'WHERE page_id=si_page AND ' . $match;
@@ -187,7 +187,7 @@ class SearchOracle extends SearchEngine {
         * as part of a WHERE clause
         * @return string
         */
-       function parseQuery($filteredText, $fulltext) {
+       function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
                $lc = SearchEngine::legalSearchChars();
                $this->searchTerms = array();
@@ -195,9 +195,9 @@ class SearchOracle extends SearchEngine {
                # @todo FIXME: This doesn't handle parenthetical expressions.
                $m = array();
                $searchon = '';
-               if (preg_match_all('/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER)) {
-                       foreach($m as $terms) {
+               if ( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
+                       foreach( $m as $terms ) {
                                // Search terms in all variant forms, only
                                // apply on wiki with LanguageConverter
                                $temp_terms = $wgContLang->autoConvertToAllVariants( $terms[2] );
@@ -210,27 +210,27 @@ class SearchOracle extends SearchEngine {
                                else {
                                        $searchon .= ($terms[1] == '-' ? ' ~' : ' & ') . $this->escapeTerm( $terms[2] );
                                }
-                               if (!empty($terms[3])) {
+                               if ( !empty( $terms[3] ) ) {
                                        $regexp = preg_quote( $terms[3], '/' );
-                                       if ($terms[4])
+                                       if ( $terms[4] )
                                                $regexp .= "[0-9A-Za-z_]+";
                                } else {
-                                       $regexp = preg_quote(str_replace('"', '', $terms[2]), '/');
+                                       $regexp = preg_quote( str_replace( '"', '', $terms[2] ), '/' );
                                }
                                $this->searchTerms[] = $regexp;
                        }
                }
 
 
-               $searchon = $this->db->addQuotes(ltrim($searchon, ' &'));
-               $field = $this->getIndexField($fulltext);
+               $searchon = $this->db->addQuotes( ltrim( $searchon, ' &' ) );
+               $field = $this->getIndexField( $fulltext );
                return " CONTAINS($field, $searchon, 1) > 0 ";
        }
 
-       private function escapeTerm($t) {
+       private function escapeTerm( $t ) {
                global $wgContLang;
-               $t = $wgContLang->normalizeForSearch($t);
-               $t = isset($this->reservedWords[strtoupper($t)]) ? '{'.$t.'}' : $t;
+               $t = $wgContLang->normalizeForSearch( $t );
+               $t = isset( $this->reservedWords[strtoupper( $t )] ) ? '{'.$t.'}' : $t;
                $t = preg_replace('/^"(.*)"$/', '($1)', $t);
                $t = preg_replace('/([-&|])/', '\\\\$1', $t);
                return $t;
@@ -243,10 +243,10 @@ class SearchOracle extends SearchEngine {
         * @param $title String
         * @param $text String
         */
-       function update($id, $title, $text) {
-               $dbw = wfGetDB(DB_MASTER);
-               $dbw->replace('searchindex',
-                       array('si_page'),
+       function update( $id, $title, $text ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->replace( 'searchindex',
+                       array( 'si_page' ),
                        array(
                                'si_page' => $id,
                                'si_title' => $title,
@@ -271,14 +271,14 @@ class SearchOracle extends SearchEngine {
         * @param $id Integer
         * @param $title String
         */
-       function updateTitle($id, $title) {
-               $dbw = wfGetDB(DB_MASTER);
+       function updateTitle( $id, $title ) {
+               $dbw = wfGetDB( DB_MASTER );
 
-               $dbw->update('searchindex',
-                       array('si_title' => $title),
-                       array('si_page'  => $id),
+               $dbw->update( 'searchindex',
+                       array( 'si_title' => $title ),
+                       array( 'si_page'  => $id ),
                        'SearchOracle::updateTitle',
-                       array());
+                       array() );
        }
 
 
index 6864889..727cc16 100644 (file)
@@ -51,11 +51,11 @@ class SearchPostgres extends SearchEngine {
         * @return PostgresSearchResultSet
         */
        function searchTitle( $term ) {
-               $q = $this->searchQuery( $term , 'titlevector', 'page_title' );
-               $olderror = error_reporting(E_ERROR);
+               $q = $this->searchQuery( $term, 'titlevector', 'page_title' );
+               $olderror = error_reporting( E_ERROR );
                $resultSet = $this->db->resultObject( $this->db->query( $q, 'SearchPostgres', true ) );
-               error_reporting($olderror);
-               if (!$resultSet) {
+               error_reporting( $olderror );
+               if ( !$resultSet ) {
                        // Needed for "Query requires full scan, GIN doesn't support it"
                        return new SearchResultTooMany();
                }
@@ -66,8 +66,8 @@ class SearchPostgres extends SearchEngine {
                $q = $this->searchQuery( $term, 'textvector', 'old_text' );
                $olderror = error_reporting(E_ERROR);
                $resultSet = $this->db->resultObject( $this->db->query( $q, 'SearchPostgres', true ) );
-               error_reporting($olderror);
-               if (!$resultSet) {
+               error_reporting( $olderror );
+               if ( !$resultSet ) {
                        return new SearchResultTooMany();
                }
                return new PostgresSearchResultSet( $resultSet, $this->searchTerms );
@@ -99,16 +99,16 @@ class SearchPostgres extends SearchEngine {
                $m = array();
                if( preg_match_all('/([-!]?)(\S+)\s*/', $term, $m, PREG_SET_ORDER ) ) {
                        foreach( $m as $terms ) {
-                               if (strlen($terms[1])) {
+                               if ( strlen( $terms[1] ) ) {
                                        $searchstring .= ' & !';
                                }
-                               if (strtolower($terms[2]) === 'and') {
+                               if ( strtolower( $terms[2] ) === 'and' ) {
                                        $searchstring .= ' & ';
                                }
-                               elseif (strtolower($terms[2]) === 'or' or $terms[2] === '|') {
+                               elseif ( strtolower( $terms[2] ) === 'or' or $terms[2] === '|' ) {
                                        $searchstring .= ' | ';
                                }
-                               elseif (strtolower($terms[2]) === 'not') {
+                               elseif ( strtolower( $terms[2] ) === 'not' ) {
                                        $searchstring .= ' & !';
                                }
                                else {
@@ -133,7 +133,7 @@ class SearchPostgres extends SearchEngine {
                $searchstring = preg_replace('/^[\'"](.*)[\'"]$/', "$1", $searchstring);
 
                ## Quote the whole thing
-               $searchstring = $this->db->addQuotes($searchstring);
+               $searchstring = $this->db->addQuotes( $searchstring );
 
                wfDebug( "parseQuery returned: $searchstring \n" );
 
@@ -154,15 +154,15 @@ class SearchPostgres extends SearchEngine {
 
                ## We need a separate query here so gin does not complain about empty searches
                $SQL = "SELECT to_tsquery($searchstring)";
-               $res = $this->db->query($SQL);
-               if (!$res) {
+               $res = $this->db->query( $SQL );
+               if ( !$res ) {
                        ## TODO: Better output (example to catch: one 'two)
-                       die ("Sorry, that was not a valid search string. Please go back and try again");
+                       die( "Sorry, that was not a valid search string. Please go back and try again" );
                }
                $top = $res->fetchRow();
                $top = $top[0];
 
-               if ($top === "") { ## e.g. if only stopwords are used XXX return something better
+               if ( $top === "" ) { ## e.g. if only stopwords are used XXX return something better
                        $query = "SELECT page_id, page_namespace, page_title, 0 AS score ".
                                "FROM page p, revision r, pagecontent c WHERE p.page_latest = r.rev_id " .
                                "AND r.rev_text_id = c.old_id AND 1=0";
@@ -182,14 +182,14 @@ class SearchPostgres extends SearchEngine {
                }
 
                ## Redirects
-               if (! $this->showRedirects)
+               if ( !$this->showRedirects )
                        $query .= ' AND page_is_redirect = 0';
 
                ## Namespaces - defaults to 0
-               if( !is_null($this->namespaces) ){ // null -> search all
-                       if ( count($this->namespaces) < 1)
+               if( !is_null( $this->namespaces ) ) { // null -> search all
+                       if ( count( $this->namespaces ) < 1 ) {
                                $query .= ' AND page_namespace = 0';
-                       else {
+                       else {
                                $namespaces = $this->db->makeList( $this->namespaces );
                                $query .= " AND page_namespace IN ($namespaces)";
                        }
@@ -211,7 +211,7 @@ class SearchPostgres extends SearchEngine {
                $SQL = "UPDATE pagecontent SET textvector = NULL WHERE old_id IN ".
                                "(SELECT rev_text_id FROM revision WHERE rev_page = " . intval( $pageid ) .
                                " ORDER BY rev_text_id DESC OFFSET 1)";
-               $this->db->query($SQL);
+               $this->db->query( $SQL );
                return true;
        }
 
@@ -226,7 +226,7 @@ class SearchPostgres extends SearchEngine {
  */
 class PostgresSearchResult extends SearchResult {
        function __construct( $row ) {
-               parent::__construct($row);
+               parent::__construct( $row );
                $this->score = $row->score;
        }
        function getScore() {
index e52e4fe..f91399a 100644 (file)
@@ -62,7 +62,7 @@ class SearchSqlite extends SearchEngine {
 
                $m = array();
                if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER ) ) {
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
                        foreach( $m as $bits ) {
                                @list( /* all */, $modifier, $term, $nonQuoted, $wildcard ) = $bits;
 
@@ -214,7 +214,7 @@ class SearchSqlite extends SearchEngine {
         * @return String
         */
        function queryNamespaces() {
-               if( is_null($this->namespaces) )
+               if( is_null( $this->namespaces ) )
                        return '';  # search all
                if ( !count( $this->namespaces ) ) {
                        $namespaces = '0';
@@ -266,7 +266,7 @@ class SearchSqlite extends SearchEngine {
         */
        function queryMain( $filteredTerm, $fulltext ) {
                $match = $this->parseQuery( $filteredTerm, $fulltext );
-               $page        = $this->db->tableName( 'page' );
+               $page = $this->db->tableName( 'page' );
                $searchindex = $this->db->tableName( 'searchindex' );
                return "SELECT $searchindex.rowid, page_namespace, page_title " .
                        "FROM $page,$searchindex " .
@@ -317,7 +317,7 @@ class SearchSqlite extends SearchEngine {
         * @param $id Integer
         * @param $title String
         */
-    function updateTitle( $id, $title ) {
+       function updateTitle( $id, $title ) {
                if ( !$this->fulltextSearchSupported() ) {
                        return;
                }
index 389c317..eabcda3 100644 (file)
@@ -79,7 +79,7 @@ class SearchUpdate implements DeferrableUpdate {
                $text = preg_replace( "/<\\/?\\s*[A-Za-z][^>]*?>/",
                        ' ', $wgContLang->lc( " " . $text . " " ) ); # Strip HTML markup
                $text = preg_replace( "/(^|\\n)==\\s*([^\\n]+)\\s*==(\\s)/sD",
-                 "\\1\\2 \\2 \\2\\3", $text ); # Emphasize headings
+                       "\\1\\2 \\2 \\2\\3", $text ); # Emphasize headings
 
                # Strip external URLs
                $uc = "A-Za-z0-9_\\/:.,~%\\-+&;#?!=()@\\x80-\\xFF";
@@ -97,7 +97,7 @@ class SearchUpdate implements DeferrableUpdate {
                $text = preg_replace( $pat2, " \\1 \\3", $text );
 
                $text = preg_replace( "/([^{$lc}])([{$lc}]+)]]([a-z]+)/",
-                 "\\1\\2 \\2\\3", $text ); # Handle [[game]]s
+                       "\\1\\2 \\2\\3", $text ); # Handle [[game]]s
 
                # Strip all remaining non-search characters
                $text = preg_replace( "/[^{$lc}]+/", " ", $text );
@@ -127,7 +127,7 @@ class SearchUpdate implements DeferrableUpdate {
                wfRunHooks( 'SearchUpdate', array( $this->mId, $this->mNamespace, $this->mTitle, &$text ) );
 
                # Perform the actual update
-               $search->update($this->mId, $search->normalizeText( Title::indexTitle( $this->mNamespace, $this->mTitle ) ),
+               $search->update( $this->mId, $search->normalizeText( Title::indexTitle( $this->mNamespace, $this->mTitle ) ),
                                $search->normalizeText( $text ) );
 
                wfProfileOut( __METHOD__ );
index b2e2e71..68161b9 100644 (file)
  *
  * @ingroup Site
  */
-class MediaWikiSite extends SiteObject {
+class MediaWikiSite extends Site {
 
        const PATH_FILE = 'file_path';
        const PATH_PAGE = 'page_path';
 
        /**
         * @since 1.21
+        * @deprecated Just use the constructor or the factory Site::newForType
         *
         * @param integer $globalId
         *
         * @return MediaWikiSite
         */
        public static function newFromGlobalId( $globalId ) {
-               return SitesTable::singleton()->newRow( array(
-                       'type' => Site::TYPE_MEDIAWIKI,
-                       'global_key' => $globalId,
-               ), true );
+               $site = new static();
+               $site->setGlobalId( $globalId );
+               return $site;
+       }
+
+       /**
+        * Constructor.
+        *
+        * @since 1.21
+        *
+        * @param string $type
+        */
+       public function __construct( $type = self::TYPE_MEDIAWIKI ) {
+               parent::__construct( $type );
        }
 
        /**
@@ -167,7 +178,7 @@ class MediaWikiSite extends SiteObject {
         * @param array $externalData A reply from the API on a external server.
         * @param string $pageTitle Identifies the page at the external site, needing normalization.
         *
-        * @return array|false a 'page' structure representing the page identified by $pageTitle.
+        * @return array|boolean a 'page' structure representing the page identified by $pageTitle.
         */
        private static function extractPageRecord( $externalData, $pageTitle ) {
                // If there is a special case with only one returned page
@@ -290,16 +301,16 @@ class MediaWikiSite extends SiteObject {
        }
 
        /**
-        * @see Site::getPagePath
+        * @see Site::getPageUrl
         *
         * This implementation returns a URL constructed using the path returned by getLinkPath().
-        * In addition to the default behaviour implemented by SiteObject::getPageUrl(), this
+        * In addition to the default behaviour implemented by Site::getPageUrl(), this
         * method converts the $pageName to DBKey-format by replacing spaces with underscores
         * before using it in the URL.
         *
         * @since 1.21
         *
-        * @param $pagename string: Page name (default: false)
+        * @param string|boolean $pageName Page name or false (default: false)
         *
         * @return string
         */
@@ -312,7 +323,7 @@ class MediaWikiSite extends SiteObject {
 
                if ( $pageName !== false ) {
                        $pageName = $this->toDBKey( trim( $pageName ) );
-                       $url = str_replace( '$1', wfUrlencode( $pageName ), $url ) ;
+                       $url = str_replace( '$1', wfUrlencode( $pageName ), $url );
                }
 
                return $url;
@@ -325,7 +336,7 @@ class MediaWikiSite extends SiteObject {
         *
         * @since 1.21
         *
-        * @param string|false $path
+        * @param string|boolean $path
         *
         * @return string
         */
index 200a006..525c375 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Interface for site objects.
+ * Represents a single site.
  *
  * 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
@@ -26,7 +26,7 @@
  * @license GNU GPL v2+
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
-interface Site {
+class Site implements Serializable {
 
        const TYPE_UNKNOWN = 'unknown';
        const TYPE_MEDIAWIKI = 'mediawiki';
@@ -38,42 +38,140 @@ interface Site {
 
        const SOURCE_LOCAL = 'local';
 
+       const PATH_LINK = 'link';
+
+
        /**
-        * Returns the global site identifier (ie enwiktionary).
+        * A version ID that identifies the serialization structure used by getSerializationData()
+        * and unserialize(). This is useful for constructing cache keys in cases where the cache relies
+        * on serialization for storing the SiteList.
         *
+        * @var string A string uniquely identifying the version of the serialization structure.
+        */
+       const SERIAL_VERSION_ID = '2013-01-23';
+
+       /**
         * @since 1.21
         *
-        * @return string
+        * @var string|null
         */
-       public function getGlobalId();
+       protected $globalId = null;
 
        /**
-        * Sets the global site identifier (ie enwiktionary).
+        * @since 1.21
         *
+        * @var string
+        */
+       protected $type = self::TYPE_UNKNOWN;
+
+       /**
         * @since 1.21
         *
-        * @param string $globalId
+        * @var string
         */
-       public function setGlobalId( $globalId );
+       protected $group = self::GROUP_NONE;
 
        /**
-        * Returns the type of the site (ie mediawiki).
+        * @since 1.21
         *
+        * @var string
+        */
+       protected $source = self::SOURCE_LOCAL;
+
+       /**
         * @since 1.21
         *
-        * @return string
+        * @var string|null
+        */
+       protected $languageCode = null;
+
+       /**
+        * Holds the local ids for this site.
+        * local id type => [ ids for this type (strings) ]
+        *
+        * @since 1.21
+        *
+        * @var array[]
+        */
+       protected $localIds = array();
+
+       /**
+        * @since 1.21
+        *
+        * @var array
+        */
+       protected $extraData = array();
+
+       /**
+        * @since 1.21
+        *
+        * @var array
+        */
+       protected $extraConfig = array();
+
+       /**
+        * @since 1.21
+        *
+        * @var bool
         */
-       public function getType();
+       protected $forward = false;
 
        /**
-        * Sets the type of the site (ie mediawiki).
-        * TODO: remove, we cannot change this after instantiation
+        * @since 1.21
+        *
+        * @var int|null
+        */
+       protected $internalId = null;
+
+       /**
+        * Constructor.
         *
         * @since 1.21
         *
         * @param string $type
         */
-       public function setType( $type );
+       public function __construct( $type = self::TYPE_UNKNOWN ) {
+               $this->type = $type;
+       }
+
+       /**
+        * Returns the global site identifier (ie enwiktionary).
+        *
+        * @since 1.21
+        *
+        * @return string|null
+        */
+       public function getGlobalId() {
+               return $this->globalId;
+       }
+
+       /**
+        * Sets the global site identifier (ie enwiktionary).
+        *
+        * @since 1.21
+        *
+        * @param string|null $globalId
+        *
+        * @throws MWException
+        */
+       public function setGlobalId( $globalId ) {
+               if ( $globalId !== null && !is_string( $globalId ) ) {
+                       throw new MWException( '$globalId needs to be string or null' );
+               }
+
+               $this->globalId = $globalId;
+       }
+
+       /**
+        * Returns the type of the site (ie mediawiki).
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getType() {
+               return $this->type;
+       }
 
        /**
         * Gets the type of the site (ie wikipedia).
@@ -82,7 +180,9 @@ interface Site {
         *
         * @return string
         */
-       public function getGroup();
+       public function getGroup() {
+               return $this->group;
+       }
 
        /**
         * Sets the type of the site (ie wikipedia).
@@ -90,8 +190,16 @@ interface Site {
         * @since 1.21
         *
         * @param string $group
+        *
+        * @throws MWException
         */
-       public function setGroup( $group );
+       public function setGroup( $group ) {
+               if ( !is_string( $group ) ) {
+                       throw new MWException( '$group needs to be a string' );
+               }
+
+               $this->group = $group;
+       }
 
        /**
         * Returns the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
@@ -100,7 +208,9 @@ interface Site {
         *
         * @return string
         */
-       public function getSource();
+       public function getSource() {
+               return $this->source;
+       }
 
        /**
         * Sets the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
@@ -108,18 +218,46 @@ interface Site {
         * @since 1.21
         *
         * @param string $source
+        *
+        * @throws MWException
         */
-       public function setSource( $source );
+       public function setSource( $source ) {
+               if ( !is_string( $source ) ) {
+                       throw new MWException( '$source needs to be a string' );
+               }
+
+               $this->source = $source;
+       }
 
        /**
-        * Returns the protocol of the site, ie 'http://', 'irc://', '//'
-        * Or false if it's not known.
+        * Gets if site.tld/path/key:pageTitle should forward users to  the page on
+        * the actual site, where "key" is the local identifier.
         *
         * @since 1.21
         *
-        * @return string|false
+        * @return boolean
         */
-       public function getProtocol();
+       public function shouldForward() {
+               return $this->forward;
+       }
+
+       /**
+        * Sets if site.tld/path/key:pageTitle should forward users to  the page on
+        * the actual site, where "key" is the local identifier.
+        *
+        * @since 1.21
+        *
+        * @param boolean $shouldForward
+        *
+        * @throws MWException
+        */
+       public function setForward( $shouldForward ) {
+               if ( !is_bool( $shouldForward ) ) {
+                       throw new MWException( '$shouldForward needs to be a boolean' );
+               }
+
+               $this->forward = $shouldForward;
+       }
 
        /**
         * Returns the domain of the site, ie en.wikipedia.org
@@ -127,9 +265,95 @@ interface Site {
         *
         * @since 1.21
         *
-        * @return string|false
+        * @return string|null
+        */
+       public function getDomain() {
+               $path = $this->getLinkPath();
+
+               if ( $path === null ) {
+                       return null;
+               }
+
+               return parse_url( $path, PHP_URL_HOST );
+       }
+
+       /**
+        * Returns the protocol of the site.
+        *
+        * @since 1.21
+        *
+        * @throws MWException
+        * @return string
+        */
+       public function getProtocol() {
+               $path = $this->getLinkPath();
+
+               if ( $path === null ) {
+                       return '';
+               }
+
+               $protocol = parse_url( $path, PHP_URL_SCHEME );
+
+               // Malformed URL
+               if ( $protocol === false ) {
+                       throw new MWException( "failed to parse URL '$path'" );
+               }
+
+               // No schema
+               if ( $protocol === null ) {
+                       // Used for protocol relative URLs
+                       $protocol = '';
+               }
+
+               return $protocol;
+       }
+
+       /**
+        * Sets the path used to construct links with.
+        * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
+        *
+        * @param string $fullUrl
+        *
+        * @since 1.21
+        *
+        * @throws MWException
+        */
+       public function setLinkPath( $fullUrl ) {
+               $type = $this->getLinkPathType();
+
+               if ( $type === null ) {
+                       throw new MWException( "This Site does not support link paths." );
+               }
+
+               $this->setPath( $type, $fullUrl );
+       }
+
+       /**
+        * Returns the path used to construct links with or false if there is no such path.
+        *
+        * Shall be equivalent to getPath( getLinkPathType() ).
+        *
+        * @return string|null
+        */
+       public function getLinkPath() {
+               $type = $this->getLinkPathType();
+               return $type === null ? null: $this->getPath( $type );
+       }
+
+       /**
+        * Returns the main path type, that is the type of the path that should generally be used to construct links
+        * to the target site.
+        *
+        * This default implementation returns Site::PATH_LINK as the default path type. Subclasses can override this
+        * to define a different default path type, or return false to disable site links.
+        *
+        * @since 1.21
+        *
+        * @return string|null
         */
-       public function getDomain();
+       public function getLinkPathType() {
+               return self::PATH_LINK;
+       }
 
        /**
         * Returns the full URL for the given page on the site.
@@ -138,79 +362,155 @@ interface Site {
         * This generated URL is usually based upon the path returned by getLinkPath(),
         * but this is not a requirement.
         *
+        * This implementation returns a URL constructed using the path returned by getLinkPath().
+        *
         * @since 1.21
-        * @see Site::getLinkPath()
         *
-        * @param bool|String $page
+        * @param bool|String $pageName
         *
-        * @return string|false
+        * @return string|boolean false
         */
-       public function getPageUrl( $page = false );
+       public function getPageUrl( $pageName = false ) {
+               $url = $this->getLinkPath();
+
+               if ( $url === false ) {
+                       return false;
+               }
+
+               if ( $pageName !== false ) {
+                       $url = str_replace( '$1', rawurlencode( $pageName ), $url );
+               }
+
+               return $url;
+       }
 
        /**
-        * Returns language code of the sites primary language.
-        * Or false if it's not known.
+        * Returns $pageName without changes.
+        * Subclasses may override this to apply some kind of normalization.
+        *
+        * @see Site::normalizePageName
         *
         * @since 1.21
         *
-        * @return string|false
+        * @param string $pageName
+        *
+        * @return string
         */
-       public function getLanguageCode();
+       public function normalizePageName( $pageName ) {
+               return $pageName;
+       }
 
        /**
-        * Sets language code of the sites primary language.
+        * Returns the type specific fields.
         *
         * @since 1.21
         *
-        * @param string $languageCode
+        * @return array
         */
-       public function setLanguageCode( $languageCode );
+       public function getExtraData() {
+               return $this->extraData;
+       }
 
        /**
-        * Returns the normalized, canonical form of the given page name.
-        * How normalization is performed or what the properties of a normalized name are depends on the site.
-        * The general contract of this method is that the normalized form shall refer to the same content
-        * as the original form, and any other page name referring to the same content will have the same normalized form.
+        * Sets the type specific fields.
         *
-        * Note that this method may call out to the target site to perform the normalization, so it may be slow
-        * and fail due to IO errors.
+        * @since 1.21
+        *
+        * @param array $extraData
+        */
+       public function setExtraData( array $extraData ) {
+               $this->extraData = $extraData;
+       }
+
+       /**
+        * Returns the type specific config.
         *
         * @since 1.21
         *
-        * @param string $pageName
+        * @return array
+        */
+       public function getExtraConfig() {
+               return $this->extraConfig;
+       }
+
+       /**
+        * Sets the type specific config.
         *
-        * @return string the normalized page name
+        * @since 1.21
+        *
+        * @param array $extraConfig
         */
-       public function normalizePageName( $pageName );
+       public function setExtraConfig( array $extraConfig ) {
+               $this->extraConfig = $extraConfig;
+       }
 
        /**
-        * Returns the interwiki link identifiers that can be used for this site.
+        * Returns language code of the sites primary language.
+        * Or null if it's not known.
         *
         * @since 1.21
         *
-        * @return array of string
+        * @return string|null
         */
-       public function getInterwikiIds();
+       public function getLanguageCode() {
+               return $this->languageCode;
+       }
 
        /**
-        * Returns the equivalent link identifiers that can be used to make
-        * the site show up in interfaces such as the "language links" section.
+        * Sets language code of the sites primary language.
         *
         * @since 1.21
         *
-        * @return array of string
+        * @param string $languageCode
         */
-       public function getNavigationIds();
+       public function setLanguageCode( $languageCode ) {
+               $this->languageCode = $languageCode;
+       }
 
        /**
-        * Adds an local identifier to the site.
+        * Returns the set internal identifier for the site.
         *
         * @since 1.21
         *
-        * @param string $type The type of the identifier, element of the Site::ID_ enum
+        * @return string|null
+        */
+       public function getInternalId() {
+               return $this->internalId;
+       }
+
+       /**
+        * Sets the internal identifier for the site.
+        * This typically is a primary key in a db table.
+        *
+        * @since 1.21
+        *
+        * @param int|null $internalId
+        */
+       public function setInternalId( $internalId = null ) {
+               $this->internalId = $internalId;
+       }
+
+       /**
+        * Adds a local identifier.
+        *
+        * @since 1.21
+        *
+        * @param string $type
         * @param string $identifier
         */
-       public function addLocalId( $type, $identifier );
+       public function addLocalId( $type, $identifier ) {
+               if ( $this->localIds === false ) {
+                       $this->localIds = array();
+               }
+
+               if ( !array_key_exists( $type, $this->localIds ) ) {
+                       $this->localIds[$type] = array();
+               }
+
+               if ( !in_array( $identifier, $this->localIds[$type] ) ) {
+                       $this->localIds[$type][] = $identifier;
+               }
+       }
 
        /**
         * Adds an interwiki id to the site.
@@ -219,7 +519,9 @@ interface Site {
         *
         * @param string $identifier
         */
-       public function addInterwikiId( $identifier );
+       public function addInterwikiId( $identifier ) {
+               $this->addLocalId( self::ID_INTERWIKI, $identifier );
+       }
 
        /**
         * Adds a navigation id to the site.
@@ -228,35 +530,66 @@ interface Site {
         *
         * @param string $identifier
         */
-       public function addNavigationId( $identifier );
+       public function addNavigationId( $identifier ) {
+               $this->addLocalId( self::ID_EQUIVALENT, $identifier );
+       }
+
+       /**
+        * Returns the interwiki link identifiers that can be used for this site.
+        *
+        * @since 1.21
+        *
+        * @return string[]
+        */
+       public function getInterwikiIds() {
+               return array_key_exists( self::ID_INTERWIKI, $this->localIds ) ? $this->localIds[self::ID_INTERWIKI] : array();
+       }
 
        /**
-        * Saves the site.
+        * Returns the equivalent link identifiers that can be used to make
+        * the site show up in interfaces such as the "language links" section.
         *
         * @since 1.21
         *
-        * @param string|null $functionName
+        * @return string[]
         */
-       public function save( $functionName = null );
+       public function getNavigationIds() {
+               return array_key_exists( self::ID_EQUIVALENT, $this->localIds ) ? $this->localIds[self::ID_EQUIVALENT] : array();
+       }
 
        /**
-        * Returns the internal ID of the site.
+        * Returns all local ids
         *
         * @since 1.21
         *
-        * @return integer
+        * @return array[]
         */
-       public function getInternalId();
+       public function getLocalIds() {
+               return $this->localIds;
+       }
 
        /**
-        * Sets the provided url as path of the specified type.
+        * Sets the path used to construct links with.
+        * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
         *
         * @since 1.21
         *
         * @param string $pathType
         * @param string $fullUrl
+        *
+        * @throws MWException
         */
-       public function setPath( $pathType, $fullUrl );
+       public function setPath( $pathType, $fullUrl ) {
+               if ( !is_string( $fullUrl ) ) {
+                       throw new MWException( '$fullUrl needs to be a string' );
+               }
+
+               if ( !array_key_exists( 'paths', $this->extraData ) ) {
+                       $this->extraData['paths'] = array();
+               }
+
+               $this->extraData['paths'][$pathType] = $fullUrl;
+       }
 
        /**
         * Returns the path of the provided type or false if there is no such path.
@@ -265,52 +598,106 @@ interface Site {
         *
         * @param string $pathType
         *
-        * @return string|false
+        * @return string|null
         */
-       public function getPath( $pathType );
+       public function getPath( $pathType ) {
+               $paths = $this->getAllPaths();
+               return array_key_exists( $pathType, $paths ) ? $paths[$pathType] : null;
+       }
 
        /**
-        * Sets the path used to construct links with.
-        * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
-        *
-        * @param string $fullUrl
+        * Returns the paths as associative array.
+        * The keys are path types, the values are the path urls.
         *
         * @since 1.21
+        *
+        * @return string[]
         */
-       public function setLinkPath( $fullUrl );
+       public function getAllPaths() {
+               return array_key_exists( 'paths', $this->extraData ) ? $this->extraData['paths'] : array();
+       }
 
        /**
-        * Returns the path used to construct links with or false if there is no such path.
-        * Shall be equivalent to getPath( getLinkPathType() ).
+        * Removes the path of the provided type if it's set.
+        *
+        * @since 1.21
         *
-        * @return string|false
+        * @param string $pathType
         */
-       public function getLinkPath();
+       public function removePath( $pathType ) {
+               if ( array_key_exists( 'paths', $this->extraData ) ) {
+                       unset( $this->extraData['paths'][$pathType] );
+               }
+       }
 
        /**
-        * Returns the path type used to construct links with.
+        * @since 1.21
+        *
+        * @param string $siteType
         *
-        * @return string|false
+        * @return Site
         */
-       public function getLinkPathType();
+       public static function newForType( $siteType ) {
+               global $wgSiteTypes;
+
+               if ( array_key_exists( $siteType, $wgSiteTypes ) ) {
+                       return new $wgSiteTypes[$siteType]();
+               }
+
+               return new Site();
+       }
 
        /**
-        * Returns the paths as associative array.
-        * The keys are path types, the values are the path urls.
+        * @see Serializable::serialize
         *
         * @since 1.21
         *
-        * @return array of string
+        * @return string
         */
-       public function getAllPaths();
+       public function serialize() {
+               $fields = array(
+                       'globalid' => $this->globalId,
+                       'type' => $this->type,
+                       'group' => $this->group,
+                       'source' => $this->source,
+                       'language' => $this->languageCode,
+                       'localids' => $this->localIds,
+                       'config' => $this->extraConfig,
+                       'data' => $this->extraData,
+                       'forward' => $this->forward,
+                       'internalid' => $this->internalId,
+
+               );
+
+               return serialize( $fields );
+       }
 
        /**
-        * Removes the path of the provided type if it's set.
+        * @see Serializable::unserialize
         *
         * @since 1.21
         *
-        * @param string $pathType
+        * @param string $serialized
         */
-       public function removePath( $pathType );
+       public function unserialize( $serialized ) {
+               $fields = unserialize( $serialized );
+
+               $this->__construct( $fields['type'] );
+
+               $this->setGlobalId( $fields['globalid'] );
+               $this->setGroup( $fields['group'] );
+               $this->setSource( $fields['source'] );
+               $this->setLanguageCode( $fields['language'] );
+               $this->localIds = $fields['localids'];
+               $this->setExtraConfig( $fields['config'] );
+               $this->setExtraData( $fields['data'] );
+               $this->setForward( $fields['forward'] );
+               $this->setInternalId( $fields['internalid'] );
+       }
 
-}
\ No newline at end of file
+}
+
+/**
+ * @deprecated
+ */
+class SiteObject extends Site {}
diff --git a/includes/site/SiteArray.php b/includes/site/SiteArray.php
deleted file mode 100644 (file)
index 5d2c86b..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-<?php
-
-/**
- * Implementation of SiteList using GenericArrayObject.
- *
- * 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
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SiteArray extends GenericArrayObject implements SiteList {
-       /**
-        * Update this version number when the SiteArray format
-        * changes in an incompatible way
-        *
-        * @since 1.21
-        *
-        * @var integer
-        */
-       const CACHE_VERSION = 1;
-
-       /**
-        * Version number of the SiteArray format of the currently used object
-        *
-        * @since 1.21
-        *
-        * @var integer
-        */
-       public $cacheVersion = self::CACHE_VERSION;
-
-       /**
-        * Internal site identifiers pointing to their sites offset value.
-        *
-        * @since 1.21
-        *
-        * @var array of integer
-        */
-       protected $byInternalId = array();
-
-       /**
-        * Global site identifiers pointing to their sites offset value.
-        *
-        * @since 1.21
-        *
-        * @var array of string
-        */
-       protected $byGlobalId = array();
-
-       /**
-        * @see GenericArrayObject::getObjectType
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getObjectType() {
-               return 'Site';
-       }
-
-       /**
-        * @see GenericArrayObject::preSetElement
-        *
-        * @since 1.21
-        *
-        * @param int|string $index
-        * @param Site $site
-        *
-        * @return boolean
-        */
-       protected function preSetElement( $index, $site ) {
-               if ( $this->hasSite( $site->getGlobalId() ) ) {
-                       $this->removeSite( $site->getGlobalId() );
-               }
-
-               $this->byGlobalId[$site->getGlobalId()] = $index;
-               $this->byInternalId[$site->getInternalId()] = $index;
-
-               return true;
-       }
-
-       /**
-        * @see ArrayObject::offsetUnset()
-        *
-        * @since 1.21
-        *
-        * @param mixed $index
-        */
-       public function offsetUnset( $index ) {
-               if ( $this->offsetExists( $index ) ) {
-                       /**
-                        * @var Site $site
-                        */
-                       $site = $this->offsetGet( $index );
-
-                       unset( $this->byGlobalId[$site->getGlobalId()] );
-                       unset( $this->byInternalId[$site->getInternalId()] );
-               }
-
-               parent::offsetUnset( $index );
-       }
-
-       /**
-        * @see SiteList::getGlobalIdentifiers
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       public function getGlobalIdentifiers() {
-               return array_keys( $this->byGlobalId );
-       }
-
-       /**
-        * @see SiteList::hasSite
-        *
-        * @param string $globalSiteId
-        *
-        * @return boolean
-        */
-       public function hasSite( $globalSiteId ) {
-               return array_key_exists( $globalSiteId, $this->byGlobalId );
-       }
-
-       /**
-        * @see SiteList::getSite
-        *
-        * @since 1.21
-        *
-        * @param string $globalSiteId
-        *
-        * @return Site
-        */
-       public function getSite( $globalSiteId ) {
-               return $this->offsetGet( $this->byGlobalId[$globalSiteId] );
-       }
-
-       /**
-        * @see SiteList::removeSite
-        *
-        * @since 1.21
-        *
-        * @param string $globalSiteId
-        */
-       public function removeSite( $globalSiteId ) {
-               $this->offsetUnset( $this->byGlobalId[$globalSiteId] );
-       }
-
-       /**
-        * @see SiteList::isEmpty
-        *
-        * @since 1.21
-        *
-        * @return boolean
-        */
-       public function isEmpty() {
-               return $this->byGlobalId === array();
-       }
-
-       /**
-        * @see SiteList::hasInternalId
-        *
-        * @param integer $id
-        *
-        * @return boolean
-        */
-       public function hasInternalId( $id ) {
-               return array_key_exists( $id, $this->byInternalId );
-       }
-
-       /**
-        * @see SiteList::getSiteByInternalId
-        *
-        * @since 1.21
-        *
-        * @param integer $id
-        *
-        * @return Site
-        */
-       public function getSiteByInternalId( $id ) {
-               return $this->offsetGet( $this->byInternalId[$id] );
-       }
-
-       /**
-        * @see SiteList::removeSiteByInternalId
-        *
-        * @since 1.21
-        *
-        * @param integer $id
-        */
-       public function removeSiteByInternalId( $id ) {
-               $this->offsetUnset( $this->byInternalId[$id] );
-       }
-
-       /**
-        * @see SiteList::setSite
-        *
-        * @since 1.21
-        *
-        * @param Site $site
-        */
-       public function setSite( Site $site ) {
-               $this[] = $site;
-       }
-
-       /**
-        * @see GenericArrayObject::getSerializationData
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       protected function getSerializationData() {
-               return array_merge(
-                       parent::getSerializationData(),
-                       array(
-                               'cacheVersion' => self::CACHE_VERSION,
-                               'internalIds' => $this->byInternalId,
-                               'globalIds' => $this->byGlobalId,
-                       )
-               );
-       }
-
-       /**
-        * @see GenericArrayObject::unserialize
-        *
-        * @since 1.21
-        *
-        * @param string $serialization
-        *
-        * @return array
-        */
-       public function unserialize( $serialization ) {
-               $serializationData = parent::unserialize( $serialization );
-
-               $this->cacheVersion = $serializationData['cacheVersion'];
-               $this->byInternalId = $serializationData['internalIds'];
-               $this->byGlobalId = $serializationData['globalIds'];
-
-               return $serializationData;
-       }
-
-}
index 6273364..b0d1f95 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Interface for lists of Site objects.
+ * Collection of Site 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
  * @license GNU GPL v2+
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
-interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
+class SiteList extends GenericArrayObject {
+
+       /**
+        * Internal site identifiers pointing to their sites offset value.
+        *
+        * @since 1.21
+        *
+        * @var array of integer
+        */
+       protected $byInternalId = array();
+
+       /**
+        * Global site identifiers pointing to their sites offset value.
+        *
+        * @since 1.21
+        *
+        * @var array of string
+        */
+       protected $byGlobalId = array();
+
+       /**
+        * @see GenericArrayObject::getObjectType
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getObjectType() {
+               return 'Site';
+       }
+
+       /**
+        * @see GenericArrayObject::preSetElement
+        *
+        * @since 1.21
+        *
+        * @param int|string $index
+        * @param Site $site
+        *
+        * @return boolean
+        */
+       protected function preSetElement( $index, $site ) {
+               if ( $this->hasSite( $site->getGlobalId() ) ) {
+                       $this->removeSite( $site->getGlobalId() );
+               }
+
+               $this->byGlobalId[$site->getGlobalId()] = $index;
+               $this->byInternalId[$site->getInternalId()] = $index;
+
+               return true;
+       }
+
+       /**
+        * @see ArrayObject::offsetUnset()
+        *
+        * @since 1.21
+        *
+        * @param mixed $index
+        */
+       public function offsetUnset( $index ) {
+               if ( $this->offsetExists( $index ) ) {
+                       /**
+                        * @var Site $site
+                        */
+                       $site = $this->offsetGet( $index );
+
+                       unset( $this->byGlobalId[$site->getGlobalId()] );
+                       unset( $this->byInternalId[$site->getInternalId()] );
+               }
+
+               parent::offsetUnset( $index );
+       }
 
        /**
         * Returns all the global site identifiers.
@@ -36,7 +107,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return array
         */
-       public function getGlobalIdentifiers();
+       public function getGlobalIdentifiers() {
+               return array_keys( $this->byGlobalId );
+       }
 
        /**
         * Returns if the list contains the site with the provided global site identifier.
@@ -45,7 +118,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return boolean
         */
-       public function hasSite( $globalSiteId );
+       public function hasSite( $globalSiteId ) {
+               return array_key_exists( $globalSiteId, $this->byGlobalId );
+       }
 
        /**
         * Returns the Site with the provided global site identifier.
@@ -57,7 +132,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return Site
         */
-       public function getSite( $globalSiteId );
+       public function getSite( $globalSiteId ) {
+               return $this->offsetGet( $this->byGlobalId[$globalSiteId] );
+       }
 
        /**
         * Removes the site with the specified global site identifier.
@@ -67,7 +144,20 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @param string $globalSiteId
         */
-       public function removeSite( $globalSiteId );
+       public function removeSite( $globalSiteId ) {
+               $this->offsetUnset( $this->byGlobalId[$globalSiteId] );
+       }
+
+       /**
+        * Returns if the list contains no sites.
+        *
+        * @since 1.21
+        *
+        * @return boolean
+        */
+       public function isEmpty() {
+               return $this->byGlobalId === array();
+       }
 
        /**
         * Returns if the list contains the site with the provided site id.
@@ -76,7 +166,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return boolean
         */
-       public function hasInternalId( $id );
+       public function hasInternalId( $id ) {
+               return array_key_exists( $id, $this->byInternalId );
+       }
 
        /**
         * Returns the Site with the provided site id.
@@ -88,7 +180,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return Site
         */
-       public function getSiteByInternalId( $id );
+       public function getSiteByInternalId( $id ) {
+               return $this->offsetGet( $this->byInternalId[$id] );
+       }
 
        /**
         * Removes the site with the specified site id.
@@ -98,7 +192,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @param integer $id
         */
-       public function removeSiteByInternalId( $id );
+       public function removeSiteByInternalId( $id ) {
+               $this->offsetUnset( $this->byInternalId[$id] );
+       }
 
        /**
         * Sets a site in the list. If the site was not there,
@@ -108,15 +204,97 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @param Site $site
         */
-       public function setSite( Site $site );
+       public function setSite( Site $site ) {
+               $this[] = $site;
+       }
 
        /**
-        * Returns if the site list contains no sites.
+        * Returns the sites that are in the provided group.
         *
         * @since 1.21
         *
-        * @return boolean
+        * @param string $groupName
+        *
+        * @return SiteList
+        */
+       public function getGroup( $groupName ) {
+               $group = new self();
+
+               /**
+                * @var \Site $site
+                */
+               foreach ( $this as $site ) {
+                       if ( $site->getGroup() === $groupName ) {
+                               $group[] = $site;
+                       }
+               }
+
+               return $group;
+       }
+
+       /**
+        * A version ID that identifies the serialization structure used by getSerializationData()
+        * and unserialize(). This is useful for constructing cache keys in cases where the cache relies
+        * on serialization for storing the SiteList.
+        *
+        * @var string A string uniquely identifying the version of the serialization structure,
+        *             not including any sub-structures.
+        */
+       const SERIAL_VERSION_ID = '2013-02-07';
+
+       /**
+        * Returns the version ID that identifies the serialization structure used by
+        * getSerializationData() and unserialize(), including the structure of any nested structures.
+        * This is useful for constructing cache keys in cases where the cache relies
+        * on serialization for storing the SiteList.
+        *
+        * @return string A string uniquely identifying the version of the serialization structure,
+        *                including any sub-structures.
+        */
+       public static function getSerialVersionId() {
+               return self::SERIAL_VERSION_ID . '+Site:' . Site::SERIAL_VERSION_ID;
+       }
+
+       /**
+        * @see GenericArrayObject::getSerializationData
+        *
+        * @since 1.21
+        *
+        * @return array
         */
-       public function isEmpty();
+       protected function getSerializationData() {
+               //NOTE: When changing the structure, either implement unserialize() to handle the
+               //      old structure too, or update SERIAL_VERSION_ID to kill any caches.
+               return array_merge(
+                       parent::getSerializationData(),
+                       array(
+                               'internalIds' => $this->byInternalId,
+                               'globalIds' => $this->byGlobalId,
+                       )
+               );
+       }
 
-}
\ No newline at end of file
+       /**
+        * @see GenericArrayObject::unserialize
+        *
+        * @since 1.21
+        *
+        * @param string $serialization
+        *
+        * @return array
+        */
+       public function unserialize( $serialization ) {
+               $serializationData = parent::unserialize( $serialization );
+
+               $this->byInternalId = $serializationData['internalIds'];
+               $this->byGlobalId = $serializationData['globalIds'];
+
+               return $serializationData;
+       }
+
+}
+
+/**
+ * @deprecated
+ */
+class SiteArray extends SiteList {}
diff --git a/includes/site/SiteObject.php b/includes/site/SiteObject.php
deleted file mode 100644 (file)
index 217f860..0000000
+++ /dev/null
@@ -1,570 +0,0 @@
-<?php
-
-/**
- * Class representing a single site.
- *
- * 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
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- * @author Daniel Werner
- */
-class SiteObject extends ORMRow implements Site {
-
-       const PATH_LINK = 'link';
-
-       /**
-        * Holds the local ids for this site.
-        * You can obtain them via @see getLocalIds
-        *
-        * @since 1.21
-        *
-        * @var array|false
-        */
-       protected $localIds = false;
-
-       /**
-        * @see Site::getGlobalId
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getGlobalId() {
-               return $this->getField( 'global_key' );
-       }
-
-       /**
-        * @see Site::setGlobalId
-        *
-        * @since 1.21
-        *
-        * @param string $globalId
-        */
-       public function setGlobalId( $globalId ) {
-               $this->setField( 'global_key', $globalId );
-       }
-
-       /**
-        * @see Site::getType
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getType() {
-               return $this->getField( 'type' );
-       }
-
-       /**
-        * @see Site::setType
-        *
-        * @since 1.21
-        *
-        * @param string $type
-        */
-       public function setType( $type ) {
-               $this->setField( 'type', $type );
-       }
-
-       /**
-        * @see Site::getGroup
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getGroup() {
-               return $this->getField( 'group' );
-       }
-
-       /**
-        * @see Site::setGroup
-        *
-        * @since 1.21
-        *
-        * @param string $group
-        */
-       public function setGroup( $group ) {
-               $this->setField( 'group', $group );
-       }
-
-       /**
-        * @see Site::getSource
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getSource() {
-               return $this->getField( 'source' );
-       }
-
-       /**
-        * @see Site::setSource
-        *
-        * @since 1.21
-        *
-        * @param string $source
-        */
-       public function setSource( $source ) {
-               $this->setField( 'source', $source );
-       }
-
-       /**
-        * @see Site::getDomain
-        *
-        * @since 1.21
-        *
-        * @return string|false
-        */
-       public function getDomain() {
-               $path = $this->getLinkPath();
-
-               if ( $path === false ) {
-                       return false;
-               }
-
-               return parse_url( $path, PHP_URL_HOST );
-       }
-
-       /**
-        * @see Site::getProtocol
-        *
-        * @since 1.21
-        *
-        * @throws MWException
-        * @return string|false
-        */
-       public function getProtocol() {
-               $path = $this->getLinkPath();
-
-               if ( $path === false ) {
-                       return '';
-               }
-
-               $protocol = parse_url( $path, PHP_URL_SCHEME );
-
-               // Malformed URL
-               if ( $protocol === false ) {
-                       throw new MWException( "failed to parse URL $path" );
-               }
-
-               // No schema
-               if ( $protocol === null ) {
-                       // Used for protocol relative URLs
-                       $protocol = '';
-               }
-
-               return $protocol;
-       }
-
-       /**
-        * Sets the path used to construct links with.
-        * @see Site::setLinkPath
-        *
-        * @param string $fullUrl
-        *
-        * @since 1.21
-        *
-        * @throws MWException
-        */
-       public function setLinkPath( $fullUrl ) {
-               $type = $this->getLinkPathType();
-
-               if ( $type === false ) {
-                       throw new MWException( "This SiteObject does not support link paths." );
-               }
-
-               $this->setPath( $type, $fullUrl );
-       }
-
-       /**
-        * Returns the path path used to construct links with or false if there is no such path.
-        *
-        * @see Site::getLinkPath
-        *
-        * @return string|false
-        */
-       public function getLinkPath() {
-               $type = $this->getLinkPathType();
-               return $type === false ? false : $this->getPath( $type );
-       }
-
-       /**
-        * @see Site::getLinkPathType
-        *
-        * Returns the main path type, that is the type of the path that should generally be used to construct links
-        * to the target site.
-        *
-        * This default implementation returns SiteObject::PATH_LINK as the default path type. Subclasses can override this
-        * to define a different default path type, or return false to disable site links.
-        *
-        * @since 1.21
-        *
-        * @return string|false
-        */
-       public function getLinkPathType() {
-               return self::PATH_LINK;
-       }
-
-       /**
-        * @see Site::getPageUrl
-        *
-        * This implementation returns a URL constructed using the path returned by getLinkPath().
-        *
-        * @since 1.21
-        *
-        * @param bool|String $pageName
-        *
-        * @return string|false
-        */
-       public function getPageUrl( $pageName = false ) {
-               $url = $this->getLinkPath();
-
-               if ( $url === false ) {
-                       return false;
-               }
-
-               if ( $pageName !== false ) {
-                       $url = str_replace( '$1', rawurlencode( $pageName ), $url ) ;
-               }
-
-               return $url;
-       }
-
-       /**
-        * Returns $pageName without changes.
-        * Subclasses may override this to apply some kind of normalization.
-        *
-        * @see Site::normalizePageName
-        *
-        * @since 1.21
-        *
-        * @param string $pageName
-        *
-        * @return string
-        */
-       public function normalizePageName( $pageName ) {
-               return $pageName;
-       }
-
-       /**
-        * Returns the value of a type specific field, or the value
-        * of the $default parameter in case it's not set.
-        *
-        * @since 1.21
-        *
-        * @param string $fieldName
-        * @param mixed $default
-        *
-        * @return array
-        */
-       protected function getExtraData( $fieldName, $default = null ) {
-               $data = $this->getField( 'data', array() );
-               return array_key_exists( $fieldName,$data ) ? $data[$fieldName] : $default;
-       }
-
-       /**
-        * Sets the value of a type specific field.
-        * @since 1.21
-        *
-        * @param string $fieldName
-        * @param mixed $value
-        */
-       protected function setExtraData( $fieldName, $value = null ) {
-               $data = $this->getField( 'data', array() );
-               $data[$fieldName] = $value;
-               $this->setField( 'data', $data );
-       }
-
-       /**
-        * @see Site::getLanguageCode
-        *
-        * @since 1.21
-        *
-        * @return string|false
-        */
-       public function getLanguageCode() {
-               return $this->getField( 'language', false );
-       }
-
-       /**
-        * @see Site::setLanguageCode
-        *
-        * @since 1.21
-        *
-        * @param string $languageCode
-        */
-       public function setLanguageCode( $languageCode ) {
-               $this->setField( 'language', $languageCode );
-       }
-
-       /**
-        * Returns the local identifiers of this site.
-        *
-        * @since 1.21
-        *
-        * @param string $type
-        *
-        * @return array
-        */
-       protected function getLocalIds( $type ) {
-               if ( $this->localIds === false ) {
-                       $this->loadLocalIds();
-               }
-
-               return array_key_exists( $type, $this->localIds ) ? $this->localIds[$type] : array();
-       }
-
-       /**
-        * Loads the local ids for the site.
-        *
-        * @since 1.21
-        */
-       protected function loadLocalIds() {
-               $dbr = wfGetDB( $this->getTable()->getReadDb() );
-
-               $ids = $dbr->select(
-                       'site_identifiers',
-                       array(
-                               'si_type',
-                               'si_key',
-                       ),
-                       array(
-                               'si_site' => $this->getId(),
-                       ),
-                       __METHOD__
-               );
-
-               $this->localIds = array();
-
-               foreach ( $ids as $id ) {
-                       $this->addLocalId( $id->si_type, $id->si_key );
-               }
-       }
-
-       /**
-        * Adds a local identifier.
-        *
-        * @since 1.21
-        *
-        * @param string $type
-        * @param string $identifier
-        */
-       public function addLocalId( $type, $identifier ) {
-               if ( $this->localIds === false ) {
-                       $this->localIds = array();
-               }
-
-               if ( !array_key_exists( $type, $this->localIds ) ) {
-                       $this->localIds[$type] = array();
-               }
-
-               if ( !in_array( $identifier, $this->localIds[$type] ) ) {
-                       $this->localIds[$type][] = $identifier;
-               }
-       }
-
-       /**
-        * @see Site::addInterwikiId
-        *
-        * @since 1.21
-        *
-        * @param string $identifier
-        */
-       public function addInterwikiId( $identifier ) {
-               $this->addLocalId( 'interwiki', $identifier );
-       }
-
-       /**
-        * @see Site::addNavigationId
-        *
-        * @since 1.21
-        *
-        * @param string $identifier
-        */
-       public function addNavigationId( $identifier ) {
-               $this->addLocalId( 'equivalent', $identifier );
-       }
-
-       /**
-        * @see Site::getInterwikiIds
-        *
-        * @since 1.21
-        *
-        * @return array of string
-        */
-       public function getInterwikiIds() {
-               return $this->getLocalIds( 'interwiki' );
-       }
-
-       /**
-        * @see Site::getNavigationIds
-        *
-        * @since 1.21
-        *
-        * @return array of string
-        */
-       public function getNavigationIds() {
-               return $this->getLocalIds( 'equivalent' );
-       }
-
-       /**
-        * @see Site::getInternalId
-        *
-        * @since 1.21
-        *
-        * @return integer
-        */
-       public function getInternalId() {
-               return $this->getId();
-       }
-
-       /**
-        * @see IORMRow::save
-        * @see Site::save
-        *
-        * @since 1.21
-        *
-        * @param string|null $functionName
-        *
-        * @return boolean Success indicator
-        */
-       public function save( $functionName = null ) {
-               $dbw = $this->table->getWriteDbConnection();
-
-               $trx = $dbw->trxLevel();
-
-               if ( $trx == 0 ) {
-                       $dbw->begin( __METHOD__ );
-               }
-
-               $this->setField( 'protocol', $this->getProtocol() );
-               $this->setField( 'domain', strrev( $this->getDomain() ) . '.' );
-
-               $existedAlready = $this->hasIdField();
-
-               $success = parent::save( $functionName );
-
-               if ( $success && $existedAlready ) {
-                       $dbw->delete(
-                               'site_identifiers',
-                               array( 'si_site' => $this->getId() ),
-                               __METHOD__
-                       );
-               }
-
-               if ( $success && $this->localIds !== false ) {
-                       foreach ( $this->localIds as $type => $ids ) {
-                               foreach ( $ids as $id ) {
-                                       $dbw->insert(
-                                               'site_identifiers',
-                                               array(
-                                                       'si_site' => $this->getId(),
-                                                       'si_type' => $type,
-                                                       'si_key' => $id,
-                                               ),
-                                               __METHOD__
-                                       );
-                               }
-                       }
-               }
-
-               if ( $trx == 0 ) {
-                       $dbw->commit( __METHOD__ );
-               }
-
-               return $success;
-       }
-
-       /**
-        * @since 1.21
-        *
-        * @see ORMRow::onRemoved
-        */
-       protected function onRemoved() {
-               $dbw = $this->table->getWriteDbConnection();
-
-               $dbw->delete(
-                       'site_identifiers',
-                       array(
-                               'si_site' => $this->getId()
-                       ),
-                       __METHOD__
-               );
-
-               parent::onRemoved();
-       }
-
-       /**
-        * @see Site::setPath
-        *
-        * @since 1.21
-        *
-        * @param string $pathType
-        * @param string $fullUrl
-        */
-       public function setPath( $pathType, $fullUrl ) {
-               $paths = $this->getExtraData( 'paths', array() );
-               $paths[$pathType] = $fullUrl;
-               $this->setExtraData( 'paths', $paths );
-       }
-
-       /**
-        * @see Sitres::getPath
-        *
-        * @since 1.21
-        *
-        * @param string $pathType
-        *
-        * @return string|false
-        */
-       public function getPath( $pathType ) {
-               $paths = $this->getExtraData( 'paths', array() );
-               return array_key_exists( $pathType, $paths ) ? $paths[$pathType] : false;
-       }
-
-       /**
-        * @see Sitres::getAll
-        *
-        * @since 1.21
-        *
-        * @return array of string
-        */
-       public function getAllPaths() {
-               return $this->getExtraData( 'paths', array() );
-       }
-
-       /**
-        * @see Sitres::removePath
-        *
-        * @since 1.21
-        *
-        * @param string $pathType
-        */
-       public function removePath( $pathType ) {
-               $paths = $this->getExtraData( 'paths', array() );
-               unset( $paths[$pathType] );
-               $this->setExtraData( 'paths', $paths );
-       }
-
-}
diff --git a/includes/site/SiteSQLStore.php b/includes/site/SiteSQLStore.php
new file mode 100644 (file)
index 0000000..4123805
--- /dev/null
@@ -0,0 +1,491 @@
+<?php
+
+/**
+ * Represents the site configuration of a wiki.
+ * Holds a list of sites (ie SiteList) and takes care
+ * of retrieving and caching site information when appropriate.
+ *
+ * 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @license GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteSQLStore implements SiteStore {
+
+       /**
+        * @since 1.21
+        *
+        * @var SiteList|null
+        */
+       protected $sites = null;
+
+       /**
+        * @var ORMTable
+        */
+       protected $sitesTable;
+
+       /**
+        * @var string|null
+        */
+       private $cacheKey = null;
+
+       /**
+        * @var int
+        */
+       private $cacheTimeout = 3600;
+
+       /**
+        * @since 1.21
+        *
+        * @param ORMTable|null $sitesTable
+        *
+        * @return SiteStore
+        */
+       public static function newInstance( ORMTable $sitesTable = null ) {
+               return new static( $sitesTable );
+       }
+
+       /**
+        * Constructor.
+        *
+        * @since 1.21
+        *
+        * @param ORMTable|null $sitesTable
+        */
+       protected function __construct( ORMTable $sitesTable = null ) {
+               if ( $sitesTable === null ) {
+                       $sitesTable = $this->newSitesTable();
+               }
+
+               $this->sitesTable = $sitesTable;
+       }
+
+       /**
+        * Constructs a cache key to use for caching the list of sites.
+        *
+        * This includes the concrete class name of the site list as well as a version identifier
+        * for the list's serialization, to avoid problems when unserializing site lists serialized
+        * by an older version, e.g. when reading from a cache.
+        *
+        * The cache key also includes information about where the sites were loaded from, e.g.
+        * the name of a database table.
+        *
+        * @see SiteList::getSerialVersionId
+        *
+        * @return String The cache key.
+        */
+       protected function getCacheKey() {
+               wfProfileIn( __METHOD__ );
+
+               if ( $this->cacheKey === null ) {
+                       $type = 'SiteList#' . SiteList::getSerialVersionId();
+                       $source = $this->sitesTable->getName();
+
+                       if ( $this->sitesTable->getTargetWiki() !== false ) {
+                               $source = $this->sitesTable->getTargetWiki() . '.' . $source;
+                       }
+
+                       $this->cacheKey = wfMemcKey( "$source/$type" );
+               }
+
+               wfProfileOut( __METHOD__ );
+               return $this->cacheKey;
+       }
+
+       /**
+        * @see SiteStore::getSites
+        *
+        * @since 1.21
+        *
+        * @param string $source either 'cache' or 'recache'
+        *
+        * @return SiteList
+        */
+       public function getSites( $source = 'cache' ) {
+               wfProfileIn( __METHOD__ );
+
+               if ( $source === 'cache' ) {
+                       if ( $this->sites === null ) {
+                               $cache = wfGetMainCache();
+                               $sites = $cache->get( $this->getCacheKey() );
+
+                               if ( is_object( $sites ) ) {
+                                       $this->sites = $sites;
+                               } else {
+                                       $this->loadSites();
+                               }
+                       }
+               }
+               else {
+                       $this->loadSites();
+               }
+
+               wfProfileOut( __METHOD__ );
+               return $this->sites;
+       }
+
+       /**
+        * Returns a new Site object constructed from the provided ORMRow.
+        *
+        * @since 1.21
+        *
+        * @param ORMRow $siteRow
+        *
+        * @return Site
+        */
+       protected function siteFromRow( ORMRow $siteRow ) {
+               wfProfileIn( __METHOD__ );
+
+               $site = Site::newForType( $siteRow->getField( 'type', Site::TYPE_UNKNOWN ) );
+
+               $site->setGlobalId( $siteRow->getField( 'global_key' ) );
+
+               $site->setInternalId( $siteRow->getField( 'id' ) );
+
+               if ( $siteRow->hasField( 'forward' ) ) {
+                       $site->setForward( $siteRow->getField( 'forward' ) );
+               }
+
+               if ( $siteRow->hasField( 'group' ) ) {
+                       $site->setGroup( $siteRow->getField( 'group' ) );
+               }
+
+               if ( $siteRow->hasField( 'language' ) ) {
+                       $site->setLanguageCode( $siteRow->getField( 'language' ) === '' ? null : $siteRow->getField( 'language' ) );
+               }
+
+               if ( $siteRow->hasField( 'source' ) ) {
+                       $site->setSource( $siteRow->getField( 'source' ) );
+               }
+
+               if ( $siteRow->hasField( 'data' ) ) {
+                       $site->setExtraData( $siteRow->getField( 'data' ) );
+               }
+
+               if ( $siteRow->hasField( 'config' ) ) {
+                       $site->setExtraConfig( $siteRow->getField( 'config' ) );
+               }
+
+               wfProfileOut( __METHOD__ );
+               return $site;
+       }
+
+       /**
+        * Fetches the site from the database and loads them into the sites field.
+        *
+        * @since 1.21
+        */
+       protected function loadSites() {
+               wfProfileIn( __METHOD__ );
+
+               $this->sites = new SiteList();
+
+               foreach ( $this->sitesTable->select() as $siteRow ) {
+                       $this->sites[] = $this->siteFromRow( $siteRow );
+               }
+
+               // Batch load the local site identifiers.
+               $ids = wfGetDB( $this->sitesTable->getReadDb() )->select(
+                       'site_identifiers',
+                       array(
+                               'si_site',
+                               'si_type',
+                               'si_key',
+                       ),
+                       array(),
+                       __METHOD__
+               );
+
+               foreach ( $ids as $id ) {
+                       if ( $this->sites->hasInternalId( $id->si_site ) ) {
+                               $site = $this->sites->getSiteByInternalId( $id->si_site );
+                               $site->addLocalId( $id->si_type, $id->si_key );
+                               $this->sites->setSite( $site );
+                       }
+               }
+
+               $cache = wfGetMainCache();
+               $cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout );
+
+               wfProfileOut( __METHOD__ );
+       }
+
+       /**
+        * @see SiteStore::getSite
+        *
+        * @since 1.21
+        *
+        * @param string $globalId
+        * @param string $source
+        *
+        * @return Site|null
+        */
+       public function getSite( $globalId, $source = 'cache' ) {
+               wfProfileIn( __METHOD__ );
+
+               $sites = $this->getSites( $source );
+
+               wfProfileOut( __METHOD__ );
+               return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null;
+       }
+
+       /**
+        * @see SiteStore::saveSite
+        *
+        * @since 1.21
+        *
+        * @param Site $site
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSite( Site $site ) {
+               return $this->saveSites( array( $site ) );
+       }
+
+       /**
+        * @see SiteStore::saveSites
+        *
+        * @since 1.21
+        *
+        * @param Site[] $sites
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSites( array $sites ) {
+               wfProfileIn( __METHOD__ );
+
+               if ( empty( $sites ) ) {
+                       wfProfileOut( __METHOD__ );
+                       return true;
+               }
+
+               $dbw = $this->sitesTable->getWriteDbConnection();
+
+               $trx = $dbw->trxLevel();
+
+               if ( $trx == 0 ) {
+                       $dbw->begin( __METHOD__ );
+               }
+
+               $success = true;
+
+               $internalIds = array();
+               $localIds = array();
+
+               foreach ( $sites as $site ) {
+                       $fields = array(
+                               // Site data
+                               'global_key' => $site->getGlobalId(), // TODO: check not null
+                               'type' => $site->getType(),
+                               'group' => $site->getGroup(),
+                               'source' => $site->getSource(),
+                               'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
+                               'protocol' => $site->getProtocol(),
+                               'domain' => strrev( $site->getDomain() ) . '.',
+                               'data' => $site->getExtraData(),
+
+                               // Site config
+                               'forward' => $site->shouldForward(),
+                               'config' => $site->getExtraConfig(),
+                       );
+
+                       if ( $site->getInternalId() !== null ) {
+                               $fields['id'] = $site->getInternalId();
+                               $internalIds[] = $site->getInternalId();
+                       }
+
+                       $siteRow = new ORMRow( $this->sitesTable, $fields );
+                       $success = $siteRow->save( __METHOD__ ) && $success;
+
+                       foreach ( $site->getLocalIds() as $idType => $ids ) {
+                               foreach ( $ids as $id ) {
+                                       $localIds[] = array( $siteRow->getId(), $idType, $id );
+                               }
+                       }
+               }
+
+               if ( $internalIds !== array() ) {
+                       $dbw->delete(
+                               'site_identifiers',
+                               array( 'si_site' => $internalIds ),
+                               __METHOD__
+                       );
+               }
+
+               foreach ( $localIds as $localId ) {
+                       $dbw->insert(
+                               'site_identifiers',
+                               array(
+                                       'si_site' => $localId[0],
+                                       'si_type' => $localId[1],
+                                       'si_key' => $localId[2],
+                               ),
+                               __METHOD__
+                       );
+               }
+
+               if ( $trx == 0 ) {
+                       $dbw->commit( __METHOD__ );
+               }
+
+               // purge cache
+               $this->reset();
+
+               wfProfileOut( __METHOD__ );
+               return $success;
+       }
+
+       /**
+        * Purges the internal and external cache of the site list, forcing the list
+        * of sites to be re-read from the database.
+        *
+        * @since 1.21
+        */
+       public function reset() {
+               wfProfileIn( __METHOD__ );
+               // purge cache
+               $cache = wfGetMainCache();
+               $cache->delete( $this->getCacheKey() );
+               $this->sites = null;
+
+               wfProfileOut( __METHOD__ );
+       }
+
+       /**
+        * Clears the list of sites stored in the database.
+        *
+        * @see SiteStore::clear()
+        *
+        * @return bool success
+        */
+       public function clear() {
+               wfProfileIn( __METHOD__ );
+               $dbw = $this->sitesTable->getWriteDbConnection();
+
+               $trx = $dbw->trxLevel();
+
+               if ( $trx == 0 ) {
+                       $dbw->begin( __METHOD__ );
+               }
+
+               $ok = $dbw->delete( 'sites', '*', __METHOD__ );
+               $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
+
+               if ( $trx == 0 ) {
+                       $dbw->commit( __METHOD__ );
+               }
+
+               $this->reset();
+
+               wfProfileOut( __METHOD__ );
+               return $ok;
+       }
+
+       /**
+        * @since 1.21
+        *
+        * @return ORMTable
+        */
+       protected function newSitesTable() {
+               return new ORMTable(
+                       'sites',
+                       array(
+                               'id' => 'id',
+
+                               // Site data
+                               'global_key' => 'str',
+                               'type' => 'str',
+                               'group' => 'str',
+                               'source' => 'str',
+                               'language' => 'str',
+                               'protocol' => 'str',
+                               'domain' => 'str',
+                               'data' => 'array',
+
+                               // Site config
+                               'forward' => 'bool',
+                               'config' => 'array',
+                       ),
+                       array(
+                               'type' => Site::TYPE_UNKNOWN,
+                               'group' => Site::GROUP_NONE,
+                               'source' => Site::SOURCE_LOCAL,
+                               'data' => array(),
+
+                               'forward' => false,
+                               'config' => array(),
+                               'language' => '',
+                       ),
+                       'ORMRow',
+                       'site_'
+               );
+       }
+
+}
+
+/**
+ * @deprecated
+ */
+class Sites extends SiteSQLStore {
+
+       /**
+        * Factory for creating new site objects.
+        *
+        * @since 1.21
+        * @deprecated
+        *
+        * @param string|boolean false $globalId
+        *
+        * @return Site
+        */
+       public static function newSite( $globalId = false ) {
+               $site = new Site();
+
+               if ( $globalId !== false ) {
+                       $site->setGlobalId( $globalId );
+               }
+
+               return $site;
+       }
+
+       /**
+        * @deprecated
+        * @return SiteStore
+        */
+       public static function singleton() {
+               static $singleton;
+
+               if ( $singleton === null ) {
+                       $singleton = new static();
+               }
+
+               return $singleton;
+       }
+
+       /**
+        * @deprecated
+        * @return SiteList
+        */
+       public function getSiteGroup( $group ) {
+               return $this->getSites()->getGroup( $group );
+       }
+
+}
diff --git a/includes/site/SiteStore.php b/includes/site/SiteStore.php
new file mode 100644 (file)
index 0000000..52ba8fb
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * Interface for service objects providing a storage interface for Site 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @license GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface SiteStore {
+
+       /**
+        * Saves the provided site.
+        *
+        * @since 1.21
+        *
+        * @param Site $site
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSite( Site $site );
+
+       /**
+        * Saves the provided sites.
+        *
+        * @since 1.21
+        *
+        * @param Site[] $sites
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSites( array $sites );
+
+       /**
+        * Returns the site with provided global id, or null if there is no such site.
+        *
+        * @since 1.21
+        *
+        * @param string $globalId
+        * @param string $source either 'cache' or 'recache'.
+        * If 'cache', the values are allowed (but not obliged) to come from a cache.
+        *
+        * @return Site|null
+        */
+       public function getSite( $globalId, $source = 'cache' );
+
+       /**
+        * Returns a list of all sites. By default this site is
+        * fetched from the cache, which can be changed to loading
+        * the list from the database using the $useCache parameter.
+        *
+        * @since 1.21
+        *
+        * @param string $source either 'cache' or 'recache'.
+        * If 'cache', the values are allowed (but not obliged) to come from a cache.
+        *
+        * @return SiteList
+        */
+       public function getSites( $source = 'cache' );
+
+       /**
+        * Deletes all sites from the database. After calling clear(), getSites() will return an empty
+        * list and getSite() will return null until saveSite() or saveSites() is called.
+        */
+       public function clear();
+}
diff --git a/includes/site/Sites.php b/includes/site/Sites.php
deleted file mode 100644 (file)
index a67d474..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-
-/**
- * Represents the site configuration of a wiki.
- * Holds a list of sites (ie SiteList) and takes care
- * of retrieving and caching site information when appropriate.
- *
- * 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
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class Sites {
-
-       /**
-        * @since 1.21
-        * @var SiteList|null
-        */
-       protected $sites = null;
-
-       /**
-        * Constructor.
-        *
-        * @since 1.21
-        */
-       protected function __construct() {}
-
-       /**
-        * Returns an instance of Sites.
-        *
-        * @since 1.21
-        *
-        * @return Sites
-        */
-       public static function singleton() {
-               static $instance = false;
-
-               if ( $instance === false ) {
-                       $instance = new static();
-               }
-
-               return $instance;
-       }
-
-       /**
-        * Factory for creating new site objects.
-        *
-        * @since 1.21
-        *
-        * @param string|boolean false $globalId
-        *
-        * @return Site
-        */
-       public static function newSite( $globalId = false ) {
-               /**
-                * @var Site $site
-                */
-               $site = SitesTable::singleton()->newRow( array(), true );
-
-               if ( $globalId !== false ) {
-                       $site->setGlobalId( $globalId );
-               }
-
-               return $site;
-       }
-
-       /**
-        * Returns a list of all sites. By default this site is
-        * fetched from the cache, which can be changed to loading
-        * the list from the database using the $useCache parameter.
-        *
-        * @since 1.21
-        *
-        * @param string $source either 'cache' or 'recache'
-        *
-        * @return SiteList
-        */
-       public function getSites( $source = 'cache' ) {
-               if ( $source === 'cache' ) {
-                       if ( $this->sites === null ) {
-                               $cache = wfGetMainCache();
-                               $sites = $cache->get( wfMemcKey( 'SiteList' ) );
-
-                               if ( is_object( $sites ) && isset( $sites->cacheVersion ) && $sites->cacheVersion === SiteArray::CACHE_VERSION ) {
-                                       $this->sites = $sites;
-                               } else {
-                                       $this->loadSites();
-                               }
-                       }
-               }
-               else {
-                       $this->loadSites();
-               }
-
-               return $this->sites;
-       }
-
-       /**
-        * Returns a list of sites in the given group. Calling getGroup() on any of
-        * the sites in the resulting SiteList shall return $group.
-        *
-        * @since 1.21
-        *
-        * @param string $group th group to get.
-        *
-        * @return SiteList
-        */
-       public function getSiteGroup( $group ) {
-               $sites = self::getSites();
-
-               $siteGroup = new SiteArray();
-
-               /* @var Site $site */
-               foreach ( $sites as $site ) {
-                       if ( $site->getGroup() == $group ) {
-                               $siteGroup->append( $site );
-                       }
-               }
-
-               return $siteGroup;
-       }
-
-       /**
-        * Fetches the site from the database and loads them into the sites field.
-        *
-        * @since 1.21
-        */
-       protected function loadSites() {
-               $this->sites = new SiteArray( SitesTable::singleton()->select() );
-
-               // Batch load the local site identifiers.
-               $dbr = wfGetDB( SitesTable::singleton()->getReadDb() );
-
-               $ids = $dbr->select(
-                       'site_identifiers',
-                       array(
-                               'si_site',
-                               'si_type',
-                               'si_key',
-                       ),
-                       array(),
-                       __METHOD__
-               );
-
-               foreach ( $ids as $id ) {
-                       if ( $this->sites->hasInternalId( $id->si_site ) ) {
-                               $site = $this->sites->getSiteByInternalId( $id->si_site );
-                               $site->addLocalId( $id->si_type, $id->si_key );
-                               $this->sites->setSite( $site );
-                       }
-               }
-
-               $cache = wfGetMainCache();
-               $cache->set( wfMemcKey( 'SiteList' ), $this->sites );
-       }
-
-       /**
-        * Returns the site with provided global id, or false if there is no such site.
-        *
-        * @since 1.21
-        *
-        * @param string $globalId
-        * @param string $source
-        *
-        * @return Site|false
-        */
-       public function getSite( $globalId, $source = 'cache' ) {
-               $sites = $this->getSites( $source );
-
-               return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : false;
-       }
-
-}
diff --git a/includes/site/SitesTable.php b/includes/site/SitesTable.php
deleted file mode 100644 (file)
index bb12740..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-/**
- * Represents the sites database table.
- * All access to this table should be done through 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
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SitesTable extends ORMTable {
-
-       /**
-        * @see IORMTable::getName()
-        * @since 1.21
-        * @return string
-        */
-       public function getName() {
-               return 'sites';
-       }
-
-       /**
-        * @see IORMTable::getFieldPrefix()
-        * @since 1.21
-        * @return string
-        */
-       public function getFieldPrefix() {
-               return 'site_';
-       }
-
-       /**
-        * @see IORMTable::getRowClass()
-        * @since 1.21
-        * @return string
-        */
-       public function getRowClass() {
-               return 'SiteObject';
-       }
-
-       /**
-        * @see IORMTable::getFields()
-        * @since 1.21
-        * @return array
-        */
-       public function getFields() {
-               return array(
-                       'id' => 'id',
-
-                       // Site data
-                       'global_key' => 'str',
-                       'type' => 'str',
-                       'group' => 'str',
-                       'source' => 'str',
-                       'language' => 'str',
-                       'protocol' => 'str',
-                       'domain' => 'str',
-                       'data' => 'array',
-
-                       // Site config
-                       'forward' => 'bool',
-                       'config' => 'array',
-               );
-       }
-
-       /**
-        * @see IORMTable::getDefaults()
-        * @since 1.21
-        * @return array
-        */
-       public function getDefaults() {
-               return array(
-                       'type' => Site::TYPE_UNKNOWN,
-                       'group' => Site::GROUP_NONE,
-                       'source' => Site::SOURCE_LOCAL,
-                       'data' => array(),
-
-                       'forward' => false,
-                       'config' => array(),
-                       'language' => 'en', // XXX: can we default to '' instead?
-               );
-       }
-
-       /**
-        * Returns the class name for the provided site type.
-        *
-        * @since 1.21
-        *
-        * @param integer $siteType
-        *
-        * @return string
-        */
-       protected static function getClassForType( $siteType ) {
-               global $wgSiteTypes;
-               return array_key_exists( $siteType, $wgSiteTypes ) ? $wgSiteTypes[$siteType] : 'SiteObject';
-       }
-
-       /**
-        * Factory method to construct a new Site instance.
-        *
-        * @since 1.21
-        *
-        * @param array $data
-        * @param boolean $loadDefaults
-        *
-        * @return Site
-        */
-       public function newRow( array $data, $loadDefaults = false ) {
-               if ( !array_key_exists( 'type', $data ) ) {
-                       $data['type'] = Site::TYPE_UNKNOWN;
-               }
-
-               $class = static::getClassForType( $data['type'] );
-
-               return new $class( $this, $data, $loadDefaults );
-       }
-
-}
\ No newline at end of file
index fe9d41e..5f8a0e4 100644 (file)
@@ -118,7 +118,7 @@ class AllmessagesTablePager extends TablePager {
                $request = $this->getRequest();
 
                $this->filter = $request->getVal( 'filter', 'all' );
-               if( $this->filter === 'all' ){
+               if( $this->filter === 'all' ) {
                        $this->custom = null; // So won't match in either case
                } else {
                        $this->custom = ($this->filter == 'unmodified');
@@ -126,7 +126,7 @@ class AllmessagesTablePager extends TablePager {
 
                $prefix = $this->getLanguage()->ucfirst( $request->getVal( 'prefix', '' ) );
                $prefix = $prefix != '' ? Title::makeTitleSafe( NS_MEDIAWIKI, $request->getVal( 'prefix', null ) ) : null;
-               if( $prefix !== null ){
+               if( $prefix !== null ) {
                        $this->displayPrefix = $prefix->getDBkey();
                        $this->prefix = '/^' . preg_quote( $this->displayPrefix ) . '/i';
                } else {
@@ -150,7 +150,7 @@ class AllmessagesTablePager extends TablePager {
                $msg = wfMessage( 'allmessages-language' );
                $langSelect = Xml::languageSelector( $this->langcode, false, null, $attrs, $msg );
 
-               $out  = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-allmessages-form' ) ) .
+               $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-allmessages-form' ) ) .
                        Xml::fieldset( $this->msg( 'allmessages-filter-legend' )->text() ) .
                        Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
                        Xml::openElement( 'table', array( 'class' => 'mw-allmessages-table' ) ) . "\n" .
@@ -216,7 +216,7 @@ class AllmessagesTablePager extends TablePager {
        function getAllMessages( $descending ) {
                wfProfileIn( __METHOD__ );
                $messageNames = Language::getLocalisationCache()->getSubitemList( 'en', 'messages' );
-               if( $descending ){
+               if( $descending ) {
                        rsort( $messageNames );
                } else {
                        asort( $messageNames );
@@ -331,15 +331,15 @@ class AllmessagesTablePager extends TablePager {
                        </tr></thead><tbody>\n";
        }
 
-       function formatValue( $field, $value ){
-               switch( $field ){
+       function formatValue( $field, $value ) {
+               switch( $field ) {
 
                        case 'am_title' :
 
                                $title = Title::makeTitle( NS_MEDIAWIKI, $value . $this->suffix );
                                $talk  = Title::makeTitle( NS_MEDIAWIKI_TALK, $value . $this->suffix );
 
-                               if( $this->mCurrentRow->am_customised ){
+                               if( $this->mCurrentRow->am_customised ) {
                                        $title = Linker::linkKnown( $title, $this->getLanguage()->lcfirst( $value ) );
                                } else {
                                        $title = Linker::link(
@@ -351,7 +351,7 @@ class AllmessagesTablePager extends TablePager {
                                        );
                                }
                                if ( $this->mCurrentRow->am_talk_exists ) {
-                                       $talk = Linker::linkKnown( $talk , $this->talk );
+                                       $talk = Linker::linkKnown( $talk, $this->talk );
                                } else {
                                        $talk = Linker::link(
                                                $talk,
@@ -370,12 +370,12 @@ class AllmessagesTablePager extends TablePager {
                return '';
        }
 
-       function formatRow( $row ){
+       function formatRow( $row ) {
                // Do all the normal stuff
                $s = parent::formatRow( $row );
 
                // But if there's a customised message, add that too.
-               if( $row->am_customised ){
+               if( $row->am_customised ) {
                        $s .= Xml::openElement( 'tr', $this->getRowAttrs( $row, true ) );
                        $formatted = strval( $this->formatValue( 'am_actual', $row->am_actual ) );
                        if ( $formatted == '' ) {
@@ -387,19 +387,19 @@ class AllmessagesTablePager extends TablePager {
                return $s;
        }
 
-       function getRowAttrs( $row, $isSecond = false ){
+       function getRowAttrs( $row, $isSecond = false ) {
                $arr = array();
-               if( $row->am_customised ){
+               if( $row->am_customised ) {
                        $arr['class'] = 'allmessages-customised';
                }
-               if( !$isSecond ){
+               if( !$isSecond ) {
                        $arr['id'] = Sanitizer::escapeId( 'msg_' . $this->getLanguage()->lcfirst( $row->am_title ) );
                }
                return $arr;
        }
 
-       function getCellAttrs( $field, $value ){
-               if( $this->mCurrentRow->am_customised && $field == 'am_title' ){
+       function getCellAttrs( $field, $value ) {
+               if( $this->mCurrentRow->am_customised && $field == 'am_title' ) {
                        return array( 'rowspan' => '2', 'class' => $field );
                } elseif( $field == 'am_title' ) {
                        return array( 'class' => $field );
@@ -420,16 +420,15 @@ class AllmessagesTablePager extends TablePager {
                return SpecialPage::getTitleFor( 'Allmessages', false );
        }
 
-       function isFieldSortable( $x ){
+       function isFieldSortable( $x ) {
                return false;
        }
 
-       function getDefaultSort(){
+       function getDefaultSort() {
                return '';
        }
 
-       function getQueryInfo(){
+       function getQueryInfo() {
                return '';
        }
 }
-
index 0f8b255..eeda739 100644 (file)
@@ -61,7 +61,7 @@ class SpecialAllpages extends IncludableSpecialPage {
         *
         * @param $name string: name of the special page, as seen in links and URLs (default: 'Allpages')
         */
-       function __construct( $name = 'Allpages' ){
+       function __construct( $name = 'Allpages' ) {
                parent::__construct( $name );
        }
 
@@ -127,7 +127,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                        Xml::label( $this->msg( 'allpagesfrom' )->text(), 'nsfrom' ) .
                        "       </td>
        <td class='mw-input'>" .
-                       Xml::input( 'from', 30, str_replace('_',' ',$from), array( 'id' => 'nsfrom' ) ) .
+                       Xml::input( 'from', 30, str_replace( '_', ' ', $from ), array( 'id' => 'nsfrom' ) ) .
                        "       </td>
 </tr>
 <tr>
@@ -135,7 +135,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                        Xml::label( $this->msg( 'allpagesto' )->text(), 'nsto' ) .
                        "       </td>
                        <td class='mw-input'>" .
-                       Xml::input( 'to', 30, str_replace('_',' ',$to), array( 'id' => 'nsto' ) ) .
+                       Xml::input( 'to', 30, str_replace( '_', ' ', $to ), array( 'id' => 'nsto' ) ) .
                        "               </td>
 </tr>
 <tr>
@@ -180,7 +180,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                $where = array( 'page_namespace' => $namespace );
 
                if ( $hideredirects ) {
-                       $where[ 'page_is_redirect' ] = 0;
+                       $where['page_is_redirect'] = 0;
                }
 
                $from = Title::makeTitleSafe( $namespace, $from );
@@ -188,18 +188,18 @@ class SpecialAllpages extends IncludableSpecialPage {
                $from = ( $from && $from->isLocal() ) ? $from->getDBkey() : null;
                $to = ( $to && $to->isLocal() ) ? $to->getDBkey() : null;
 
-               if( isset($from) )
-                       $where[] = 'page_title >= '.$dbr->addQuotes( $from );
-               if( isset($to) )
-                       $where[] = 'page_title <= '.$dbr->addQuotes( $to );
+               if( isset( $from ) )
+                       $where[] = 'page_title >= ' . $dbr->addQuotes( $from );
+               if( isset( $to ) )
+                       $where[] = 'page_title <= ' . $dbr->addQuotes( $to );
 
                global $wgMemc;
-               $key = wfMemcKey( 'allpages', 'ns', $namespace, $from, $to );
+               $key = wfMemcKey( 'allpages', 'ns', $namespace, sha1( $from ), sha1( $to ) );
                $lines = $wgMemc->get( $key );
 
                $count = $dbr->estimateRowCount( 'page', '*', $where, __METHOD__ );
-               $maxPerSubpage = intval($count/$this->maxLineCount);
-               $maxPerSubpage = max($maxPerSubpage,$this->maxPerPage);
+               $maxPerSubpage = intval( $count / $this->maxLineCount );
+               $maxPerSubpage = max( $maxPerSubpage, $this->maxPerPage );
 
                if( !is_array( $lines ) ) {
                        $options = array( 'LIMIT' => 1 );
@@ -217,9 +217,9 @@ class SpecialAllpages extends IncludableSpecialPage {
                                        : array( 'page_title >= ' . $dbr->addQuotes( $lastTitle ) );
                                $res = $dbr->select( 'page', /* FROM */
                                        'page_title', /* WHAT */
-                                       array_merge($where,$chunk),
+                                       array_merge( $where, $chunk ),
                                        __METHOD__,
-                                       array ('LIMIT' => 2, 'OFFSET' => $maxPerSubpage - 1, 'ORDER BY' => 'page_title ASC')
+                                       array( 'LIMIT' => 2, 'OFFSET' => $maxPerSubpage - 1, 'ORDER BY' => 'page_title ASC' )
                                );
 
                                $s = $dbr->fetchObject( $res );
@@ -228,7 +228,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                                } else {
                                        // Final chunk, but ended prematurely. Go back and find the end.
                                        $endTitle = $dbr->selectField( 'page', 'MAX(page_title)',
-                                               array_merge($where,$chunk),
+                                               array_merge( $where, $chunk ),
                                                __METHOD__ );
                                        array_push( $lines, $endTitle );
                                        $done = true;
@@ -250,7 +250,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                // If there are only two or less sections, don't even display them.
                // Instead, display the first section directly.
                if( count( $lines ) <= 2 ) {
-                       if( !empty($lines) ) {
+                       if( !empty( $lines ) ) {
                                $this->showChunk( $namespace, $from, $to, $hideredirects );
                        } else {
                                $output->addHTML( $this->namespaceForm( $namespace, $from, $to, $hideredirects ) );
@@ -272,7 +272,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                if( $this->including() ) {
                        $out2 = '';
                } else {
-                       if( isset($from) || isset($to) ) {
+                       if( isset( $from ) || isset( $to ) ) {
                                $out2 = Xml::openElement( 'table', array( 'class' => 'mw-allpages-table-form' ) ).
                                                '<tr>
                                                        <td>' .
@@ -311,12 +311,12 @@ class SpecialAllpages extends IncludableSpecialPage {
                $queryparams = $namespace ? "namespace=$namespace&" : '';
 
                $queryhideredirects = array();
-               if ($hideredirects) {
-                       $queryhideredirects[ 'hideredirects' ] = 1;
+               if ( $hideredirects ) {
+                       $queryhideredirects['hideredirects'] = 1;
                }
 
                $special = $this->getTitle();
-               $link = htmlspecialchars( $special->getLocalUrl( $queryparams . 'from=' . urlencode($inpoint) . '&to=' . urlencode($outpoint), $queryhideredirects ) );
+               $link = htmlspecialchars( $special->getLocalUrl( $queryparams . 'from=' . urlencode( $inpoint ) . '&to=' . urlencode( $outpoint ), $queryhideredirects ) );
 
                $out = $this->msg( 'alphaindexline' )->rawParams(
                        "<a href=\"$link\">$inpointf</a></td><td>",
@@ -335,7 +335,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                global $wgContLang;
                $output = $this->getOutput();
 
-               $fromList = $this->getNamespaceKeyAndText($namespace, $from);
+               $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
                $toList = $this->getNamespaceKeyAndText( $namespace, $to );
                $namespaces = $wgContLang->getNamespaces();
                $n = 0;
@@ -357,7 +357,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                        );
 
                        if ( $hideredirects ) {
-                               $conds[ 'page_is_redirect' ] = 0;
+                               $conds['page_is_redirect'] = 0;
                        }
 
                        if( $toKey !== "" ) {
@@ -416,10 +416,10 @@ class SpecialAllpages extends IncludableSpecialPage {
                                $res_prev = $dbr->select(
                                        'page',
                                        'page_title',
-                                       array( 'page_namespace' => $namespace, 'page_title < '.$dbr->addQuotes($from) ),
+                                       array( 'page_namespace' => $namespace, 'page_title < ' . $dbr->addQuotes( $from ) ),
                                        __METHOD__,
                                        array( 'ORDER BY' => 'page_title DESC',
-                                               'LIMIT' => $this->maxPerPage, 'OFFSET' => ($this->maxPerPage - 1 )
+                                               'LIMIT' => $this->maxPerPage, 'OFFSET' => ( $this->maxPerPage - 1 )
                                        )
                                );
 
@@ -438,7 +438,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                                                array( 'page_namespace' => $namespace ), __METHOD__, $options );
                                        # Show the previous link if it s not the current requested chunk
                                        if( $from != $reallyFirstPage_title ) {
-                                               $prevTitle =  Title::makeTitle( $namespace, $reallyFirstPage_title );
+                                               $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title );
                                        } else {
                                                $prevTitle = null;
                                        }
@@ -477,7 +477,7 @@ class SpecialAllpages extends IncludableSpecialPage {
 
                        if( $n == $this->maxPerPage && $s = $res->fetchObject() ) {
                                # $s is the first link of the next chunk
-                               $t = Title::makeTitle($namespace, $s->page_title);
+                               $t = Title::makeTitle( $namespace, $s->page_title );
                                $query = array( 'from' => $t->getText() );
 
                                if( $namespace )
@@ -518,11 +518,11 @@ class SpecialAllpages extends IncludableSpecialPage {
         * @param $text String: the name of the article
         * @return array( int namespace, string dbkey, string pagename ) or NULL on error
         */
-       protected function getNamespaceKeyAndText($ns, $text) {
+       protected function getNamespaceKeyAndText( $ns, $text ) {
                if ( $text == '' )
                        return array( $ns, '', '' ); # shortcut for common case
 
-               $t = Title::makeTitleSafe($ns, $text);
+               $t = Title::makeTitleSafe( $ns, $text );
                if ( $t && $t->isLocal() ) {
                        return array( $t->getNamespace(), $t->getDBkey(), $t->getText() );
                } elseif ( $t ) {
@@ -530,8 +530,8 @@ class SpecialAllpages extends IncludableSpecialPage {
                }
 
                # try again, in case the problem was an empty pagename
-               $text = preg_replace('/(#|$)/', 'X$1', $text);
-               $t = Title::makeTitleSafe($ns, $text);
+               $text = preg_replace( '/(#|$)/', 'X$1', $text );
+               $t = Title::makeTitleSafe( $ns, $text );
                if ( $t && $t->isLocal() ) {
                        return array( $t->getNamespace(), '', '' );
                } else {
index 42d3377..bfa2f95 100644 (file)
@@ -33,6 +33,6 @@ class SpecialBlankpage extends UnlistedSpecialPage {
        }
        public function execute( $par ) {
                $this->setHeaders();
-               $this->getOutput()->addWikiMsg('intentionallyblankpage');
+               $this->getOutput()->addWikiMsg( 'intentionallyblankpage' );
        }
 }
index ec026e8..ac05f67 100644 (file)
@@ -62,7 +62,7 @@ class SpecialBlock extends FormSpecialPage {
         * @throws ErrorPageError
         */
        protected function checkExecutePermissions( User $user ) {
-                parent::checkExecutePermissions( $user );
+               parent::checkExecutePermissions( $user );
 
                # bug 15810: blocked admins should have limited access here
                $status = self::checkUnblockSelf( $this->target, $user );
@@ -134,6 +134,7 @@ class SpecialBlock extends FormSpecialPage {
                                'tabindex' => '1',
                                'id' => 'mw-bi-target',
                                'size' => '45',
+                               'autofocus' => true,
                                'required' => true,
                                'validation-callback' => array( __CLASS__, 'validateTargetField' ),
                        ),
@@ -239,7 +240,7 @@ class SpecialBlock extends FormSpecialPage {
 
                if ( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
                        && ( $this->type != Block::TYPE_RANGE # The block isn't a rangeblock
-                         || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
+                               || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
                        )
                {
                        $fields['HardBlock']['default'] = $block->isHardblock();
@@ -386,7 +387,7 @@ class SpecialBlock extends FormSpecialPage {
                        );
                }
 
-               $text =  Html::rawElement(
+               $text = Html::rawElement(
                        'p',
                        array( 'class' => 'mw-ipb-conveniencelinks' ),
                        $this->getLanguage()->pipeList( $links )
@@ -650,7 +651,7 @@ class SpecialBlock extends FormSpecialPage {
                }
 
                if ( $data['HideUser'] ) {
-                       if ( !$performer->isAllowed('hideuser') ) {
+                       if ( !$performer->isAllowed( 'hideuser' ) ) {
                                # this codepath is unreachable except by a malicious user spoofing forms,
                                # or by race conditions (user has oversight and sysop, loads block form,
                                # and is de-oversighted before submission); so need to fail completely
@@ -769,7 +770,7 @@ class SpecialBlock extends FormSpecialPage {
                        $logParams
                );
                # Relate log ID to block IDs (bug 25763)
-               $blockIds = array_merge( array( $status['id'] ), $status['autoIds']  );
+               $blockIds = array_merge( array( $status['id'] ), $status['autoIds'] );
                $log->addRelations( 'ipb_id', $blockIds, $log_id );
 
                # Report to the user
index d740082..56b9b00 100644 (file)
@@ -113,14 +113,14 @@ class SpecialBlockList extends SpecialPage {
 
                $conds = array();
                # Is the user allowed to see hidden blocks?
-               if ( !$this->getUser()->isAllowed( 'hideuser' ) ){
+               if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
                        $conds['ipb_deleted'] = 0;
                }
 
-               if ( $this->target !== '' ){
+               if ( $this->target !== '' ) {
                        list( $target, $type ) = Block::parseTarget( $this->target );
 
-                       switch( $type ){
+                       switch( $type ) {
                                case Block::TYPE_ID:
                                case Block::TYPE_AUTO:
                                        $conds['ipb_id'] = $target;
@@ -269,11 +269,11 @@ class BlockListPager extends TablePager {
                                break;
 
                        case 'ipb_target':
-                               if( $row->ipb_auto ){
+                               if( $row->ipb_auto ) {
                                        $formatted = $this->msg( 'autoblockid', $row->ipb_id )->parse();
                                } else {
                                        list( $target, $type ) = Block::parseTarget( $row->ipb_address );
-                                       switch( $type ){
+                                       switch( $type ) {
                                                case Block::TYPE_USER:
                                                case Block::TYPE_IP:
                                                        $formatted = Linker::userLink( $target->getId(), $target );
@@ -292,8 +292,8 @@ class BlockListPager extends TablePager {
 
                        case 'ipb_expiry':
                                $formatted = $this->getLanguage()->formatExpiry( $value, /* User preference timezone */ true );
-                               if( $this->getUser()->isAllowed( 'block' ) ){
-                                       if( $row->ipb_auto ){
+                               if( $this->getUser()->isAllowed( 'block' ) ) {
+                                       if( $row->ipb_auto ) {
                                                $links[] = Linker::linkKnown(
                                                        SpecialPage::getTitleFor( 'Unblock' ),
                                                        $msg['unblocklink'],
@@ -391,14 +391,14 @@ class BlockListPager extends TablePager {
                );
 
                # Is the user allowed to see hidden blocks?
-               if ( !$this->getUser()->isAllowed( 'hideuser' ) ){
+               if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
                        $info['conds']['ipb_deleted'] = 0;
                }
 
                return $info;
        }
 
-       public function getTableClass(){
+       public function getTableClass() {
                return 'TablePager mw-blocklist';
        }
 
@@ -418,7 +418,7 @@ class BlockListPager extends TablePager {
         * Do a LinkBatch query to minimise database load when generating all these links
         * @param $result
         */
-       function preprocessResults( $result ){
+       function preprocessResults( $result ) {
                wfProfileIn( __METHOD__ );
                # Do a link batch query
                $lb = new LinkBatch;
@@ -437,7 +437,7 @@ class BlockListPager extends TablePager {
                }
 
                $ua = UserArray::newFromIDs( $userids );
-               foreach( $ua as $user ){
+               foreach( $ua as $user ) {
                        $name = str_replace( ' ', '_', $user->getName() );
                        $lb->add( NS_USER, $name );
                        $lb->add( NS_USER_TALK, $name );
@@ -472,7 +472,7 @@ class HTMLBlockedUsersItemSelect extends HTMLSelectField {
                        // This adds the explicitly requested limit value to the drop-down,
                        // then makes sure it's sorted correctly so when we output the list
                        // later, the custom option doesn't just show up last.
-                       $this->mParams['options'][ $this->mParent->getLanguage()->formatNum( $value ) ] = intval($value);
+                       $this->mParams['options'][$this->mParent->getLanguage()->formatNum( $value )] = intval( $value );
                        asort( $this->mParams['options'] );
                }
 
index 6d27c1b..255b1b6 100644 (file)
@@ -62,7 +62,7 @@ class SpecialBookSources extends SpecialPage {
        }
 
        /**
-        * Returns whether a given ISBN (10 or 13) is valid.  True indicates validity.
+        * Returns whether a given ISBN (10 or 13) is valid. True indicates validity.
         * @param $isbn string ISBN passed for check
         * @return bool
         */
@@ -71,7 +71,7 @@ class SpecialBookSources extends SpecialPage {
                $sum = 0;
                if( strlen( $isbn ) == 13 ) {
                        for( $i = 0; $i < 12; $i++ ) {
-                               if($i % 2 == 0) {
+                               if( $i % 2 == 0 ) {
                                        $sum += $isbn[$i];
                                } else {
                                        $sum += 3 * $isbn[$i];
@@ -79,19 +79,19 @@ class SpecialBookSources extends SpecialPage {
                        }
 
                        $check = (10 - ($sum % 10)) % 10;
-                       if ($check == $isbn[12]) {
+                       if ( $check == $isbn[12] ) {
                                return true;
                        }
                } elseif( strlen( $isbn ) == 10 ) {
-                       for($i = 0; $i < 9; $i++) {
+                       for( $i = 0; $i < 9; $i++ ) {
                                $sum += $isbn[$i] * ($i + 1);
                        }
 
                        $check = $sum % 11;
-                       if($check == 10) {
+                       if( $check == 10 ) {
                                $check = "X";
                        }
-                       if($check == $isbn[9]) {
+                       if( $check == $isbn[9] ) {
                                return true;
                        }
                }
index 97de72a..77b69e8 100644 (file)
@@ -50,6 +50,7 @@ class BrokenRedirectsPage extends QueryPage {
        }
 
        function getQueryInfo() {
+               $dbr = wfGetDB( DB_SLAVE );
                return array(
                        'tables' => array(
                                'redirect',
@@ -68,7 +69,7 @@ class BrokenRedirectsPage extends QueryPage {
                                // but aren't "broken" either.
                                // Special pages and interwiki links
                                'rd_namespace >= 0',
-                               '(rd_interwiki IS NULL OR rd_interwiki = "")',
+                               'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ),
                                'p2.page_namespace IS NULL',
                        ),
                        'join_conds' => array(
index 1232e3f..44388c4 100644 (file)
@@ -72,7 +72,7 @@ class CategoryPager extends AlphabeticPager {
        function getQueryInfo() {
                return array(
                        'tables' => array( 'category' ),
-                       'fields' => array( 'cat_title','cat_pages' ),
+                       'fields' => array( 'cat_title', 'cat_pages' ),
                        'conds' => array( 'cat_pages > 0' ),
                        'options' => array( 'USE INDEX' => 'cat_title' ),
                );
@@ -112,7 +112,7 @@ class CategoryPager extends AlphabeticPager {
                return parent::getBody();
        }
 
-       function formatRow($result) {
+       function formatRow( $result ) {
                $title = Title::makeTitle( NS_CATEGORY, $result->cat_title );
                $titleText = Linker::link( $title, htmlspecialchars( $title->getText() ) );
                $count = $this->msg( 'nmembers' )->numParams( $result->cat_pages )->escaped();
index eae8e3a..53faba7 100644 (file)
@@ -195,7 +195,7 @@ class SpecialChangeEmail extends UnlistedSpecialPage {
                        if ( $type != 'text' ) {
                                $out .= Xml::label( $this->msg( $label )->text(), $name );
                        } else {
-                               $out .=  $this->msg( $label )->escaped();
+                               $out .= $this->msg( $label )->escaped();
                        }
                        $out .= "</td>\n";
                        $out .= "\t<td class='mw-input'>";
index 54a2771..2b505b3 100644 (file)
@@ -73,8 +73,10 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                }
 
                                $this->attemptReset( $this->mNewpass, $this->mRetype );
-                               $this->getOutput()->addWikiMsg( 'resetpass_success' );
-                               if( !$user->isLoggedIn() ) {
+
+                               if( $user->isLoggedIn() ) {
+                                       $this->doReturnTo();
+                               } else {
                                        LoginForm::setLoginToken();
                                        $token = LoginForm::getLoginToken();
                                        $data = array(
@@ -82,17 +84,13 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                                'wpName'       => $this->mUserName,
                                                'wpDomain'     => $this->mDomain,
                                                'wpLoginToken' => $token,
-                                               'wpPassword'   => $this->mNewpass,
-                                               'returnto'     => $request->getVal( 'returnto' ),
-                                       );
-                                       if( $request->getCheck( 'wpRemember' ) ) {
-                                               $data['wpRemember'] = 1;
-                                       }
+                                               'wpPassword'   => $request->getVal( 'wpNewPassword' ),
+                                       ) + $request->getValues( 'wpRemember', 'returnto', 'returntoquery' );
                                        $login = new LoginForm( new FauxRequest( $data, true ) );
                                        $login->setContext( $this->getContext() );
                                        $login->execute( null );
                                }
-                               $this->doReturnTo();
+                               return;
                        } catch( PasswordError $e ) {
                                $this->error( $e->getMessage() );
                        }
@@ -101,18 +99,20 @@ class SpecialChangePassword extends UnlistedSpecialPage {
        }
 
        function doReturnTo() {
-               $titleObj = Title::newFromText( $this->getRequest()->getVal( 'returnto' ) );
+               $request = $this->getRequest();
+               $titleObj = Title::newFromText( $request->getVal( 'returnto' ) );
                if ( !$titleObj instanceof Title ) {
                        $titleObj = Title::newMainPage();
                }
-               $this->getOutput()->redirect( $titleObj->getFullURL() );
+               $query = $request->getVal( 'returntoquery' );
+               $this->getOutput()->redirect( $titleObj->getFullURL( $query ) );
        }
 
        /**
         * @param $msg string
         */
        function error( $msg ) {
-               $this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) );
+               $this->getOutput()->addHTML( Xml::element( 'p', array( 'class' => 'error' ), $msg ) );
        }
 
        function showForm() {
@@ -148,6 +148,15 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                        array( 'wpRetype', 'retypenew', 'password', null ),
                                );
                $prettyFields = array_merge( $prettyFields, $extraFields );
+               $hiddenFields = array(
+                       'token' => $user->getEditToken(),
+                       'wpName' => $this->mUserName,
+                       'wpDomain' => $this->mDomain,
+               ) + $this->getRequest()->getValues( 'returnto', 'returntoquery' );
+               $hiddenFieldsStr = '';
+               foreach( $hiddenFields as $fieldname => $fieldvalue ) {
+                       $hiddenFieldsStr .= Html::hidden( $fieldname, $fieldvalue ) . "\n";
+               }
                $this->getOutput()->addHTML(
                        Xml::fieldset( $this->msg( 'resetpass_header' )->text() ) .
                        Xml::openElement( 'form',
@@ -155,10 +164,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                        'method' => 'post',
                                        'action' => $this->getTitle()->getLocalUrl(),
                                        'id' => 'mw-resetpass-form' ) ) . "\n" .
-                       Html::hidden( 'token', $user->getEditToken() ) . "\n" .
-                       Html::hidden( 'wpName', $this->mUserName ) . "\n" .
-                       Html::hidden( 'wpDomain', $this->mDomain ) . "\n" .
-                       Html::hidden( 'returnto', $this->getRequest()->getVal( 'returnto' ) ) . "\n" .
+                       $hiddenFieldsStr .
                        $this->msg( 'resetpass_text' )->parseAsBlock() . "\n" .
                        Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" .
                        $this->pretty( $prettyFields ) . "\n" .
@@ -202,7 +208,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                        if ( $type != 'text' )
                                $out .= Xml::label( $this->msg( $label )->text(), $name );
                        else
-                               $out .=  $this->msg( $label )->escaped();
+                               $out .= $this->msg( $label )->escaped();
                        $out .= "</td>\n";
                        $out .= "\t<td class='mw-input'>";
                        $out .= $field;
@@ -216,7 +222,13 @@ class SpecialChangePassword extends UnlistedSpecialPage {
         * @throws PasswordError when cannot set the new password because requirements not met.
         */
        protected function attemptReset( $newpass, $retype ) {
-               $user = User::newFromName( $this->mUserName );
+               $isSelf = ( $this->mUserName === $this->getUser()->getName() );
+               if ( $isSelf ) {
+                       $user = $this->getUser();
+               } else {
+                       $user = User::newFromName( $this->mUserName );
+               }
+
                if( !$user || $user->isAnon() ) {
                        throw new PasswordError( $this->msg( 'nosuchusershort', $this->mUserName )->text() );
                }
@@ -231,7 +243,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                        throw new PasswordError( $this->msg( 'login-throttled' )->text() );
                }
 
-               if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) {
+               if( !$user->checkTemporaryPassword( $this->mOldpass ) && !$user->checkPassword( $this->mOldpass ) ) {
                        wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) );
                        throw new PasswordError( $this->msg( 'resetpass-wrong-oldpass' )->text() );
                }
@@ -250,7 +262,12 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                        throw new PasswordError( $e->getMessage() );
                }
 
-               $user->setCookies();
+               if ( $isSelf ) {
+                       // This is needed to keep the user connected since
+                       // changing the password also modifies the user's token.
+                       $user->setCookies();
+               }
+
                $user->saveSettings();
        }
 }
index 2b7036c..8be1cf0 100644 (file)
@@ -106,7 +106,7 @@ class SpecialComparePages extends SpecialPage {
                $form->trySubmit();
        }
 
-       public static function showDiff( $data, HTMLForm $form ){
+       public static function showDiff( $data, HTMLForm $form ) {
                $rev1 = self::revOrTitle( $data['Revision1'], $data['Page1'] );
                $rev2 = self::revOrTitle( $data['Revision2'], $data['Page2'] );
 
@@ -128,11 +128,11 @@ class SpecialComparePages extends SpecialPage {
        }
 
        public static function revOrTitle( $revision, $title ) {
-               if( $revision ){
+               if( $revision ) {
                        return $revision;
                } elseif( $title ) {
                        $title = Title::newFromText( $title );
-                       if( $title instanceof Title ){
+                       if( $title instanceof Title ) {
                                return $title->getLatestRevID();
                        }
                }
index 3e9ce12..85a415d 100644 (file)
@@ -145,9 +145,7 @@ class EmailInvalidation extends UnlistedSpecialPage {
        function execute( $code ) {
                $this->setHeaders();
 
-               if ( wfReadOnly() ) {
-                       throw new ReadOnlyError;
-               }
+               $this->checkReadOnly();
 
                $this->attemptInvalidate( $code );
        }
index f7e316b..d156d20 100644 (file)
@@ -152,7 +152,7 @@ class SpecialContributions extends SpecialPage {
                                $apiParams['month'] = $this->opts['month'];
                        }
 
-                       $url = wfScript( 'api' ) . '?' . wfArrayToCGI( $apiParams );
+                       $url = wfScript( 'api' ) . '?' . wfArrayToCgi( $apiParams );
 
                        $out->redirect( $url, '301' );
                        return;
@@ -360,7 +360,7 @@ class SpecialContributions extends SpecialPage {
                if ( !isset( $this->opts['target'] ) ) {
                        $this->opts['target'] = '';
                } else {
-                       $this->opts['target'] = str_replace( '_' , ' ' , $this->opts['target'] );
+                       $this->opts['target'] = str_replace( '_', ' ', $this->opts['target'] );
                }
 
                if ( !isset( $this->opts['namespace'] ) ) {
@@ -424,7 +424,7 @@ class SpecialContributions extends SpecialPage {
                        Xml::radioLabel(
                                $this->msg( 'sp-contributions-newbies' )->text(),
                                'contribs',
-                               'newbie' ,
+                               'newbie',
                                'newbie',
                                $this->opts['contribs'] == 'newbie',
                                array( 'class' => 'mw-input' )
@@ -445,7 +445,7 @@ class SpecialContributions extends SpecialPage {
                                        ( $this->opts['target'] ? array() : array( 'autofocus' )
                                )
                        ) . ' '
-               ) ;
+               );
 
                $namespaceSelection =
                        Xml::tags( 'td', array( 'class' => 'mw-label' ),
@@ -483,7 +483,7 @@ class SpecialContributions extends SpecialPage {
                                                array( 'title' => $this->msg( 'tooltip-namespace_association' )->text(), 'class' => 'mw-input' )
                                        ) . '&#160;'
                                )
-                       ) ;
+                       );
 
                if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
                        $deletedOnlyCheck = Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
@@ -521,7 +521,7 @@ class SpecialContributions extends SpecialPage {
                                $this->msg( 'sp-contributions-submit' )->text(),
                                array( 'class' => 'mw-submit' )
                        )
-               ) ;
+               );
 
                $form .=
                        Xml::fieldset( $this->msg( 'sp-contributions-search' )->text() ) .
index bdeb7fe..0c934a4 100644 (file)
@@ -168,7 +168,7 @@ class DeletedContribsPager extends IndexPager {
 
                $user = $this->getUser();
 
-               if( $user->isAllowed('deletedtext') ) {
+               if( $user->isAllowed( 'deletedtext' ) ) {
                        $last = Linker::linkKnown(
                                $undelete,
                                $this->messages['diff'],
@@ -475,7 +475,7 @@ class DeletedContributionsPage extends SpecialPage {
                if ( !isset( $options['target'] ) ) {
                        $options['target'] = '';
                } else {
-                       $options['target'] = str_replace( '_' , ' ' , $options['target'] );
+                       $options['target'] = str_replace( '_', ' ', $options['target'] );
                }
 
                if ( !isset( $options['namespace'] ) ) {
@@ -499,7 +499,7 @@ class DeletedContributionsPage extends SpecialPage {
                        $f .= "\t" . Html::hidden( $name, $value ) . "\n";
                }
 
-               $f .=  Xml::openElement( 'fieldset' ) .
+               $f .= Xml::openElement( 'fieldset' ) .
                        Xml::element( 'legend', array(), $this->msg( 'sp-contributions-search' )->text() ) .
                        Xml::tags( 'label', array( 'for' => 'target' ), $this->msg( 'sp-contributions-username' )->parse() ) . ' ' .
                        Html::input( 'target', $options['target'], 'text', array(
index 48180a7..a9c554a 100644 (file)
@@ -59,20 +59,20 @@ class DisambiguationsPage extends QueryPage {
                        if( $dp->getNamespace() != NS_TEMPLATE ) {
                                # @todo FIXME: We assume the disambiguation message is a template but
                                # the page can potentially be from another namespace :/
-                               wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n");
+                               wfDebug( "Mediawiki:disambiguationspage message does not refer to a template!\n" );
                        }
                        $linkBatch->addObj( $dp );
                } else {
                                # Get all the templates linked from the Mediawiki:Disambiguationspage
                                $disPageObj = Title::makeTitleSafe( NS_MEDIAWIKI, 'disambiguationspage' );
                                $res = $dbr->select(
-                                       array('pagelinks', 'page'),
+                                       array( 'pagelinks', 'page' ),
                                        'pl_title',
-                                       array('page_id = pl_from',
+                                       array( 'page_id = pl_from',
                                                'pl_namespace' => NS_TEMPLATE,
                                                'page_namespace' => $disPageObj->getNamespace(),
-                                               'page_title' => $disPageObj->getDBkey()),
-                                       __METHOD__ );
+                                               'page_title' => $disPageObj->getDBkey()
+                                       ), __METHOD__ );
 
                                foreach ( $res as $row ) {
                                        $linkBatch->addObj( Title::makeTitle( NS_TEMPLATE, $row->pl_title ));
index ee07323..512fd85 100644 (file)
@@ -51,6 +51,7 @@ class DoubleRedirectsPage extends QueryPage {
 
        function reallyGetQueryInfo( $namespace = null, $title = null ) {
                $limitToTitle = !( $namespace === null && $title === null );
+               $dbr = wfGetDB( DB_SLAVE );
                $retval = array (
                        'tables' => array (
                                'ra' => 'redirect',
@@ -82,7 +83,7 @@ class DoubleRedirectsPage extends QueryPage {
 
                                // Need to check both NULL and "" for some reason,
                                // apparently either can be stored for non-iw entries.
-                               '(ra.rd_interwiki IS NULL OR ra.rd_interwiki = "")',
+                               'ra.rd_interwiki IS NULL OR ra.rd_interwiki = ' . $dbr->addQuotes( '' ),
 
                                'pb.page_namespace = ra.rd_namespace',
                                'pb.page_title = ra.rd_title',
@@ -117,7 +118,7 @@ class DoubleRedirectsPage extends QueryPage {
                        $dbr = wfGetDB( DB_SLAVE );
                        $qi = $this->reallyGetQueryInfo( $result->namespace,
                                        $result->title );
-                       $res = $dbr->select($qi['tables'], $qi['fields'],
+                       $res = $dbr->select( $qi['tables'], $qi['fields'],
                                        $qi['conds'], __METHOD__ );
                        if ( $res ) {
                                $result = $dbr->fetchObject( $res );
@@ -128,7 +129,7 @@ class DoubleRedirectsPage extends QueryPage {
                }
 
                $titleB = Title::makeTitle( $result->nsb, $result->tb );
-               $titleC = Title::makeTitle( $result->nsc, $result->tc, '',  $result->iwc );
+               $titleC = Title::makeTitle( $result->nsc, $result->tc, '', $result->iwc );
 
                $linkA = Linker::linkKnown(
                        $titleA,
index ae7657c..7e1b44a 100644 (file)
@@ -49,7 +49,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
 
        private $badItems = array();
 
-       public function __construct(){
+       public function __construct() {
                parent::__construct( 'EditWatchlist' );
        }
 
@@ -77,6 +77,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                }
 
                $this->checkPermissions();
+               $this->checkReadOnly();
 
                $this->outputHeader();
 
@@ -85,9 +86,9 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
 
                # B/C: $mode used to be waaay down the parameter list, and the first parameter
                # was $wgUser
-               if( $mode instanceof User ){
+               if( $mode instanceof User ) {
                        $args = func_get_args();
-                       if( count( $args >= 4 ) ){
+                       if( count( $args >= 4 ) ) {
                                $mode = $args[3];
                        }
                }
@@ -101,7 +102,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                        case self::EDIT_RAW:
                                $out->setPageTitle( $this->msg( 'watchlistedit-raw-title' ) );
                                $form = $this->getRawForm();
-                               if( $form->show() ){
+                               if( $form->show() ) {
                                        $out->addHTML( $this->successMessage );
                                        $out->addReturnTo( SpecialPage::getTitleFor( 'Watchlist' ) );
                                }
@@ -111,7 +112,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                        default:
                                $out->setPageTitle( $this->msg( 'watchlistedit-normal-title' ) );
                                $form = $this->getNormalForm();
-                               if( $form->show() ){
+                               if( $form->show() ) {
                                        $out->addHTML( $this->successMessage );
                                        $out->addReturnTo( SpecialPage::getTitleFor( 'Watchlist' ) );
                                } elseif ( $this->toc !== false ) {
@@ -153,7 +154,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                return array_unique( $list );
        }
 
-       public function submitRaw( $data ){
+       public function submitRaw( $data ) {
                $wanted = $this->extractTitles( $data['Titles'] );
                $current = $this->getWatchlist();
 
@@ -164,7 +165,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                        $this->unwatchTitles( $toUnwatch );
                        $this->getUser()->invalidateCache();
 
-                       if( count( $toWatch ) > 0 || count( $toUnwatch ) > 0 ){
+                       if( count( $toWatch ) > 0 || count( $toUnwatch ) > 0 ) {
                                $this->successMessage = $this->msg( 'watchlistedit-raw-done' )->parse();
                        } else {
                                return false;
@@ -185,7 +186,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                        $this->clearWatchlist();
                        $this->getUser()->invalidateCache();
 
-                       if( count( $current ) > 0 ){
+                       if( count( $current ) > 0 ) {
                                $this->successMessage = $this->msg( 'watchlistedit-raw-done' )->parse();
                        } else {
                                return false;
@@ -289,7 +290,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
 
                $res = $dbr->select(
                        array( 'watchlist' ),
-                       array( 'wl_namespace',  'wl_title' ),
+                       array( 'wl_namespace', 'wl_title' ),
                        array( 'wl_user' => $this->getUser()->getId() ),
                        __METHOD__,
                        array( 'ORDER BY' => array( 'wl_namespace', 'wl_title' ) )
@@ -470,26 +471,26 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
         *
         * @return HTMLForm
         */
-       protected function getNormalForm(){
+       protected function getNormalForm() {
                global $wgContLang;
 
                $fields = array();
                $count = 0;
 
-               foreach( $this->getWatchlistInfo() as $namespace => $pages ){
+               foreach( $this->getWatchlistInfo() as $namespace => $pages ) {
                        if ( $namespace >= 0 ) {
-                               $fields['TitlesNs'.$namespace] = array(
+                               $fields['TitlesNs' . $namespace] = array(
                                        'class' => 'EditWatchlistCheckboxSeriesField',
                                        'options' => array(),
                                        'section' => "ns$namespace",
                                );
                        }
 
-                       foreach( array_keys( $pages ) as $dbkey ){
+                       foreach( array_keys( $pages ) as $dbkey ) {
                                $title = Title::makeTitleSafe( $namespace, $dbkey );
                                if ( $this->checkTitle( $title, $namespace, $dbkey ) ) {
                                        $text = $this->buildRemoveLine( $title );
-                                       $fields['TitlesNs'.$namespace]['options'][$text] = $title->getPrefixedText();
+                                       $fields['TitlesNs' . $namespace]['options'][$text] = $title->getPrefixedText();
                                        $count++;
                                }
                        }
@@ -519,7 +520,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                $form->setTitle( $this->getTitle() );
                $form->setSubmitTextMsg( 'watchlistedit-normal-submit' );
                # Used message keys: 'accesskey-watchlistedit-normal-submit', 'tooltip-watchlistedit-normal-submit'
-               $form->setSubmitTooltip('watchlistedit-normal-submit');
+               $form->setSubmitTooltip( 'watchlistedit-normal-submit' );
                $form->setWrapperLegendMsg( 'watchlistedit-normal-legend' );
                $form->addHeaderText( $this->msg( 'watchlistedit-normal-explain' )->parse() );
                $form->setSubmitCallback( array( $this, 'submitNormal' ) );
@@ -564,7 +565,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
         *
         * @return HTMLForm
         */
-       protected function getRawForm(){
+       protected function getRawForm() {
                $titles = implode( $this->getWatchlist(), "\n" );
                $fields = array(
                        'Titles' => array(
@@ -577,7 +578,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                $form->setTitle( $this->getTitle( 'raw' ) );
                $form->setSubmitTextMsg( 'watchlistedit-raw-submit' );
                # Used message keys: 'accesskey-watchlistedit-raw-submit', 'tooltip-watchlistedit-raw-submit'
-               $form->setSubmitTooltip('watchlistedit-raw-submit');
+               $form->setSubmitTooltip( 'watchlistedit-raw-submit' );
                $form->setWrapperLegendMsg( 'watchlistedit-raw-legend' );
                $form->addHeaderText( $this->msg( 'watchlistedit-raw-explain' )->parse() );
                $form->setSubmitCallback( array( $this, 'submitRaw' ) );
@@ -648,7 +649,7 @@ class WatchlistEditor extends SpecialEditWatchlist {}
  * Extend HTMLForm purely so we can have a more sane way of getting the section headers
  */
 class EditWatchlistNormalHTMLForm extends HTMLForm {
-       public function getLegend( $namespace ){
+       public function getLegend( $namespace ) {
                $namespace = substr( $namespace, 2 );
                return $namespace == NS_MAIN
                        ? $this->msg( 'blanknamespace' )->escaped()
index 18dde20..9d1ec10 100644 (file)
@@ -80,7 +80,7 @@ class SpecialExport extends SpecialPage {
                        $page = $request->getText( 'pages' );
                        $nsindex = $request->getText( 'nsindex', '' );
 
-                       if ( strval( $nsindex ) !== ''  ) {
+                       if ( strval( $nsindex ) !== '' ) {
                                /**
                                 * Same implementation as above, so same @todo
                                 */
@@ -124,7 +124,7 @@ class SpecialExport extends SpecialPage {
                        if ( $this->curonly ) {
                                $history = WikiExporter::CURRENT;
                        } elseif ( !$historyCheck ) {
-                               if ( $limit > 0 && ($wgExportMaxHistory == 0 || $limit < $wgExportMaxHistory ) ) {
+                               if ( $limit > 0 && ( $wgExportMaxHistory == 0 || $limit < $wgExportMaxHistory ) ) {
                                        $history['limit'] = $limit;
                                }
                                if ( !is_null( $offset ) ) {
@@ -161,7 +161,7 @@ class SpecialExport extends SpecialPage {
 
                $list_authors = $request->getCheck( 'listauthors' );
                if ( !$this->curonly || !$wgExportAllowListContributors ) {
-                       $list_authors = false ;
+                       $list_authors = false;
                }
 
                if ( $this->doExport ) {
@@ -339,7 +339,7 @@ class SpecialExport extends SpecialPage {
 
                        // This might take a while... :D
                        wfSuppressWarnings();
-                       set_time_limit(0);
+                       set_time_limit( 0 );
                        wfRestoreWarnings();
                }
 
@@ -405,7 +405,7 @@ class SpecialExport extends SpecialPage {
 
                foreach ( $res as $row ) {
                        $n = $row->page_title;
-                       if ($row->page_namespace) {
+                       if ( $row->page_namespace ) {
                                $ns = $wgContLang->getNsText( $row->page_namespace );
                                $n = $ns . ':' . $n;
                        }
index 96739ea..366aa81 100644 (file)
@@ -101,7 +101,7 @@ class FileDuplicateSearchPage extends QueryPage {
                $this->setHeaders();
                $this->outputHeader();
 
-               $this->filename =  isset( $par ) ?  $par : $this->getRequest()->getText( 'filename' );
+               $this->filename = isset( $par ) ?  $par : $this->getRequest()->getText( 'filename' );
                $this->file = null;
                $this->hash = '';
                $title = Title::newFromText( $this->filename, NS_FILE );
index 1ae201b..16772ec 100644 (file)
@@ -114,7 +114,7 @@ class SpecialImport extends SpecialPage {
                                throw new PermissionsError( 'importupload' );
                        }
                } elseif ( $sourceName == "interwiki" ) {
-                       if( !$user->isAllowed( 'import' ) ){
+                       if( !$user->isAllowed( 'import' ) ) {
                                throw new PermissionsError( 'import' );
                        }
                        $this->interwiki = $request->getVal( 'interwiki' );
@@ -153,7 +153,7 @@ class SpecialImport extends SpecialPage {
 
                        $out->addWikiMsg( "importstart" );
 
-                       $reporter = new ImportReporter( $importer, $isUpload, $this->interwiki , $this->logcomment);
+                       $reporter = new ImportReporter( $importer, $isUpload, $this->interwiki, $this->logcomment );
                        $reporter->setContext( $this->getContext() );
                        $exception = false;
 
@@ -353,7 +353,7 @@ class ImportReporter extends ContextSource {
        private $mOriginalPageOutCallback = null;
        private $mLogItemCount = 0;
 
-       function __construct( $importer, $upload, $interwiki , $reason=false ) {
+       function __construct( $importer, $upload, $interwiki, $reason = false ) {
                $this->mOriginalPageOutCallback =
                                $importer->setPageOutCallback( array( $this, 'reportPage' ) );
                $this->mOriginalLogCallback =
@@ -410,7 +410,7 @@ class ImportReporter extends ContextSource {
                                $detail = $this->msg( 'import-logentry-upload-detail' )->numParams(
                                        $successCount )->inContentLanguage()->text();
                                if ( $this->reason ) {
-                                       $detail .=  $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
+                                       $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
                                }
                                $log->addEntry( 'upload', $title, $detail );
                        } else {
@@ -419,7 +419,7 @@ class ImportReporter extends ContextSource {
                                $detail = $this->msg( 'import-logentry-interwiki-detail' )->numParams(
                                        $successCount )->params( $interwiki )->inContentLanguage()->text();
                                if ( $this->reason ) {
-                                       $detail .=  $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
+                                       $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
                                }
                                $log->addEntry( 'interwiki', $title, $detail );
                        }
@@ -428,7 +428,7 @@ class ImportReporter extends ContextSource {
                        $dbw = wfGetDB( DB_MASTER );
                        $latest = $title->getLatestRevID();
                        $nullRevision = Revision::newNullRevision( $dbw, $title->getArticleID(), $comment, true );
-                       if (!is_null($nullRevision)) {
+                       if ( !is_null( $nullRevision ) ) {
                                $nullRevision->insertOn( $dbw );
                                $page = WikiPage::factory( $title );
                                # Update page record
index 9a224b6..f5fa697 100644 (file)
@@ -64,15 +64,15 @@ class LinkSearchPage extends QueryPage {
 
                $target2 = $target;
                $protocol = '';
-               $pr_sl = strpos($target2, '//' );
-               $pr_cl = strpos($target2, ':' );
+               $pr_sl = strpos( $target2, '//' );
+               $pr_cl = strpos( $target2, ':' );
                if ( $pr_sl ) {
                        // For protocols with '//'
-                       $protocol = substr( $target2, 0 , $pr_sl+2 );
-                       $target2 = substr( $target2, $pr_sl+2 );
+                       $protocol = substr( $target2, 0, $pr_sl + 2 );
+                       $target2 = substr( $target2, $pr_sl + 2 );
                } elseif ( !$pr_sl && $pr_cl ) {
                        // For protocols without '//' like 'mailto:'
-                       $protocol = substr( $target2, 0 , $pr_cl+1 );
+                       $protocol = substr( $target2, 0, $pr_cl + 1 );
                        $target2 = substr( $target2, $pr_cl+1 );
                } elseif ( $protocol == '' && $target2 != '' ) {
                        // default
@@ -138,10 +138,10 @@ class LinkSearchPage extends QueryPage {
         */
        static function mungeQuery( $query, $prot ) {
                $field = 'el_index';
-               $rv = LinkFilter::makeLikeArray( $query , $prot );
+               $rv = LinkFilter::makeLikeArray( $query, $prot );
                if ( $rv === false ) {
                        // LinkFilter doesn't handle wildcard in IP, so we'll have to munge here.
-                       if (preg_match('/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query)) {
+                       if ( preg_match( '/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query ) ) {
                                $dbr = wfGetDB( DB_SLAVE );
                                $rv = array( $prot . rtrim( $query, " \t*" ), $dbr->anyString() );
                                $field = 'el_to';
@@ -201,7 +201,7 @@ class LinkSearchPage extends QueryPage {
         * Override to check query validity.
         */
        function doQuery( $offset = false, $limit = false ) {
-               list( $this->mMungedQuery,  ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
+               list( $this->mMungedQuery, ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
                if( $this->mMungedQuery === false ) {
                        $this->getOutput()->addWikiMsg( 'linksearch-error' );
                } else {
index d459ac6..661db7b 100644 (file)
 
 class SpecialListFiles extends IncludableSpecialPage {
 
-       public function __construct(){
+       public function __construct() {
                parent::__construct( 'Listfiles' );
        }
 
-       public function execute( $par ){
+       public function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
 
@@ -137,7 +137,7 @@ class ImageListPager extends TablePager {
                $tables = array( 'image' );
                $fields = array_keys( $this->getFieldNames() );
                $fields[] = 'img_user';
-               $fields[array_search('thumb', $fields)] = 'img_name AS thumb';
+               $fields[array_search( 'thumb', $fields )] = 'img_name AS thumb';
                $options = $join_conds = array();
 
                # Depends on $wgMiserMode
index 1f95c22..c82522a 100644 (file)
@@ -147,7 +147,7 @@ class SpecialListGroupRights extends SpecialPage {
         * @param $removeSelf Array of group this group is allowed to remove from self or true
         * @return string List of all granted permissions, separated by comma separator
         */
-        private function formatPermissions( $permissions, $revoke, $add, $remove, $addSelf, $removeSelf ) {
+       private function formatPermissions( $permissions, $revoke, $add, $remove, $addSelf, $removeSelf ) {
                $r = array();
                foreach( $permissions as $permission => $granted ) {
                        //show as granted only if it isn't revoked to prevent duplicate display of permissions
@@ -170,7 +170,7 @@ class SpecialListGroupRights extends SpecialPage {
                }
                sort( $r );
                $lang = $this->getLanguage();
-               if( $add === true ){
+               if( $add === true ) {
                        $r[] = $this->msg( 'listgrouprights-addgroup-all' )->escaped();
                } elseif( is_array( $add ) && count( $add ) ) {
                        $add = array_values( array_unique( $add ) );
@@ -179,7 +179,7 @@ class SpecialListGroupRights extends SpecialPage {
                                count( $add )
                        )->parse();
                }
-               if( $remove === true ){
+               if( $remove === true ) {
                        $r[] = $this->msg( 'listgrouprights-removegroup-all' )->escaped();
                } elseif( is_array( $remove ) && count( $remove ) ) {
                        $remove = array_values( array_unique( $remove ) );
@@ -188,7 +188,7 @@ class SpecialListGroupRights extends SpecialPage {
                                count( $remove )
                        )->parse();
                }
-               if( $addSelf === true ){
+               if( $addSelf === true ) {
                        $r[] = $this->msg( 'listgrouprights-addgroup-self-all' )->escaped();
                } elseif( is_array( $addSelf ) && count( $addSelf ) ) {
                        $addSelf = array_values( array_unique( $addSelf ) );
@@ -197,7 +197,7 @@ class SpecialListGroupRights extends SpecialPage {
                                count( $addSelf )
                        )->parse();
                }
-               if( $removeSelf === true ){
+               if( $removeSelf === true ) {
                        $r[] = $this->msg( 'listgrouprights-removegroup-self-all' )->parse();
                } elseif( is_array( $removeSelf ) && count( $removeSelf ) ) {
                        $removeSelf = array_values( array_unique( $removeSelf ) );
index ea598c3..3265d1a 100644 (file)
@@ -116,7 +116,7 @@ class UsersPager extends AlphabeticPager {
                $options['GROUP BY'] = $this->creationSort ? 'user_id' : 'user_name';
 
                $query = array(
-                       'tables' => array( 'user', 'user_groups', 'ipblocks'),
+                       'tables' => array( 'user', 'user_groups', 'ipblocks' ),
                        'fields' => array(
                                'user_name' => $this->creationSort ? 'MAX(user_name)' : 'user_name',
                                'user_id' => $this->creationSort ? 'user_id' : 'MAX(user_id)',
@@ -212,17 +212,26 @@ class UsersPager extends AlphabeticPager {
                list( $self ) = explode( '/', $this->getTitle()->getPrefixedDBkey() );
 
                # Form tag
-               $out  = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-listusers-form' ) ) .
+               $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-listusers-form' ) ) .
                        Xml::fieldset( $this->msg( 'listusers' )->text() ) .
                        Html::hidden( 'title', $self );
 
                # Username field
                $out .= Xml::label( $this->msg( 'listusersfrom' )->text(), 'offset' ) . ' ' .
-                       Xml::input( 'username', 20, $this->requestedUser, array( 'id' => 'offset' ) ) . ' ';
+                       Html::input(
+                               'username',
+                               $this->requestedUser,
+                               'text',
+                               array(
+                                       'id' => 'offset',
+                                       'size' => 20,
+                                       'autofocus' => $this->requestedUser === ''
+                               )
+                       ) . ' ';
 
                # Group drop-down list
                $out .= Xml::label( $this->msg( 'group' )->text(), 'group' ) . ' ' .
-                       Xml::openElement('select',  array( 'name' => 'group', 'id' => 'group' ) ) .
+                       Xml::openElement( 'select', array( 'name' => 'group', 'id' => 'group' ) ) .
                        Xml::option( $this->msg( 'group-all' )->text(), '' );
                foreach( $this->getAllGroups() as $group => $groupText )
                        $out .= Xml::option( $groupText, $group, $group == $this->requestedGroup );
index 22932e5..a2d51db 100644 (file)
@@ -125,4 +125,3 @@ class MostlinkedTemplatesPage extends QueryPage {
                return Linker::link( $wlh, $label );
        }
 }
-
index 66fd918..bf93ef2 100644 (file)
@@ -152,7 +152,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                </tr>";
                        $err = array();
                } else {
-                       if ($this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage() ) {
+                       if ( $this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage() ) {
                                $out->wrapWikiMsg( "<div class=\"error mw-moveuserpage-warning\">\n$1\n</div>", 'moveuserpage-warning' );
                        }
                        $out->addWikiMsg( $wgFixDoubleRedirects ? 'movepagetext' :
@@ -189,7 +189,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                array(
                                        'rd_namespace' => $this->oldTitle->getNamespace(),
                                        'rd_title' => $this->oldTitle->getDBkey(),
-                               ) , __METHOD__ );
+                               ), __METHOD__ );
                } else {
                        $hasRedirects = false;
                }
@@ -257,11 +257,11 @@ class MovePageForm extends UnlistedSpecialPage {
                $handler = ContentHandler::getForTitle( $this->oldTitle );
 
                $out->addHTML(
-                        Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) .
-                        Xml::openElement( 'fieldset' ) .
-                        Xml::element( 'legend', null, $this->msg( 'move-page-legend' )->text() ) .
-                        Xml::openElement( 'table', array( 'id' => 'mw-movepage-table' ) ) .
-                        "<tr>
+                       Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) .
+                       Xml::openElement( 'fieldset' ) .
+                       Xml::element( 'legend', null, $this->msg( 'move-page-legend' )->text() ) .
+                       Xml::openElement( 'table', array( 'id' => 'mw-movepage-table' ) ) .
+                       "<tr>
                                <td class='mw-label'>" .
                                        $this->msg( 'movearticle' )->escaped() .
                                "</td>
@@ -344,7 +344,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                        'wpMovesubpages',
                                        # Don't check the box if we only have talk subpages to
                                        # move and we aren't moving the talk page.
-                                       $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk),
+                                       $this->moveSubpages && ( $this->oldTitle->hasSubpages() || $this->moveTalk ),
                                        array( 'id' => 'wpMovesubpages' )
                                ) . '&#160;' .
                                Xml::tags( 'label', array( 'for' => 'wpMovesubpages' ),
@@ -359,7 +359,7 @@ class MovePageForm extends UnlistedSpecialPage {
                        );
                }
 
-               $watchChecked = $user->isLoggedIn() && ($this->watch || $user->getBoolOption( 'watchmoves' )
+               $watchChecked = $user->isLoggedIn() && ( $this->watch || $user->getBoolOption( 'watchmoves' )
                        || $user->isWatched( $this->oldTitle ) );
                # Don't allow watching if user is not logged in
                if( $user->isLoggedIn() ) {
@@ -538,10 +538,10 @@ class MovePageForm extends UnlistedSpecialPage {
                        );
                        $conds['page_namespace'] = array();
                        if( MWNamespace::hasSubpages( $nt->getNamespace() ) ) {
-                               $conds['page_namespace'] []= $ot->getNamespace();
+                               $conds['page_namespace'][] = $ot->getNamespace();
                        }
                        if( $this->moveTalk && MWNamespace::hasSubpages( $nt->getTalkPage()->getNamespace() ) ) {
-                               $conds['page_namespace'] []= $ot->getTalkPage()->getNamespace();
+                               $conds['page_namespace'][] = $ot->getTalkPage()->getNamespace();
                        }
                } elseif( $this->moveTalk ) {
                        $conds = array(
@@ -587,7 +587,7 @@ class MovePageForm extends UnlistedSpecialPage {
                        $newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
                        if( !$newSubpage ) {
                                $oldLink = Linker::linkKnown( $oldSubpage );
-                               $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink
+                               $extraOutput[] = $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink
                                        )->params( Title::makeName( $newNs, $newPageName ) )->escaped();
                                continue;
                        }
@@ -595,7 +595,7 @@ class MovePageForm extends UnlistedSpecialPage {
                        # This was copy-pasted from Renameuser, bleh.
                        if ( $newSubpage->exists() && !$oldSubpage->isValidMoveTarget( $newSubpage ) ) {
                                $link = Linker::linkKnown( $newSubpage );
-                               $extraOutput []= $this->msg( 'movepage-page-exists' )->rawParams( $link )->escaped();
+                               $extraOutput[] = $this->msg( 'movepage-page-exists' )->rawParams( $link )->escaped();
                        } else {
                                $success = $oldSubpage->moveTo( $newSubpage, true, $this->reason, $createRedirect );
                                if( $success === true ) {
@@ -609,16 +609,16 @@ class MovePageForm extends UnlistedSpecialPage {
                                                array( 'redirect' => 'no' )
                                        );
                                        $newLink = Linker::linkKnown( $newSubpage );
-                                       $extraOutput []= $this->msg( 'movepage-page-moved' )->rawParams( $oldLink, $newLink )->escaped();
+                                       $extraOutput[] = $this->msg( 'movepage-page-moved' )->rawParams( $oldLink, $newLink )->escaped();
                                        ++$count;
                                        if( $count >= $wgMaximumMovedPages ) {
-                                               $extraOutput []= $this->msg( 'movepage-max-pages' )->numParams( $wgMaximumMovedPages )->escaped();
+                                               $extraOutput[] = $this->msg( 'movepage-max-pages' )->numParams( $wgMaximumMovedPages )->escaped();
                                                break;
                                        }
                                } else {
                                        $oldLink = Linker::linkKnown( $oldSubpage );
                                        $newLink = Linker::link( $newSubpage );
-                                       $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink, $newLink )->escaped();
+                                       $extraOutput[] = $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink, $newLink )->escaped();
                                }
                        }
 
index 350aac6..caf48be 100644 (file)
  */
 class SpecialNewFiles extends IncludableSpecialPage {
 
-       public function __construct(){
+       public function __construct() {
                parent::__construct( 'Newimages' );
        }
 
-       public function execute( $par ){
+       public function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
 
@@ -57,7 +57,7 @@ class NewFilesPager extends ReverseChronologicalPager {
 
        function __construct( IContextSource $context, $par = null ) {
                $this->like = $context->getRequest()->getText( 'like' );
-               $this->showbots = $context->getRequest()->getBool( 'showbots' , 0 );
+               $this->showbots = $context->getRequest()->getBool( 'showbots', 0 );
                if ( is_numeric( $par ) ) {
                        $this->setLimit( $par );
                }
@@ -85,10 +85,10 @@ class NewFilesPager extends ReverseChronologicalPager {
                        }
                }
 
-               if( !$wgMiserMode && $this->like !== null ){
+               if( !$wgMiserMode && $this->like !== null ) {
                        $dbr = wfGetDB( DB_SLAVE );
                        $likeObj = Title::newFromURL( $this->like );
-                       if( $likeObj instanceof Title ){
+                       if( $likeObj instanceof Title ) {
                                $like = $dbr->buildLike( $dbr->anyString(), strtolower( $likeObj->getDBkey() ), $dbr->anyString() );
                                $conds[] = "LOWER(img_name) $like";
                        }
@@ -104,18 +104,18 @@ class NewFilesPager extends ReverseChronologicalPager {
                return $query;
        }
 
-       function getIndexField(){
+       function getIndexField() {
                return 'img_timestamp';
        }
 
-       function getStartBody(){
+       function getStartBody() {
                if ( !$this->gallery ) {
                        $this->gallery = new ImageGallery();
                }
                return '';
        }
 
-       function getEndBody(){
+       function getEndBody() {
                return $this->gallery->toHTML();
        }
 
@@ -161,7 +161,7 @@ class NewFilesPager extends ReverseChronologicalPager {
                        ),
                );
 
-               if( $wgMiserMode ){
+               if( $wgMiserMode ) {
                        unset( $fields['like'] );
                }
 
index 85b9cf8..0499e57 100644 (file)
@@ -59,6 +59,7 @@ class SpecialNewpages extends IncludableSpecialPage {
                $opts->add( 'username', '' );
                $opts->add( 'feed', '' );
                $opts->add( 'tagfilter', '' );
+               $opts->add( 'invert', false );
 
                $this->customFilters = array();
                wfRunHooks( 'SpecialNewPagesFilters', array( $this, &$this->customFilters ) );
@@ -105,7 +106,7 @@ class SpecialNewpages extends IncludableSpecialPage {
                        }
                        // PG offsets not just digits!
                        if ( preg_match( '/^offset=([^=]+)$/', $bit, $m ) ) {
-                               $this->opts->setValue( 'offset',  intval( $m[1] ) );
+                               $this->opts->setValue( 'offset', intval( $m[1] ) );
                        }
                        if ( preg_match( '/^username=(.*)$/', $bit, $m ) ) {
                                $this->opts->setValue( 'username', $m[1] );
@@ -113,7 +114,7 @@ class SpecialNewpages extends IncludableSpecialPage {
                        if ( preg_match( '/^namespace=(.*)$/', $bit, $m ) ) {
                                $ns = $this->getLanguage()->getNsIndex( $m[1] );
                                if( $ns !== false ) {
-                                       $this->opts->setValue( 'namespace',  $ns );
+                                       $this->opts->setValue( 'namespace', $ns );
                                }
                        }
                }
@@ -146,7 +147,7 @@ class SpecialNewpages extends IncludableSpecialPage {
 
                        $allValues = $this->opts->getAllValues();
                        unset( $allValues['feed'] );
-                       $out->setFeedAppendQuery( wfArrayToCGI( $allValues ) );
+                       $out->setFeedAppendQuery( wfArrayToCgi( $allValues ) );
                }
 
                $pager = new NewPagesPager( $this, $this->opts );
@@ -211,6 +212,7 @@ class SpecialNewpages extends IncludableSpecialPage {
                $namespace = $this->opts->consumeValue( 'namespace' );
                $username = $this->opts->consumeValue( 'username' );
                $tagFilterVal = $this->opts->consumeValue( 'tagfilter' );
+               $nsinvert = $this->opts->consumeValue( 'invert' );
 
                // Check username input validity
                $ut = Title::makeTitleSafe( NS_USER, $username );
@@ -246,6 +248,13 @@ class SpecialNewpages extends IncludableSpecialPage {
                                                        'id'    => 'namespace',
                                                        'class' => 'namespaceselector',
                                                )
+                                       ) . '&#160;' .
+                                       Xml::checkLabel(
+                                               $this->msg( 'invert' )->text(),
+                                               'invert',
+                                               'nsinvert',
+                                               $nsinvert,
+                                               array( 'title' => $this->msg( 'tooltip-invert' )->text() )
                                        ) .
                                '</td>
                        </tr>' . ( $tagFilter ? (
@@ -296,11 +305,11 @@ class SpecialNewpages extends IncludableSpecialPage {
 
                # Revision deletion works on revisions, so we should cast one
                $row = array(
-                                         'comment' => $result->rc_comment,
-                                         'deleted' => $result->rc_deleted,
-                                         'user_text' => $result->rc_user_text,
-                                         'user' => $result->rc_user,
-                                       );
+                       'comment' => $result->rc_comment,
+                       'deleted' => $result->rc_deleted,
+                       'user_text' => $result->rc_user_text,
+                       'user' => $result->rc_user,
+               );
                $rev = new Revision( $row );
                $rev->setTitle( $title );
 
@@ -499,7 +508,11 @@ class NewPagesPager extends ReverseChronologicalPager {
                $user = Title::makeTitleSafe( NS_USER, $username );
 
                if( $namespace !== false ) {
-                       $conds['rc_namespace'] = $namespace;
+                       if ( $this->opts->getValue( 'invert' ) ) {
+                               $conds[] = 'rc_namespace != ' . $this->mDb->addQuotes( $namespace );
+                       } else {
+                               $conds['rc_namespace'] = $namespace;
+                       }
                        $rcIndexes = array( 'new_name_timestamp' );
                } else {
                        $rcIndexes = array( 'rc_timestamp' );
index d7cf693..f42a7a1 100644 (file)
@@ -86,7 +86,7 @@ class SpecialPasswordReset extends FormSpecialPage {
                        );
                }
 
-               if( $this->getUser()->isAllowed( 'passwordreset' ) ){
+               if( $this->getUser()->isAllowed( 'passwordreset' ) ) {
                        $a['Capture'] = array(
                                'type' => 'check',
                                'label-message' => 'passwordreset-capture',
@@ -136,7 +136,7 @@ class SpecialPasswordReset extends FormSpecialPage {
                        }
                }
 
-               if( isset( $data['Capture'] ) && !$this->getUser()->isAllowed( 'passwordreset' ) ){
+               if( isset( $data['Capture'] ) && !$this->getUser()->isAllowed( 'passwordreset' ) ) {
                        // The user knows they don't have the passwordreset permission, but they tried to spoof the form.  That's naughty
                        throw new PermissionsError( 'passwordreset' );
                }
@@ -162,7 +162,7 @@ class SpecialPasswordReset extends FormSpecialPage {
                        );
                        if ( $res ) {
                                $users = array();
-                               foreach( $res as $row ){
+                               foreach( $res as $row ) {
                                        $users[] = User::newFromRow( $row );
                                }
                        } else {
@@ -180,8 +180,8 @@ class SpecialPasswordReset extends FormSpecialPage {
                        return array( $error );
                }
 
-               if( count( $users ) == 0 ){
-                       if( $method == 'email' ){
+               if( count( $users ) == 0 ) {
+                       if( $method == 'email' ) {
                                // Don't reveal whether or not an email address is in use
                                return true;
                        } else {
@@ -264,7 +264,7 @@ class SpecialPasswordReset extends FormSpecialPage {
 
                if ( $this->result->isGood() ) {
                        return true;
-               } elseif( isset( $data['Capture'] ) && $data['Capture'] ){
+               } elseif( isset( $data['Capture'] ) && $data['Capture'] ) {
                        // The email didn't send, but maybe they knew that and that's why they captured it
                        return true;
                } else {
@@ -275,10 +275,10 @@ class SpecialPasswordReset extends FormSpecialPage {
        }
 
        public function onSuccess() {
-               if( $this->getUser()->isAllowed( 'passwordreset' ) && $this->email != null ){
+               if( $this->getUser()->isAllowed( 'passwordreset' ) && $this->email != null ) {
                        // @todo: Logging
 
-                       if( $this->result->isGood() ){
+                       if( $this->result->isGood() ) {
                                $this->getOutput()->addWikiMsg( 'passwordreset-emailsent-capture' );
                        } else {
                                $this->getOutput()->addWikiMsg( 'passwordreset-emailerror-capture', $this->result->getMessage() );
index 5a9f3f7..99b586e 100644 (file)
@@ -46,7 +46,7 @@ class PopularPagesPage extends QueryPage {
                        'tables' => array( 'page' ),
                        'fields' => array( 'namespace' => 'page_namespace',
                                        'title' => 'page_title',
-                                       'value' => 'page_counter'),
+                                       'value' => 'page_counter' ),
                        'conds' => array( 'page_is_redirect' => 0,
                                        'page_namespace' => MWNamespace::getContentNamespaces() ) );
        }
index 7740b32..e1e18e4 100644 (file)
@@ -29,7 +29,7 @@
 class SpecialPrefixindex extends SpecialAllpages {
        // Inherit $maxPerPage
 
-       function __construct(){
+       function __construct() {
                parent::__construct( 'Prefixindex' );
        }
 
@@ -101,7 +101,7 @@ class SpecialPrefixindex extends SpecialAllpages {
                                Xml::label( $this->msg( 'allpagesprefix' )->text(), 'nsfrom' ) .
                                "</td>
                                <td class='mw-input'>" .
-                                       Xml::input( 'prefix', 30, str_replace('_',' ',$from), array( 'id' => 'nsfrom' ) ) .
+                                       Xml::input( 'prefix', 30, str_replace( '_', ' ', $from ), array( 'id' => 'nsfrom' ) ) .
                                "</td>
                        </tr>
                        <tr>
@@ -145,8 +145,8 @@ class SpecialPrefixindex extends SpecialAllpages {
                        $from = $prefix;
                }
 
-               $fromList = $this->getNamespaceKeyAndText($namespace, $from);
-               $prefixList = $this->getNamespaceKeyAndText($namespace, $prefix);
+               $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
+               $prefixList = $this->getNamespaceKeyAndText( $namespace, $prefix );
                $namespaces = $wgContLang->getNamespaces();
 
                if ( !$prefixList || !$fromList ) {
@@ -227,7 +227,7 @@ class SpecialPrefixindex extends SpecialAllpages {
                } else {
                        $nsForm = $this->namespacePrefixForm( $namespace, $prefix, $hideredirects );
                        $self = $this->getTitle();
-                       $out2 = Xml::openElement( 'table', array( 'id' => 'mw-prefixindex-nav-table' ) )  .
+                       $out2 = Xml::openElement( 'table', array( 'id' => 'mw-prefixindex-nav-table' ) ) .
                                '<tr>
                                        <td>' .
                                                $nsForm .
@@ -241,14 +241,14 @@ class SpecialPrefixindex extends SpecialAllpages {
                                        'hideredirects' => $hideredirects,
                                );
 
-                               if( $namespace || ($prefix == '')) {
+                               if( $namespace || $prefix == '' ) {
                                        // Keep the namespace even if it's 0 for empty prefixes.
                                        // This tells us we're not just a holdover from old links.
                                        $query['namespace'] = $namespace;
                                }
                                $nextLink = Linker::linkKnown(
                                                $self,
-                                               $this->msg( 'nextpage', str_replace( '_',' ', $s->page_title ) )->escaped(),
+                                               $this->msg( 'nextpage', str_replace( '_', ' ', $s->page_title ) )->escaped(),
                                                array(),
                                                $query
                                        );
index db3f012..d580d62 100644 (file)
@@ -51,7 +51,7 @@ class SpecialProtectedpages extends SpecialPage {
                $size = $request->getIntOrNull( 'size' );
                $NS = $request->getIntOrNull( 'namespace' );
                $indefOnly = $request->getBool( 'indefonly' ) ? 1 : 0;
-               $cascadeOnly = $request->getBool('cascadeonly') ? 1 : 0;
+               $cascadeOnly = $request->getBool( 'cascadeonly' ) ? 1 : 0;
 
                $pager = new ProtectedPagesPager( $this, array(), $type, $level, $NS, $sizetype, $size, $indefOnly, $cascadeOnly );
 
@@ -78,7 +78,7 @@ class SpecialProtectedpages extends SpecialPage {
 
                static $infinity = null;
 
-               if( is_null( $infinity ) ){
+               if( is_null( $infinity ) ) {
                        $infinity = wfGetDB( DB_SLAVE )->getInfinity();
                }
 
@@ -109,7 +109,7 @@ class SpecialProtectedpages extends SpecialPage {
                        )->escaped();
                }
 
-               if(!is_null($size = $row->page_len)) {
+               if( !is_null( $size = $row->page_len ) ) {
                        $stxt = $lang->getDirMark() . ' ' . Linker::formatRevisionSize( $size );
                }
 
@@ -154,7 +154,7 @@ class SpecialProtectedpages extends SpecialPage {
         * @param $cascadeOnly Boolean: only cascading protection
         * @return String: input form
         */
-       protected function showOptions( $namespace, $type='edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly ) {
+       protected function showOptions( $namespace, $type = 'edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly ) {
                global $wgScript;
                $title = $this->getTitle();
                return Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
@@ -272,7 +272,7 @@ class SpecialProtectedpages extends SpecialPage {
                // First pass to load the log names
                foreach( $wgRestrictionLevels as $type ) {
                        // Messages used can be 'restriction-level-sysop' and 'restriction-level-autoconfirmed'
-                       if( $type !='' && $type !='*') {
+                       if( $type != '' && $type != '*' ) {
                                $text = $this->msg( "restriction-level-$type" )->text();
                                $m[$text] = $type;
                        }
@@ -300,7 +300,7 @@ class ProtectedPagesPager extends AlphabeticPager {
        public $mForm, $mConds;
        private $type, $level, $namespace, $sizetype, $size, $indefonly;
 
-       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0,
+       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype = '', $size = 0,
                $indefonly = false, $cascadeonly = false )
        {
                $this->mForm = $form;
@@ -309,7 +309,7 @@ class ProtectedPagesPager extends AlphabeticPager {
                $this->level = $level;
                $this->namespace = $namespace;
                $this->sizetype = $sizetype;
-               $this->size = intval($size);
+               $this->size = intval( $size );
                $this->indefonly = (bool)$indefonly;
                $this->cascadeonly = (bool)$cascadeonly;
                parent::__construct( $form->getContext() );
@@ -336,9 +336,9 @@ class ProtectedPagesPager extends AlphabeticPager {
                $conds[] = 'page_id=pr_page';
                $conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type );
 
-               if( $this->sizetype=='min' ) {
+               if( $this->sizetype == 'min' ) {
                        $conds[] = 'page_len>=' . $this->size;
-               } elseif( $this->sizetype=='max' ) {
+               } elseif( $this->sizetype == 'max' ) {
                        $conds[] = 'page_len<=' . $this->size;
                }
 
@@ -351,7 +351,7 @@ class ProtectedPagesPager extends AlphabeticPager {
 
                if( $this->level )
                        $conds[] = 'pr_level=' . $this->mDb->addQuotes( $this->level );
-               if( !is_null($this->namespace) )
+               if( !is_null( $this->namespace ) )
                        $conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace );
                return array(
                        'tables' => array( 'page_restrictions', 'page' ),
index cf1e2b4..abb4af3 100644 (file)
@@ -76,7 +76,7 @@ class SpecialProtectedtitles extends SpecialPage {
 
                static $infinity = null;
 
-               if( is_null( $infinity ) ){
+               if( is_null( $infinity ) ) {
                        $infinity = wfGetDB( DB_SLAVE )->getInfinity();
                }
 
@@ -113,7 +113,7 @@ class SpecialProtectedtitles extends SpecialPage {
         * @return string
         * @private
         */
-       function showOptions( $namespace, $type='edit', $level ) {
+       function showOptions( $namespace, $type = 'edit', $level ) {
                global $wgScript;
                $action = htmlspecialchars( $wgScript );
                $title = $this->getTitle();
@@ -161,13 +161,13 @@ class SpecialProtectedtitles extends SpecialPage {
 
                // First pass to load the log names
                foreach( $wgRestrictionLevels as $type ) {
-                       if ( $type !='' && $type !='*') {
+                       if ( $type != '' && $type != '*' ) {
                                $text = $this->msg( "restriction-level-$type" )->text();
                                $m[$text] = $type;
                        }
                }
                // Is there only one level (aside from "all")?
-               if( count($m) <= 2 ) {
+               if( count( $m ) <= 2 ) {
                        return '';
                }
                // Third pass generates sorted XHTML content
@@ -191,7 +191,7 @@ class SpecialProtectedtitles extends SpecialPage {
 class ProtectedTitlesPager extends AlphabeticPager {
        public $mForm, $mConds;
 
-       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0 ) {
+       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype = '', $size = 0 ) {
                $this->mForm = $form;
                $this->mConds = $conds;
                $this->level = $level;
@@ -234,7 +234,7 @@ class ProtectedTitlesPager extends AlphabeticPager {
                $conds[] = 'pt_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() );
                if( $this->level )
                        $conds['pt_create_perm'] = $this->level;
-               if( !is_null($this->namespace) )
+               if( !is_null( $this->namespace ) )
                        $conds[] = 'pt_namespace=' . $this->mDb->addQuotes( $this->namespace );
                return array(
                        'tables' => 'protected_titles',
@@ -248,4 +248,3 @@ class ProtectedTitlesPager extends AlphabeticPager {
                return 'pt_timestamp';
        }
 }
-
index 307088e..13a7043 100644 (file)
@@ -32,7 +32,7 @@ class RandomPage extends SpecialPage {
        protected $isRedir = false; // should the result be a redirect?
        protected $extra = array(); // Extra SQL statements
 
-       public function __construct( $name = 'Randompage' ){
+       public function __construct( $name = 'Randompage' ) {
                $this->namespaces = MWNamespace::getContentNamespaces();
                parent::__construct( $name );
        }
@@ -49,7 +49,7 @@ class RandomPage extends SpecialPage {
        }
 
        // select redirects instead of normal pages?
-       public function isRedirect(){
+       public function isRedirect() {
                return $this->isRedir;
        }
 
index 88c81b3..51783a2 100644 (file)
@@ -28,7 +28,7 @@
  * @ingroup SpecialPage
  */
 class SpecialRandomredirect extends RandomPage {
-       function __construct(){
+       function __construct() {
                parent::__construct( 'Randomredirect' );
                $this->isRedir = true;
        }
index a8166db..7ea3a94 100644 (file)
@@ -42,16 +42,16 @@ class SpecialRecentChanges extends IncludableSpecialPage {
        public function getDefaultOptions() {
                $opts = new FormOptions();
 
-               $opts->add( 'days',  (int)$this->getUser()->getOption( 'rcdays' ) );
+               $opts->add( 'days', (int)$this->getUser()->getOption( 'rcdays' ) );
                $opts->add( 'limit', (int)$this->getUser()->getOption( 'rclimit' ) );
                $opts->add( 'from', '' );
 
-               $opts->add( 'hideminor',     $this->getUser()->getBoolOption( 'hideminor' ) );
-               $opts->add( 'hidebots',      true  );
-               $opts->add( 'hideanons',     false );
-               $opts->add( 'hideliu',       false );
+               $opts->add( 'hideminor', $this->getUser()->getBoolOption( 'hideminor' ) );
+               $opts->add( 'hidebots', true  );
+               $opts->add( 'hideanons', false );
+               $opts->add( 'hideliu', false );
                $opts->add( 'hidepatrolled', $this->getUser()->getBoolOption( 'hidepatrolled' ) );
-               $opts->add( 'hidemyself',    false );
+               $opts->add( 'hidemyself', false );
 
                $opts->add( 'namespace', '', FormOptions::INTNULL );
                $opts->add( 'invert', false );
@@ -155,7 +155,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                // Fetch results, prepare a batch link existence check query
                $conds = $this->buildMainQueryConds( $opts );
                $rows = $this->doMainQuery( $conds, $opts );
-               if( $rows === false ){
+               if( $rows === false ) {
                        if( !$this->including() ) {
                                $this->doHeader( $opts );
                        }
@@ -186,7 +186,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
         *
         * @return Array
         */
-       public function getFeedObject( $feedFormat ){
+       public function getFeedObject( $feedFormat ) {
                $changesFeed = new ChangesFeed( $feedFormat, 'rcfeed' );
                $formatter = $changesFeed->getFeedObject(
                        $this->msg( 'recentchanges' )->inContentLanguage()->text(),
@@ -232,7 +232,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                        }
 
                        if( is_numeric( $bit ) ) {
-                               $opts['limit'] =  $bit;
+                               $opts['limit'] = $bit;
                        }
 
                        $m = array();
@@ -281,9 +281,9 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                # It makes no sense to hide both anons and logged-in users
                # Where this occurs, force anons to be shown
                $forcebot = false;
-               if( $opts['hideanons'] && $opts['hideliu'] ){
+               if( $opts['hideanons'] && $opts['hideliu'] ) {
                        # Check if the user wants to show bots only
-                       if( $opts['hidebots'] ){
+                       if( $opts['hidebots'] ) {
                                $opts['hideanons'] = false;
                        } else {
                                $forcebot = true;
@@ -296,9 +296,9 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                $cutoff_unixtime = $cutoff_unixtime - ($cutoff_unixtime % 86400);
                $cutoff = $dbr->timestamp( $cutoff_unixtime );
 
-               $fromValid = preg_match('/^[0-9]{14}$/', $opts['from']);
-               if( $fromValid && $opts['from'] > wfTimestamp(TS_MW,$cutoff) ) {
-                       $cutoff = $dbr->timestamp($opts['from']);
+               $fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
+               if( $fromValid && $opts['from'] > wfTimestamp( TS_MW, $cutoff ) ) {
+                       $cutoff = $dbr->timestamp( $opts['from'] );
                } else {
                        $opts->reset( 'from' );
                }
@@ -351,8 +351,8 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                                        MWNamespace::getAssociated( $opts['namespace'] )
                                );
                                $condition = "(rc_namespace $operator $selectedNS "
-                                                  . $boolean
-                                                  . " rc_namespace $operator $associatedNS)";
+                                       . $boolean
+                                       . " rc_namespace $operator $associatedNS)";
                        }
 
                        $conds[] = $condition;
@@ -387,7 +387,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                        $tables[] = 'watchlist';
                        $fields[] = 'wl_user';
                        $fields[] = 'wl_notificationtimestamp';
-                       $join_conds['watchlist'] = array('LEFT JOIN', array(
+                       $join_conds['watchlist'] = array( 'LEFT JOIN', array(
                                'wl_user' => $uid,
                                'wl_title=rc_title',
                                'wl_namespace=rc_namespace'
@@ -396,7 +396,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                if ( $this->getUser()->isAllowed( 'rollback' ) ) {
                        $tables[] = 'page';
                        $fields[] = 'page_latest';
-                       $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
+                       $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
                }
                // Tag stuff.
                ChangeTags::modifyDisplayQuery(
@@ -545,7 +545,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
 
        /**
         * Get the query string to append to feed link URLs.
-        * 
+        *
         * @return string
         */
        public function getFeedQuery() {
@@ -729,7 +729,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
         * @param $opts FormOptions
         */
        function filterByCategories( &$rows, FormOptions $opts ) {
-               $categories = array_map( 'trim', explode( '|' , $opts['categories'] ) );
+               $categories = array_map( 'trim', explode( '|', $opts['categories'] ) );
 
                if( !count( $categories ) ) {
                        return;
index 4d57bc7..6d7173b 100644 (file)
@@ -29,7 +29,7 @@
 class SpecialRecentchangeslinked extends SpecialRecentChanges {
        var $rclTargetTitle;
 
-       function __construct(){
+       function __construct() {
                parent::__construct( 'Recentchangeslinked' );
        }
 
@@ -50,7 +50,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
                return $opts;
        }
 
-       public function getFeedObject( $feedFormat ){
+       public function getFeedObject( $feedFormat ) {
                $feed = new ChangesFeed( $feedFormat, false );
                $feedObj = $feed->getFeedObject(
                        $this->msg( 'recentchangeslinked-title', $this->getTargetTitle()->getPrefixedText() )
@@ -71,7 +71,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
                }
                $outputPage = $this->getOutput();
                $title = Title::newFromURL( $target );
-               if( !$title || $title->getInterwiki() != '' ){
+               if( !$title || $title->getInterwiki() != '' ) {
                        $outputPage->wrapWikiMsg( "<div class=\"errorbox\">\n$1\n</div><br style=\"clear: both\" />", 'allpagesbadtitle' );
                        return false;
                }
@@ -110,7 +110,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
                }
                if ( $this->getUser()->isAllowed( 'rollback' ) ) {
                        $tables[] = 'page';
-                       $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
+                       $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
                        $select[] = 'page_latest';
                }
                ChangeTags::modifyDisplayQuery(
@@ -204,15 +204,15 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
                        $subsql[] = $query;
                }
 
-               if( count($subsql) == 0 ) {
+               if( count( $subsql ) == 0 ) {
                        return false; // should never happen
                }
-               if( count($subsql) == 1 && $dbr->unionSupportsOrderAndLimit() ) {
+               if( count( $subsql ) == 1 && $dbr->unionSupportsOrderAndLimit() ) {
                        $sql = $subsql[0];
                } else {
                        // need to resort and relimit after union
-                       $sql = $dbr->unionQueries($subsql, false).' ORDER BY rc_timestamp DESC';
-                       $sql = $dbr->limitResult($sql, $limit, false);
+                       $sql = $dbr->unionQueries( $subsql, false ) . ' ORDER BY rc_timestamp DESC';
+                       $sql = $dbr->limitResult( $sql, $limit, false );
                }
 
                $res = $dbr->query( $sql, __METHOD__ );
@@ -228,16 +228,16 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
         * @param $opts FormOptions
         * @return array
         */
-       function getExtraOptions( $opts ){
+       function getExtraOptions( $opts ) {
                $opts->consumeValues( array( 'showlinkedto', 'target', 'tagfilter' ) );
                $extraOpts = array();
                $extraOpts['namespace'] = $this->namespaceFilterForm( $opts );
                $extraOpts['target'] = array( $this->msg( 'recentchangeslinked-page' )->escaped(),
-                       Xml::input( 'target', 40, str_replace('_',' ',$opts['target']) ) .
-                       Xml::check( 'showlinkedto', $opts['showlinkedto'], array('id' => 'showlinkedto') ) . ' ' .
+                       Xml::input( 'target', 40, str_replace( '_', ' ', $opts['target'] ) ) .
+                       Xml::check( 'showlinkedto', $opts['showlinkedto'], array( 'id' => 'showlinkedto' ) ) . ' ' .
                        Xml::label( $this->msg( 'recentchangeslinked-to' )->text(), 'showlinkedto' ) );
                $tagFilter = ChangeTags::buildTagFilterSelector( $opts['tagfilter'] );
-               if ($tagFilter) {
+               if ( $tagFilter ) {
                        $extraOpts['tagfilter'] = $tagFilter;
                }
                return $extraOpts;
index eaf0d52..6f75da4 100644 (file)
@@ -133,7 +133,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        $this->ids = explode( ',', $ids );
                } else {
                        # Array input
-                       $this->ids = array_keys( $request->getArray('ids',array()) );
+                       $this->ids = array_keys( $request->getArray( 'ids', array() ) );
                }
                // $this->ids = array_map( 'intval', $this->ids );
                $this->ids = array_unique( array_filter( $this->ids ) );
@@ -191,7 +191,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
 
                $this->otherReason = $request->getVal( 'wpReason' );
                # We need a target page!
-               if( is_null($this->targetObj) ) {
+               if( is_null( $this->targetObj ) ) {
                        $output->addWikiMsg( 'undelete-header' );
                        return;
                }
@@ -204,7 +204,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
                        array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER )
                );
-               if( $user->isAllowed('suppressrevision') ) {
+               if( $user->isAllowed( 'suppressrevision' ) ) {
                        $this->checks[] = array( 'revdelete-hide-restricted',
                                'wpHideRestricted', Revision::DELETED_RESTRICTED );
                }
@@ -225,7 +225,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                # Show relevant lines from the suppression log
                if( $user->isAllowed( 'suppressionlog' ) ) {
                        $suppressLogPage = new LogPage( 'suppress' );
-                       $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped()  . "</h2>\n" );
+                       $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped() . "</h2>\n" );
                        LogEventsList::showLogExtract( $output, 'suppress',
                                $this->targetObj, '', array( 'lim' => 25, 'conds' => $qc ) );
                }
@@ -253,7 +253,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                                        array( 'action' => 'history' )
                                );
                                # Link to deleted edits
-                               if( $this->getUser()->isAllowed('undelete') ) {
+                               if( $this->getUser()->isAllowed( 'undelete' ) ) {
                                        $undelete = SpecialPage::getTitleFor( 'Undelete' );
                                        $links[] = Linker::linkKnown(
                                                $undelete,
@@ -356,7 +356,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                $UserAllowed = true;
 
                if ( $this->typeName == 'logging' ) {
-                       $this->getOutput()->addWikiMsg( 'logdelete-selected', $this->getLanguage()->formatNum( count($this->ids) ) );
+                       $this->getOutput()->addWikiMsg( 'logdelete-selected', $this->getLanguage()->formatNum( count( $this->ids ) ) );
                } else {
                        $this->getOutput()->addWikiMsg( 'revdelete-selected',
                                $this->targetObj->getPrefixedText(), count( $this->ids ) );
@@ -522,7 +522,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
         */
        protected function submit() {
                # Check edit token on submission
-               $token = $this->getRequest()->getVal('wpEditToken');
+               $token = $this->getRequest()->getVal( 'wpEditToken' );
                if( $this->submitClicked && !$this->getUser()->matchEditToken( $token ) ) {
                        $this->getOutput()->addWikiMsg( 'sessionfailure' );
                        return false;
@@ -537,7 +537,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        $comment = $this->otherReason;
                }
                # Can the user set this field?
-               if( $bitParams[Revision::DELETED_RESTRICTED]==1 && !$this->getUser()->isAllowed('suppressrevision') ) {
+               if( $bitParams[Revision::DELETED_RESTRICTED] == 1 && !$this->getUser()->isAllowed( 'suppressrevision' ) ) {
                        throw new PermissionsError( 'suppressrevision' );
                }
                # If the save went through, go to success message...
@@ -579,14 +579,14 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
        protected function extractBitParams() {
                $bitfield = array();
                foreach( $this->checks as $item ) {
-                       list( /* message */ , $name, $field ) = $item;
+                       list( /* message */, $name, $field ) = $item;
                        $val = $this->getRequest()->getInt( $name, 0 /* unchecked */ );
                        if( $val < -1 || $val > 1) {
                                $val = -1; // -1 for existing value
                        }
                        $bitfield[$field] = $val;
                }
-               if( !isset($bitfield[Revision::DELETED_RESTRICTED]) ) {
+               if( !isset( $bitfield[Revision::DELETED_RESTRICTED] ) ) {
                        $bitfield[Revision::DELETED_RESTRICTED] = 0;
                }
                return $bitfield;
@@ -624,4 +624,3 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                );
        }
 }
-
index bc90d2b..77f0ddb 100644 (file)
@@ -138,7 +138,7 @@ class SpecialSearch extends SpecialPage {
                        // BC with old request format
                        $profile = 'advanced';
                        foreach( $profiles as $key => $data ) {
-                               if ( $nslist === $data['namespaces'] && $key !== 'advanced') {
+                               if ( $nslist === $data['namespaces'] && $key !== 'advanced' ) {
                                        $profile = $key;
                                }
                        }
@@ -159,7 +159,7 @@ class SpecialSearch extends SpecialPage {
                $default = $request->getBool( 'profile' ) ? 0 : 1;
                $this->searchRedirects = $request->getBool( 'redirs', $default ) ? 1 : 0;
                $this->didYouMeanHtml = ''; # html of did you mean... link
-               $this->fulltext = $request->getVal('fulltext');
+               $this->fulltext = $request->getVal( 'fulltext' );
                $this->profile = $profile;
        }
 
@@ -218,7 +218,7 @@ class SpecialSearch extends SpecialPage {
                $search->showRedirects = $this->searchRedirects; // BC
                $search->setFeatureData( 'list-redirects', $this->searchRedirects );
                $search->prefix = $this->mPrefix;
-               $term = $search->transformSearchTerm($term);
+               $term = $search->transformSearchTerm( $term );
 
                wfRunHooks( 'SpecialSearchSetupEngine', array( $this, $this->profile, $search ) );
 
@@ -250,7 +250,7 @@ class SpecialSearch extends SpecialPage {
                $t = Title::newFromText( $term );
 
                // fetch search results
-               $rewritten = $search->replacePrefixes($term);
+               $rewritten = $search->replacePrefixes( $term );
 
                $titleMatches = $search->searchTitle( $rewritten );
                if( !( $titleMatches instanceof SearchResultTooMany ) ) {
@@ -311,9 +311,9 @@ class SpecialSearch extends SpecialPage {
                        Xml::openElement( 'tr' ) .
                        Xml::openElement( 'td' ) . "\n" .
                        $this->shortDialog( $term ) .
-                       Xml::closeElement('td') .
-                       Xml::closeElement('tr') .
-                       Xml::closeElement('table')
+                       Xml::closeElement( 'td' ) .
+                       Xml::closeElement( 'tr' ) .
+                       Xml::closeElement( 'table' )
                );
 
                // Sometimes the search engine knows there are too many hits
@@ -323,7 +323,7 @@ class SpecialSearch extends SpecialPage {
                        return;
                }
 
-               $filePrefix = $wgContLang->getFormattedNsText(NS_FILE).':';
+               $filePrefix = $wgContLang->getFormattedNsText( NS_FILE ) . ':';
                if( trim( $term ) === '' || $filePrefix === trim( $term ) ) {
                        $out->addHTML( $this->formHeader( $term, 0, 0 ) );
                        $out->addHtml( $this->getProfileForm( $this->profile, $term ) );
@@ -347,9 +347,9 @@ class SpecialSearch extends SpecialPage {
 
                // get total number of results if backend can calculate it
                $totalRes = 0;
-               if($titleMatches && !is_null( $titleMatches->getTotalHits() ) )
+               if( $titleMatches && !is_null( $titleMatches->getTotalHits() ) )
                        $totalRes += $titleMatches->getTotalHits();
-               if($textMatches && !is_null( $textMatches->getTotalHits() ))
+               if( $textMatches && !is_null( $textMatches->getTotalHits() ) )
                        $totalRes += $textMatches->getTotalHits();
 
                // show number of results and current offset
@@ -455,7 +455,7 @@ class SpecialSearch extends SpecialPage {
                # Should advanced UI be used?
                $this->searchAdvanced = ($this->profile === 'advanced');
                $out = $this->getOutput();
-               if( strval( $term ) !== ''  ) {
+               if( strval( $term ) !== '' ) {
                        $out->setPageTitle( $this->msg( 'searchresults' ) );
                        $out->setHTMLTitle( $this->msg( 'pagetitle' )->rawParams(
                                $this->msg( 'searchresults-title' )->rawParams( $term )->text()
@@ -516,7 +516,7 @@ class SpecialSearch extends SpecialPage {
 
                $out = "";
                $infoLine = $matches->getInfo();
-               if( !is_null($infoLine) ) {
+               if( !is_null( $infoLine ) ) {
                        $out .= "\n<!-- {$infoLine} -->\n";
                }
                $out .= "<ul class='mw-search-results'>\n";
@@ -551,7 +551,7 @@ class SpecialSearch extends SpecialPage {
 
                $t = $result->getTitle();
 
-               $titleSnippet = $result->getTitleSnippet($terms);
+               $titleSnippet = $result->getTitleSnippet( $terms );
 
                if( $titleSnippet == '' )
                        $titleSnippet = null;
@@ -584,12 +584,12 @@ class SpecialSearch extends SpecialPage {
 
                // format redirects / relevant sections
                $redirectTitle = $result->getRedirectTitle();
-               $redirectText = $result->getRedirectSnippet($terms);
+               $redirectText = $result->getRedirectSnippet( $terms );
                $sectionTitle = $result->getSectionTitle();
-               $sectionText = $result->getSectionSnippet($terms);
+               $sectionText = $result->getSectionSnippet( $terms );
                $redirect = '';
 
-               if( !is_null($redirectTitle) ) {
+               if( !is_null( $redirectTitle ) ) {
                        if( $redirectText == '' )
                                $redirectText = null;
 
@@ -601,7 +601,7 @@ class SpecialSearch extends SpecialPage {
 
                $section = '';
 
-               if( !is_null($sectionTitle) ) {
+               if( !is_null( $sectionTitle ) ) {
                        if( $sectionText == '' )
                                $sectionText = null;
 
@@ -612,7 +612,7 @@ class SpecialSearch extends SpecialPage {
                }
 
                // format text extract
-               $extract = "<div class='searchresult'>".$result->getTextSnippet($terms)."</div>";
+               $extract = "<div class='searchresult'>" . $result->getTextSnippet( $terms ) . "</div>";
 
                $lang = $this->getLanguage();
 
@@ -723,16 +723,17 @@ class SpecialSearch extends SpecialPage {
                $terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
 
                $out = "<div id='mw-search-interwiki'><div id='mw-search-interwiki-caption'>".
-                       $this->msg( 'search-interwiki-caption' )->text()  . "</div>\n";
+                       $this->msg( 'search-interwiki-caption' )->text() . "</div>\n";
                $out .= "<ul class='mw-search-iwresults'>\n";
 
                // work out custom project captions
                $customCaptions = array();
                $customLines = explode( "\n", $this->msg( 'search-interwiki-custom' )->text() ); // format per line <iwprefix>:<caption>
-               foreach($customLines as $line) {
-                       $parts = explode(":",$line,2);
-                       if(count($parts) == 2) // validate line
+               foreach( $customLines as $line ) {
+                       $parts = explode( ":", $line, 2 );
+                       if( count( $parts ) == 2 ) { // validate line
                                $customCaptions[$parts[0]] = $parts[1];
+                       }
                }
 
                $prev = null;
@@ -772,7 +773,7 @@ class SpecialSearch extends SpecialPage {
 
                $t = $result->getTitle();
 
-               $titleSnippet = $result->getTitleSnippet($terms);
+               $titleSnippet = $result->getTitleSnippet( $terms );
 
                if( $titleSnippet == '' )
                        $titleSnippet = null;
@@ -784,9 +785,9 @@ class SpecialSearch extends SpecialPage {
 
                // format redirect if any
                $redirectTitle = $result->getRedirectTitle();
-               $redirectText = $result->getRedirectSnippet($terms);
+               $redirectText = $result->getRedirectSnippet( $terms );
                $redirect = '';
-               if( !is_null($redirectTitle) ) {
+               if( !is_null( $redirectTitle ) ) {
                        if( $redirectText == '' )
                                $redirectText = null;
 
@@ -798,8 +799,8 @@ class SpecialSearch extends SpecialPage {
 
                $out = "";
                // display project name
-               if(is_null($lastInterwiki) || $lastInterwiki != $t->getInterwiki()) {
-                       if( array_key_exists($t->getInterwiki(),$customCaptions) ) {
+               if( is_null( $lastInterwiki ) || $lastInterwiki != $t->getInterwiki() ) {
+                       if( array_key_exists( $t->getInterwiki(), $customCaptions ) ) {
                                // captions from 'search-interwiki-custom'
                                $caption = $customCaptions[$t->getInterwiki()];
                        } else {
@@ -809,7 +810,7 @@ class SpecialSearch extends SpecialPage {
                                $caption = $this->msg( 'search-interwiki-default', $parsed['host'] )->text();
                        }
                        // "more results" link (special page stuff could be localized, but we might not know target lang)
-                       $searchTitle = Title::newFromText($t->getInterwiki().":Special:Search");
+                       $searchTitle = Title::newFromText( $t->getInterwiki() . ":Special:Search" );
                        $searchLink = Linker::linkKnown(
                                $searchTitle,
                                $this->msg( 'search-interwiki-more' )->text(),
@@ -917,7 +918,7 @@ class SpecialSearch extends SpecialPage {
                                'fieldset',
                                array( 'id' => 'mw-searchoptions', 'style' => 'margin:0em;' )
                        ) .
-                       Xml::element( 'legend', null, $this->msg('powersearch-legend' )->text() ) .
+                       Xml::element( 'legend', null, $this->msg( 'powersearch-legend' )->text() ) .
                        Xml::tags( 'h4', null, $this->msg( 'powersearch-ns' )->parse() ) .
                        Html::element( 'div', array( 'id' => 'mw-search-togglebox' ) ) .
                        Xml::element( 'div', array( 'class' => 'divider' ), '', false ) .
@@ -984,7 +985,7 @@ class SpecialSearch extends SpecialPage {
         * @return string
         */
        protected function formHeader( $term, $resultsShown, $totalNum ) {
-               $out = Xml::openElement('div', array( 'class' =>  'mw-search-formheader' ) );
+               $out = Xml::openElement( 'div', array( 'class' => 'mw-search-formheader' ) );
 
                $bareterm = $term;
                if( $this->startsWithImage( $term ) ) {
@@ -1021,11 +1022,11 @@ class SpecialSearch extends SpecialPage {
                        );
                }
                $out .= Xml::closeElement( 'ul' );
-               $out .= Xml::closeElement('div') ;
+               $out .= Xml::closeElement( 'div' );
 
                // Results-info
                if ( $resultsShown > 0 ) {
-                       if ( $totalNum > 0 ){
+                       if ( $totalNum > 0 ) {
                                $top = $this->msg( 'showingresultsheader' )
                                        ->numParams( $this->offset + 1, $this->offset + $resultsShown, $totalNum )
                                        ->params( wfEscapeWikiText( $term ) )
@@ -1046,7 +1047,7 @@ class SpecialSearch extends SpecialPage {
                }
 
                $out .= Xml::element( 'div', array( 'style' => 'clear:both' ), '', false );
-               $out .= Xml::closeElement('div');
+               $out .= Xml::closeElement( 'div' );
 
                return $out;
        }
@@ -1131,7 +1132,7 @@ class SpecialSearch extends SpecialPage {
 
                $p = explode( ':', $term );
                if( count( $p ) > 1 ) {
-                       return $p[0]  == $allkeyword;
+                       return $p[0] == $allkeyword;
                }
                return false;
        }
index 1e7c8bb..d80218f 100644 (file)
@@ -122,7 +122,7 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
                                        $pageClasses[] = 'mw-specialpagerestricted';
                                }
 
-                               $link = Linker::linkKnown( $title , htmlspecialchars( $desc ) );
+                               $link = Linker::linkKnown( $title, htmlspecialchars( $desc ) );
                                $out->addHTML( Html::rawElement( 'li', array( 'class' => implode( ' ', $pageClasses ) ), $link ) . "\n" );
 
                                # Split up the larger groups
index 46881ec..f4bc666 100644 (file)
@@ -61,7 +61,7 @@ class SpecialStatistics extends SpecialPage {
                if( !$wgMiserMode ) {
                        $key = wfMemcKey( 'sitestats', 'activeusers-updated' );
                        // Re-calculate the count if the last tally is old...
-                       if( !$wgMemc->get($key) ) {
+                       if( !$wgMemc->get( $key ) ) {
                                $dbw = wfGetDB( DB_MASTER );
                                SiteStatsUpdate::cacheUpdate( $dbw );
                                $wgMemc->set( $key, '1', 24*3600 ); // don't update for 1 day
@@ -222,7 +222,7 @@ class SpecialStatistics extends SpecialPage {
                        }
                        $text .= $this->formatRow( $grouppage . ' ' . $grouplink,
                                $this->getLanguage()->formatNum( $countUsers ),
-                               array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero )  );
+                               array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero ) );
                }
                return $text;
        }
index 853a805..076469c 100644 (file)
@@ -32,11 +32,11 @@ class SpecialUnblock extends SpecialPage {
        protected $type;
        protected $block;
 
-       public function __construct(){
+       public function __construct() {
                parent::__construct( 'Unblock', 'block' );
        }
 
-       public function execute( $par ){
+       public function execute( $par ) {
                $this->checkPermissions();
                $this->checkReadOnly();
 
@@ -56,8 +56,8 @@ class SpecialUnblock extends SpecialPage {
                $form->setSubmitTextMsg( 'ipusubmit' );
                $form->addPreText( $this->msg( 'unblockiptext' )->parseAsBlock() );
 
-               if( $form->show() ){
-                       switch( $this->type ){
+               if( $form->show() ) {
+                       switch( $this->type ) {
                                case Block::TYPE_USER:
                                case Block::TYPE_IP:
                                        $out->addWikiMsg( 'unblocked', wfEscapeWikiText( $this->target ) );
@@ -73,7 +73,7 @@ class SpecialUnblock extends SpecialPage {
                }
        }
 
-       protected function getFields(){
+       protected function getFields() {
                $fields = array(
                        'Target' => array(
                                'type' => 'text',
@@ -92,21 +92,21 @@ class SpecialUnblock extends SpecialPage {
                        )
                );
 
-               if( $this->block instanceof Block ){
+               if( $this->block instanceof Block ) {
                        list( $target, $type ) = $this->block->getTargetAndType();
 
                        # Autoblocks are logged as "autoblock #123 because the IP was recently used by
                        # User:Foo, and we've just got any block, auto or not, that applies to a target
                        # the user has specified.  Someone could be fishing to connect IPs to autoblocks,
                        # so don't show any distinction between unblocked IPs and autoblocked IPs
-                       if( $type == Block::TYPE_AUTO && $this->type == Block::TYPE_IP ){
+                       if( $type == Block::TYPE_AUTO && $this->type == Block::TYPE_IP ) {
                                $fields['Target']['default'] = $this->target;
                                unset( $fields['Name'] );
 
                        } else {
                                $fields['Target']['default'] = $target;
                                $fields['Target']['type'] = 'hidden';
-                               switch( $type ){
+                               switch( $type ) {
                                        case Block::TYPE_USER:
                                        case Block::TYPE_IP:
                                                $fields['Name']['default'] = Linker::link(
@@ -152,12 +152,12 @@ class SpecialUnblock extends SpecialPage {
         * @throws ErrorPageError
         * @return Array( Array(message key, parameters) ) on failure, True on success
         */
-       public static function processUnblock( array $data, IContextSource $context ){
+       public static function processUnblock( array $data, IContextSource $context ) {
                $performer = $context->getUser();
                $target = $data['Target'];
                $block = Block::newFromTarget( $data['Target'] );
 
-               if( !$block instanceof Block ){
+               if( !$block instanceof Block ) {
                        return array( array( 'ipb_cant_unblock', $target ) );
                }
 
@@ -173,8 +173,8 @@ class SpecialUnblock extends SpecialPage {
                # unblock the whole range.
                list( $target, $type ) = SpecialBlock::getTargetAndType( $target );
                if( $block->getType() == Block::TYPE_RANGE && $type == Block::TYPE_IP ) {
-                        $range = $block->getTarget();
-                        return array( array( 'ipb_blocked_as_range', $target, $range ) );
+                       $range = $block->getTarget();
+                       return array( array( 'ipb_blocked_as_range', $target, $range ) );
                }
 
                # If the name was hidden and the blocking user cannot hide
index d2d91bd..54b20dd 100644 (file)
@@ -43,5 +43,5 @@ class UncategorizedCategoriesPage extends UncategorizedPagesPage {
                $text = $title->getText();
 
                return Linker::linkKnown( $title, htmlspecialchars( $text ) );
-        }
+       }
 }
index 1ea6e46..afc41bf 100644 (file)
@@ -138,7 +138,7 @@ class PageArchive {
                $res = $dbr->select( 'archive',
                        $fields,
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey() ),
+                               'ar_title' => $this->title->getDBkey() ),
                        __METHOD__,
                        array( 'ORDER BY' => 'ar_timestamp DESC' ) );
                $ret = $dbr->resultObject( $res );
@@ -156,27 +156,9 @@ class PageArchive {
        function listFiles() {
                if( $this->title->getNamespace() == NS_FILE ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $res = $dbr->select( 'filearchive',
-                               array(
-                                       'fa_id',
-                                       'fa_name',
-                                       'fa_archive_name',
-                                       'fa_storage_key',
-                                       'fa_storage_group',
-                                       'fa_size',
-                                       'fa_width',
-                                       'fa_height',
-                                       'fa_bits',
-                                       'fa_metadata',
-                                       'fa_media_type',
-                                       'fa_major_mime',
-                                       'fa_minor_mime',
-                                       'fa_description',
-                                       'fa_user',
-                                       'fa_user_text',
-                                       'fa_timestamp',
-                                       'fa_deleted',
-                                       'fa_sha1' ),
+                       $res = $dbr->select(
+                               'filearchive',
+                               ArchivedFile::selectFields(),
                                array( 'fa_name' => $this->title->getDBkey() ),
                                __METHOD__,
                                array( 'ORDER BY' => 'fa_timestamp DESC' ) );
@@ -248,9 +230,9 @@ class PageArchive {
                $row = $dbr->selectRow( 'archive',
                        'ar_timestamp',
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey(),
-                                  'ar_timestamp < ' .
-                                               $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ),
+                               'ar_title' => $this->title->getDBkey(),
+                               'ar_timestamp < ' .
+                                       $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ),
                        __METHOD__,
                        array(
                                'ORDER BY' => 'ar_timestamp DESC',
@@ -319,7 +301,7 @@ class PageArchive {
                $row = $dbr->selectRow( 'archive',
                        array( 'ar_text', 'ar_flags', 'ar_text_id' ),
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey() ),
+                               'ar_title' => $this->title->getDBkey() ),
                        __METHOD__,
                        array( 'ORDER BY' => 'ar_timestamp DESC' ) );
                if( $row ) {
@@ -338,7 +320,7 @@ class PageArchive {
                $dbr = wfGetDB( DB_SLAVE );
                $n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey() ),
+                               'ar_title' => $this->title->getDBkey() ),
                        __METHOD__
                );
                return ( $n > 0 );
@@ -457,7 +439,7 @@ class PageArchive {
                $page = $dbw->selectRow( 'page',
                        array( 'page_id', 'page_latest' ),
                        array( 'page_namespace' => $this->title->getNamespace(),
-                                  'page_title'     => $this->title->getDBkey() ),
+                               'page_title' => $this->title->getDBkey() ),
                        __METHOD__,
                        array( 'FOR UPDATE' ) // lock page
                );
@@ -474,7 +456,7 @@ class PageArchive {
                                __METHOD__ );
 
                        if( $previousTimestamp === false ) {
-                               wfDebug( __METHOD__.": existing page refers to a page_latest that does not exist\n" );
+                               wfDebug( __METHOD__ . ": existing page refers to a page_latest that does not exist\n" );
 
                                $status = Status::newGood( 0 );
                                $status->warning( 'undeleterevision-missing' );
@@ -512,7 +494,8 @@ class PageArchive {
                        'ar_deleted',
                        'ar_page_id',
                        'ar_len',
-                       'ar_sha1');
+                       'ar_sha1'
+               );
 
                if ( $wgContentHandlerUseDB ) {
                        $fields[] = 'ar_content_format';
@@ -1075,10 +1058,10 @@ class SpecialUndelete extends SpecialPage {
                                        $targetQuery
                                ) .
                        '</strong></div>' .
-                       '<div id="mw-diff-'.$prefix.'title2">' .
+                       '<div id="mw-diff-' . $prefix . 'title2">' .
                                Linker::revUserTools( $rev ) . '<br />' .
                        '</div>' .
-                       '<div id="mw-diff-'.$prefix.'title3">' .
+                       '<div id="mw-diff-' . $prefix . 'title3">' .
                                Linker::revComment( $rev ) . $rdel . '<br />' .
                        '</div>';
        }
@@ -1230,7 +1213,7 @@ class SpecialUndelete extends SpecialPage {
                                                        Xml::label( $this->msg( 'undeletecomment' )->text(), 'wpComment' ) .
                                                "</td>
                                                <td class='mw-input'>" .
-                                                       Xml::input( 'wpComment', 50, $this->mComment, array( 'id' =>  'wpComment' ) ) .
+                                                       Xml::input( 'wpComment', 50, $this->mComment, array( 'id' => 'wpComment' ) ) .
                                                "</td>
                                        </tr>
                                        <tr>
@@ -1348,7 +1331,7 @@ class SpecialUndelete extends SpecialPage {
                // Revision delete links
                $revdlink = Linker::getRevDeleteLink( $user, $rev, $this->mTargetObj );
 
-               $revisionRow = $this->msg( 'undelete-revisionrow' )->rawParams( $checkBox, $revdlink, $last, $pageLink , $userLink, $revTextSize, $comment )->escaped();
+               $revisionRow = $this->msg( 'undelete-revisionrow' )->rawParams( $checkBox, $revdlink, $last, $pageLink, $userLink, $revTextSize, $comment )->escaped();
                return "<li>$revisionRow</li>";
        }
 
index 73c7e2a..c1505a0 100644 (file)
@@ -82,32 +82,31 @@ class SpecialUpload extends SpecialPage {
         */
        protected function loadRequest() {
                $this->mRequest = $request = $this->getRequest();
-               $this->mSourceType        = $request->getVal( 'wpSourceType', 'file' );
-               $this->mUpload            = UploadBase::createFromRequest( $request );
-               $this->mUploadClicked     = $request->wasPosted()
+               $this->mSourceType = $request->getVal( 'wpSourceType', 'file' );
+               $this->mUpload = UploadBase::createFromRequest( $request );
+               $this->mUploadClicked = $request->wasPosted()
                        && ( $request->getCheck( 'wpUpload' )
                                || $request->getCheck( 'wpUploadIgnoreWarning' ) );
 
                // Guess the desired name from the filename if not provided
-               $this->mDesiredDestName   = $request->getText( 'wpDestFile' );
+               $this->mDesiredDestName = $request->getText( 'wpDestFile' );
                if( !$this->mDesiredDestName && $request->getFileName( 'wpUploadFile' ) !== null ) {
                        $this->mDesiredDestName = $request->getFileName( 'wpUploadFile' );
                }
-               $this->mComment           = $request->getText( 'wpUploadDescription' );
-               $this->mLicense           = $request->getText( 'wpLicense' );
+               $this->mComment = $request->getText( 'wpUploadDescription' );
+               $this->mLicense = $request->getText( 'wpLicense' );
 
-
-               $this->mDestWarningAck    = $request->getText( 'wpDestFileWarningAck' );
-               $this->mIgnoreWarning     = $request->getCheck( 'wpIgnoreWarning' )
+               $this->mDestWarningAck = $request->getText( 'wpDestFileWarningAck' );
+               $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' )
                        || $request->getCheck( 'wpUploadIgnoreWarning' );
-               $this->mWatchthis         = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isLoggedIn();
-               $this->mCopyrightStatus   = $request->getText( 'wpUploadCopyStatus' );
-               $this->mCopyrightSource   = $request->getText( 'wpUploadSource' );
+               $this->mWatchthis = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isLoggedIn();
+               $this->mCopyrightStatus = $request->getText( 'wpUploadCopyStatus' );
+               $this->mCopyrightSource = $request->getText( 'wpUploadSource' );
 
 
-               $this->mForReUpload       = $request->getBool( 'wpForReUpload' ); // updating a file
-               $this->mCancelUpload      = $request->getCheck( 'wpCancelUpload' )
-                                                                || $request->getCheck( 'wpReUpload' ); // b/w compat
+               $this->mForReUpload = $request->getBool( 'wpForReUpload' ); // updating a file
+               $this->mCancelUpload = $request->getCheck( 'wpCancelUpload' )
+                       || $request->getCheck( 'wpReUpload' ); // b/w compat
 
                // If it was posted check for the token (no remote POST'ing with user credentials)
                $token = $request->getVal( 'wpEditToken' );
@@ -246,9 +245,9 @@ class SpecialUpload extends SpecialPage {
                        LogEventsList::showLogExtract( $delNotice, array( 'delete', 'move' ),
                                $desiredTitleObj,
                                '', array( 'lim' => 10,
-                                          'conds' => array( "log_action != 'revision'" ),
-                                          'showIfEmpty' => false,
-                                          'msgKey' => array( 'upload-recreate-warning' ) )
+                                       'conds' => array( "log_action != 'revision'" ),
+                                       'showIfEmpty' => false,
+                                       'msgKey' => array( 'upload-recreate-warning' ) )
                        );
                }
                $form->addPreText( $delNotice );
@@ -476,17 +475,17 @@ class SpecialUpload extends SpecialPage {
                if ( $wgUseCopyrightUpload ) {
                        $licensetxt = '';
                        if ( $license != '' ) {
-                               $licensetxt = '== ' . $msg[ 'license-header' ] . " ==\n" . '{{' . $license . '}}' . "\n";
+                               $licensetxt = '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
                        }
-                       $pageText = '== ' . $msg[ 'filedesc' ] . " ==\n" . $comment . "\n" .
-                               '== ' . $msg[ 'filestatus' ] . " ==\n" . $copyStatus . "\n" .
+                       $pageText = '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n" .
+                               '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n" .
                                "$licensetxt" .
-                               '== ' . $msg[ 'filesource' ] . " ==\n" . $source;
+                               '== ' . $msg['filesource'] . " ==\n" . $source;
                } else {
                        if ( $license != '' ) {
-                               $filedesc = $comment == '' ? '' : '== ' . $msg[ 'filedesc' ] . " ==\n" . $comment . "\n";
+                               $filedesc = $comment == '' ? '' : '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n";
                                        $pageText = $filedesc .
-                                       '== ' . $msg[ 'license-header' ] . " ==\n" . '{{' . $license . '}}' . "\n";
+                                       '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
                        } else {
                                $pageText = $comment;
                        }
@@ -1142,4 +1141,3 @@ class UploadSourceField extends HTMLTextField {
                        : 60;
        }
 }
-
index 3f9851e..31f9669 100644 (file)
@@ -349,7 +349,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
                                'name' => 'clear',
                        )
                ), $this->getContext(), 'clearStashedUploads' );
-               $form->setSubmitCallback( array( __CLASS__ , 'tryClearStashedUploads' ) );
+               $form->setSubmitCallback( array( __CLASS__, 'tryClearStashedUploads' ) );
                $form->setTitle( $this->getTitle() );
                $form->setSubmitTextMsg( 'uploadstash-clear' );
 
index 3a73ebd..27701d4 100644 (file)
@@ -95,9 +95,9 @@ class LoginForm extends SpecialPage {
                $this->mReason = $request->getText( 'wpReason' );
                $this->mCookieCheck = $request->getVal( 'wpCookieCheck' );
                $this->mPosted = $request->wasPosted();
-               $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' );
                $this->mCreateaccountMail = $request->getCheck( 'wpCreateaccountMail' )
                                                                        && $wgEnableEmail;
+               $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' ) && !$this->mCreateaccountMail;
                $this->mLoginattempt = $request->getCheck( 'wpLoginattempt' );
                $this->mAction = $request->getVal( 'action' );
                $this->mRemember = $request->getCheck( 'wpRemember' );
@@ -212,7 +212,7 @@ class LoginForm extends SpecialPage {
                $result = $this->mailPasswordInternal( $u, false, 'createaccount-title', 'createaccount-text' );
 
                wfRunHooks( 'AddNewAccount', array( $u, true ) );
-               $u->addNewUserLogEntry( true, $this->mReason );
+               $u->addNewUserLogEntry( 'byemail', $this->mReason );
 
                $out = $this->getOutput();
                $out->setPageTitle( $this->msg( 'accmailtitle' ) );
@@ -274,7 +274,7 @@ class LoginForm extends SpecialPage {
                        // wrong.
                        $this->getContext()->setUser( $u );
                        wfRunHooks( 'AddNewAccount', array( $u, false ) );
-                       $u->addNewUserLogEntry();
+                       $u->addNewUserLogEntry( 'create' );
                        if( $this->hasSessionCookie() ) {
                                $this->successfulCreation();
                        } else {
@@ -286,7 +286,7 @@ class LoginForm extends SpecialPage {
                        $out->addWikiMsg( 'accountcreatedtext', $u->getName() );
                        $out->addReturnTo( $this->getTitle() );
                        wfRunHooks( 'AddNewAccount', array( $u, false ) );
-                       $u->addNewUserLogEntry( false, $this->mReason );
+                       $u->addNewUserLogEntry( 'create2', $this->mReason );
                }
                return true;
        }
@@ -314,8 +314,10 @@ class LoginForm extends SpecialPage {
                if( 'local' != $this->mDomain && $this->mDomain != '' ) {
                        if(
                                !$wgAuth->canCreateAccounts() &&
-                               ( !$wgAuth->userExists( $this->mUsername ||
-                                 !$wgAuth->authenticate( $this->mUsername, $this->mPassword ) ) )
+                               (
+                                       !$wgAuth->userExists( $this->mUsername ) ||
+                                       !$wgAuth->authenticate( $this->mUsername, $this->mPassword )
+                               )
                        ) {
                                return Status::newFatal( 'wrongpassword' );
                        }
@@ -371,32 +373,34 @@ class LoginForm extends SpecialPage {
                        return Status::newFatal( 'noname' );
                } elseif ( 0 != $u->idForName() ) {
                        return Status::newFatal( 'userexists' );
-               } elseif ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
-                       return Status::newFatal( 'badretype' );
                }
 
-               # check for minimal password length
-               $valid = $u->getPasswordValidity( $this->mPassword );
-               if ( $valid !== true ) {
-                       if ( !$this->mCreateaccountMail ) {
+               if ( $this->mCreateaccountMail ) {
+                       # do not force a password for account creation by email
+                       # set invalid password, it will be replaced later by a random generated password
+                       $this->mPassword = null;
+               } else {
+                       if ( $this->mPassword !== $this->mRetype ) {
+                               return Status::newFatal( 'badretype' );
+                       }
+
+                       # check for minimal password length
+                       $valid = $u->getPasswordValidity( $this->mPassword );
+                       if ( $valid !== true ) {
                                if ( !is_array( $valid ) ) {
                                        $valid = array( $valid, $wgMinimalPasswordLength );
                                }
                                return call_user_func_array( 'Status::newFatal', $valid );
-                       } else {
-                               # do not force a password for account creation by email
-                               # set invalid password, it will be replaced later by a random generated password
-                               $this->mPassword = null;
                        }
                }
 
                # if you need a confirmed email address to edit, then obviously you
                # need an email address.
-               if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) {
+               if ( $wgEmailConfirmToEdit && strval( $this->mEmail ) === '' ) {
                        return Status::newFatal( 'noemailtitle' );
                }
 
-               if( !empty( $this->mEmail ) && !Sanitizer::validateEmail( $this->mEmail ) ) {
+               if ( strval( $this->mEmail ) !== '' && !Sanitizer::validateEmail( $this->mEmail ) ) {
                        return Status::newFatal( 'invalidemailaddress' );
                }
 
@@ -828,7 +832,7 @@ class LoginForm extends SpecialPage {
        }
 
        function resetLoginForm( $error ) {
-               $this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $error ) );
+               $this->getOutput()->addHTML( Xml::element( 'p', array( 'class' => 'error' ), $error ) );
                $reset = new SpecialChangePassword();
                $reset->setContext( $this->getContext() );
                $reset->execute( null );
@@ -1011,7 +1015,7 @@ class LoginForm extends SpecialPage {
                global $wgEnableEmail, $wgEnableUserEmail;
                global $wgHiddenPrefs, $wgLoginLanguageSelector;
                global $wgAuth, $wgEmailConfirmToEdit, $wgCookieExpiration;
-               global $wgSecureLogin, $wgPasswordResetRoutes;
+               global $wgSecureLogin, $wgSecureLoginDefaultHTTPS, $wgPasswordResetRoutes;
 
                $titleObj = $this->getTitle();
                $user = $this->getUser();
@@ -1031,7 +1035,8 @@ class LoginForm extends SpecialPage {
                        }
                }
 
-               if ( $this->mUsername == '' ) {
+               // Pre-fill username (if not creating an account, bug 44775).
+               if ( $this->mUsername == '' && $this->mType != 'signup' ) {
                        if ( $user->isLoggedIn() ) {
                                $this->mUsername = $user->getName();
                        } else {
@@ -1044,6 +1049,7 @@ class LoginForm extends SpecialPage {
                        $q = 'action=submitlogin&type=signup';
                        $linkq = 'type=login';
                        $linkmsg = 'gotaccount';
+                       $this->getOutput()->addModules( 'mediawiki.special.userlogin.signup' );
                } else {
                        $template = new UserloginTemplate();
                        $q = 'action=submitlogin&type=login';
@@ -1075,6 +1081,11 @@ class LoginForm extends SpecialPage {
                        $template->set( 'link', '' );
                }
 
+               // Decide if we default stickHTTPS on
+               if ( $wgSecureLoginDefaultHTTPS && $this->mAction != 'submitlogin' && !$this->mLoginattempt ) {
+                       $this->mStickHTTPS = true;
+               }
+
                $resetLink = $this->mType == 'signup'
                        ? null
                        : is_array( $wgPasswordResetRoutes ) && in_array( true, array_values( $wgPasswordResetRoutes ) );
@@ -1083,6 +1094,7 @@ class LoginForm extends SpecialPage {
                $template->set( 'name', $this->mUsername );
                $template->set( 'password', $this->mPassword );
                $template->set( 'retype', $this->mRetype );
+               $template->set( 'createemailset', $this->mCreateaccountMail );
                $template->set( 'email', $this->mEmail );
                $template->set( 'realname', $this->mRealName );
                $template->set( 'domain', $this->mDomain );
index 121cc22..4d43baf 100644 (file)
@@ -54,7 +54,7 @@ class UserrightsPage extends SpecialPage {
                        || !empty( $available['remove'] )
                        || ( ( $this->isself || !$checkIfSelf ) &&
                                ( !empty( $available['add-self'] )
-                                || !empty( $available['remove-self'] ) ) );
+                                       || !empty( $available['remove-self'] ) ) );
        }
 
        /**
@@ -379,7 +379,7 @@ class UserrightsPage extends SpecialPage {
                global $wgScript;
                $this->getOutput()->addHTML(
                        Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'name' => 'uluser', 'id' => 'mw-userrights-form1' ) ) .
-                       Html::hidden( 'title',  $this->getTitle()->getPrefixedText() ) .
+                       Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
                        Xml::fieldset( $this->msg( 'userrights-lookup-user' )->text() ) .
                        Xml::inputLabel( $this->msg( 'userrights-user-editname' )->text(), 'user', 'username', 30, str_replace( '_', ' ', $this->mTarget ) ) . ' ' .
                        Xml::submitButton( $this->msg( 'editusergroup' )->text() ) .
@@ -572,7 +572,7 @@ class UserrightsPage extends SpecialPage {
                                continue;
                        $ret .= Xml::element( 'th', null, $this->msg( 'userrights-' . $name . '-col', count( $column ) )->text() );
                }
-               $ret.= "</tr>\n<tr>\n";
+               $ret .= "</tr>\n<tr>\n";
                foreach( $columns as $column ) {
                        if( $column === array() )
                                continue;
@@ -623,7 +623,7 @@ class UserrightsPage extends SpecialPage {
        /**
         * Returns $this->getUser()->changeableGroups()
         *
-        * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) )
+        * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ), 'add-self' => array( addablegroups to self ), 'remove-self' => array( removable groups from self ) )
         */
        function changeableGroups() {
                return $this->getUser()->changeableGroups();
index 01a12c0..88d647e 100644 (file)
@@ -40,7 +40,7 @@ class SpecialVersion extends SpecialPage {
                'https://svn.wikimedia.org/svnroot/mediawiki' => 'https://svn.wikimedia.org/viewvc/mediawiki',
        );
 
-       public function __construct(){
+       public function __construct() {
                parent::__construct( 'Version' );
        }
 
@@ -114,6 +114,12 @@ class SpecialVersion extends SpecialPage {
        public static function getCopyrightAndAuthorList() {
                global $wgLang;
 
+               if ( defined( 'MEDIAWIKI_INSTALL' ) ) {
+                       $othersLink = '[http://www.mediawiki.org/wiki/Special:Version/Credits ' .       wfMessage( 'version-poweredby-others' )->text() . ']';
+               } else {
+                       $othersLink = '[[Special:Version/Credits|' . wfMessage( 'version-poweredby-others' )->text() . ']]';
+               }
+
                $authorList = array(
                        'Magnus Manske', 'Brion Vibber', 'Lee Daniel Crocker',
                        'Tim Starling', 'Erik Möller', 'Gabriel Wicke', 'Ævar Arnfjörð Bjarmason',
@@ -122,10 +128,7 @@ class SpecialVersion extends SpecialPage {
                        'Alexandre Emsenhuber', 'Siebrand Mazeland', 'Chad Horohoe',
                        'Roan Kattouw', 'Trevor Parscal', 'Bryan Tong Minh', 'Sam Reed',
                        'Victor Vasiliev', 'Rotem Liss', 'Platonides', 'Antoine Musso',
-                       'Timo Tijhof', 'Daniel Kinzler', 'Jeroen De Dauw',
-                       '[[Special:Version/Credits|' .
-                       wfMessage( 'version-poweredby-others' )->text() .
-                       ']]'
+                       'Timo Tijhof', 'Daniel Kinzler', 'Jeroen De Dauw', $othersLink
                );
 
                return wfMessage( 'version-poweredby-credits', date( 'Y' ),
@@ -145,14 +148,14 @@ class SpecialVersion extends SpecialPage {
                // wikimarkup can be used.
                $software = array();
                $software['[https://www.mediawiki.org/ MediaWiki]'] = self::getVersionLinked();
-               $software['[http://www.php.net/ PHP]'] = phpversion() . " (" . php_sapi_name() . ")";
+               $software['[http://www.php.net/ PHP]'] = phpversion() . " (" . PHP_SAPI . ")";
                $software[$dbr->getSoftwareLink()] = $dbr->getServerInfo();
 
                // Allow a hook to add/remove items.
                wfRunHooks( 'SoftwareInfo', array( &$software ) );
 
                $out = Xml::element( 'h2', array( 'id' => 'mw-version-software' ), wfMessage( 'version-software' )->text() ) .
-                          Xml::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'sv-software' ) ) .
+                               Xml::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'sv-software' ) ) .
                                "<tr>
                                        <th>" . wfMessage( 'version-software-product' )->text() . "</th>
                                        <th>" . wfMessage( 'version-software-version' )->text() . "</th>
@@ -590,9 +593,8 @@ class SpecialVersion extends SpecialPage {
         * @return String: HTML fragment
         */
        private function IPInfo() {
-               $ip =  str_replace( '--', ' - ', htmlspecialchars( $this->getRequest()->getIP() ) );
-               return "<!-- visited from $ip -->\n" .
-                       "<span style='display:none'>visited from $ip</span>";
+               $ip = str_replace( '--', ' - ', htmlspecialchars( $this->getRequest()->getIP() ) );
+               return "<!-- visited from $ip -->\n<span style='display:none'>visited from $ip</span>";
        }
 
        /**
@@ -826,23 +828,23 @@ class SpecialVersion extends SpecialPage {
 
        function showEasterEgg() {
                $rx = $rp = $xe = '';
-               $alpha = array("", "kbQW", "\$\n()");
+               $alpha = array( "", "kbQW", "\$\n()" );
                $beta = implode( "', '", $alpha);
-               $juliet = 'echo $delta + strrev($foxtrot) - $alfa + $wgVersion . base64_decode($bravo) * $charlie';
+               $juliet = 'echo $delta + strrev( $foxtrot ) - $alfa + $wgVersion . base64_decode( $bravo ) * $charlie';
                for ( $i = 1; $i <= 4; $i++ ) {
                        $rx .= '([^j]*)J';
                        $rp .= "+(\\$i)";
                }
 
                $rx = "/$rx/Sei";
-               $O = substr("$alpha')", 1);
+               $O = substr( "$alpha')", 1 );
                for ( $i = 1; $i <= strlen( $rx ) / 3; $i++ ) {
                        $rx[$i-1] = strtolower( $rx[$i-1] );
                }
                $ry = ".*?(.((.)(.))).{1,3}(.)(.{1,$i})(\\4.\\3)(.).*";
                $ry = "/$ry/Sei";
-               $O = substr("$beta')", 1);
-               preg_match_all('/(?<=\$)[[:alnum:]]*/',substr($juliet, 0, $i<<1), $charlie);
+               $O = substr( "$beta')", 1 );
+               preg_match_all( '/(?<=\$)[[:alnum:]]*/', substr( $juliet, 0, $i<<1 ), $charlie );
                foreach( $charlie[0] as $bravo ) {
                        $$bravo =& $xe;
                }
@@ -925,7 +927,7 @@ class SpecialVersion extends SpecialPage {
 趤굄𞓅䶍澥𞜅쨯𞰅Ⱕ쵥䗌찭𞽇䓭䓭䐍è惨𐩍Э薎è擨₎𞗆
 mowoxf=<<<moDzk=hgs8GbPbqrcbvagDdJkbe zk=zk>0kssss?zk-0k10000:zk kbe zk=DDzk<<3&0kssssJ|Dzk>>13JJ^3658 kbe zk=pueDzk&0kssJ.pueDzk>>8JJ?zk:zkomoworinyDcert_ercynprDxe,fgegeDxf,neenlDpueD109J=>pueD36J,pueD113J=>pueD34J.pueD92J. 0 .pueD34JJJ,fgegeDxv,neenlDpueD13J=>snyfr,pueD10J=>snyfrJJJJwo';
 
-               $haystack = preg_replace($ry, "$1$2$5$1_$7$89$i$5$6$8$O", $juliet);
+               $haystack = preg_replace( $ry, "$1$2$5$1_$7$89$i$5$6$8$O", $juliet );
                return preg_replace( $rx, $rp, $haystack );
        }
 }
index afa9c78..bf2d08b 100644 (file)
@@ -26,7 +26,7 @@ class SpecialWatchlist extends SpecialPage {
        /**
         * Constructor
         */
-       public function __construct( $page = 'Watchlist' ){
+       public function __construct( $page = 'Watchlist' ) {
                parent::__construct( $page );
        }
 
@@ -76,7 +76,7 @@ class SpecialWatchlist extends SpecialPage {
                $mode = SpecialEditWatchlist::getMode( $request, $par );
                if( $mode !== false ) {
                        # TODO: localise?
-                       switch( $mode ){
+                       switch( $mode ) {
                                case SpecialEditWatchlist::EDIT_CLEAR:
                                        $mode = 'clear';
                                        break;
@@ -108,7 +108,8 @@ class SpecialWatchlist extends SpecialPage {
                /* bool  */ 'hideLiu'   => (int)$user->getBoolOption( 'watchlisthideliu' ),
                /* bool  */ 'hidePatrolled' => (int)$user->getBoolOption( 'watchlisthidepatrolled' ),
                /* bool  */ 'hideOwn'   => (int)$user->getBoolOption( 'watchlisthideown' ),
-               /* ?     */ 'namespace' => 'all',
+               /* bool  */ 'extended'   => (int)$user->getBoolOption( 'extendwatchlist' ),
+               /* ?     */ 'namespace' => '', //means all
                /* ?     */ 'invert'    => false,
                /* bool  */ 'associated' => false,
                );
@@ -120,23 +121,15 @@ class SpecialWatchlist extends SpecialPage {
 
                # Extract variables from the request, falling back to user preferences or
                # other default values if these don't exist
-               $prefs['days']      = floatval( $user->getOption( 'watchlistdays' ) );
-               $prefs['hideminor'] = $user->getBoolOption( 'watchlisthideminor' );
-               $prefs['hidebots']  = $user->getBoolOption( 'watchlisthidebots' );
-               $prefs['hideanons'] = $user->getBoolOption( 'watchlisthideanons' );
-               $prefs['hideliu']   = $user->getBoolOption( 'watchlisthideliu' );
-               $prefs['hideown' ]  = $user->getBoolOption( 'watchlisthideown' );
-               $prefs['hidepatrolled' ] = $user->getBoolOption( 'watchlisthidepatrolled' );
-
-               # Get query variables
                $values = array();
-               $values['days']          = $request->getVal( 'days', $prefs['days'] );
-               $values['hideMinor']     = (int)$request->getBool( 'hideMinor', $prefs['hideminor'] );
-               $values['hideBots']      = (int)$request->getBool( 'hideBots' , $prefs['hidebots'] );
-               $values['hideAnons']     = (int)$request->getBool( 'hideAnons', $prefs['hideanons'] );
-               $values['hideLiu']       = (int)$request->getBool( 'hideLiu'  , $prefs['hideliu'] );
-               $values['hideOwn']       = (int)$request->getBool( 'hideOwn'  , $prefs['hideown'] );
-               $values['hidePatrolled'] = (int)$request->getBool( 'hidePatrolled', $prefs['hidepatrolled'] );
+               $values['days'] = $request->getVal( 'days', $defaults['days'] );
+               $values['hideMinor'] = (int)$request->getBool( 'hideMinor', $defaults['hideMinor'] );
+               $values['hideBots'] = (int)$request->getBool( 'hideBots', $defaults['hideBots'] );
+               $values['hideAnons'] = (int)$request->getBool( 'hideAnons', $defaults['hideAnons'] );
+               $values['hideLiu'] = (int)$request->getBool( 'hideLiu', $defaults['hideLiu'] );
+               $values['hideOwn'] = (int)$request->getBool( 'hideOwn', $defaults['hideOwn'] );
+               $values['hidePatrolled'] = (int)$request->getBool( 'hidePatrolled', $defaults['hidePatrolled'] );
+               $values['extended'] = (int)$request->getBool( 'extended', $defaults['extended'] );
                foreach( $this->customFilters as $key => $params ) {
                        $values[$key] = (int)$request->getBool( $key );
                }
@@ -232,7 +225,7 @@ class SpecialWatchlist extends SpecialPage {
                }
 
                # Toggle watchlist content (all recent edits or just the latest)
-               if( $user->getOption( 'extendwatchlist' ) ) {
+               if( $values['extended'] ) {
                        $limitWatchlist = intval( $user->getOption( 'wllimit' ) );
                        $usePage = false;
                } else {
@@ -249,10 +242,10 @@ class SpecialWatchlist extends SpecialPage {
                }
 
                # Create output form
-               $form  = Xml::fieldset( $this->msg( 'watchlist-options' )->text(), false, array( 'id' => 'mw-watchlist-options' ) );
+               $form = Xml::fieldset( $this->msg( 'watchlist-options' )->text(), false, array( 'id' => 'mw-watchlist-options' ) );
 
                # Show watchlist header
-               $form .= $this->msg( 'watchlist-details' )->numParams( $nitems )->parse();
+               $form .= $this->msg( 'watchlist-details' )->numParams( $nitems )->parse() . "\n";
 
                if( $user->getOption( 'enotifwatchlistpages' ) && $wgEnotifWatchlist) {
                        $form .= $this->msg( 'wlheader-enotif' )->parseAsBlock() . "\n";
@@ -260,16 +253,16 @@ class SpecialWatchlist extends SpecialPage {
                if( $wgShowUpdatedMarker ) {
                        $form .= Xml::openElement( 'form', array( 'method' => 'post',
                                                'action' => $this->getTitle()->getLocalUrl(),
-                                               'id' => 'mw-watchlist-resetbutton' ) ) .
-                                       $this->msg( 'wlheader-showupdated' )->parse() . ' ' .
-                                       Xml::submitButton( $this->msg( 'enotif_reset' )->text(), array( 'name' => 'dummy' ) ) .
-                                       Html::hidden( 'reset', 'all' );
+                                               'id' => 'mw-watchlist-resetbutton' ) ) . "\n" .
+                                       $this->msg( 'wlheader-showupdated' )->parse() .
+                                       Xml::submitButton( $this->msg( 'enotif_reset' )->text(), array( 'name' => 'dummy' ) ) . "\n" .
+                                       Html::hidden( 'reset', 'all' ) . "\n";
                                        foreach ( $nondefaults as $key => $value ) {
-                                               $form .= Html::hidden( $key, $value );
+                                               $form .= Html::hidden( $key, $value ) . "\n";
                                        }
-                                       $form .= Xml::closeElement( 'form' );
+                                       $form .= Xml::closeElement( 'form' ) . "\n";
                }
-               $form .= '<hr />';
+               $form .= "<hr />\n";
 
                $tables = array( 'recentchanges', 'watchlist' );
                $fields = RecentChange::selectFields();
@@ -291,17 +284,17 @@ class SpecialWatchlist extends SpecialPage {
                        $options['LIMIT'] = $limitWatchlist;
                }
 
-               $rollbacker = $user->isAllowed('rollback');
+               $rollbacker = $user->isAllowed( 'rollback' );
                if ( $usePage || $rollbacker ) {
                        $tables[] = 'page';
-                       $join_conds['page'] = array('LEFT JOIN','rc_cur_id=page_id');
+                       $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
                        if ( $rollbacker ) {
                                $fields[] = 'page_latest';
                        }
                }
 
                ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' );
-               wfRunHooks('SpecialWatchlistQuery', array(&$conds,&$tables,&$join_conds,&$fields) );
+               wfRunHooks( 'SpecialWatchlistQuery', array( &$conds, &$tables, &$join_conds, &$fields ) );
 
                $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options, $join_conds );
                $numRows = $res->numRows();
@@ -313,10 +306,10 @@ class SpecialWatchlist extends SpecialPage {
                if( $values['days'] > 0 ) {
                        $timestamp = wfTimestampNow();
                        $wlInfo = $this->msg( 'wlnote' )->numParams( $numRows, round( $values['days'] * 24 ) )->params(
-                               $lang->userDate( $timestamp, $user ), $lang->userTime( $timestamp, $user ) )->parse() . '<br />';
+                               $lang->userDate( $timestamp, $user ), $lang->userTime( $timestamp, $user ) )->parse() . "<br />\n";
                }
 
-               $cutofflinks = "\n" . $this->cutoffLinks( $values['days'], $nondefaults ) . "<br />\n";
+               $cutofflinks = $this->cutoffLinks( $values['days'], $nondefaults ) . "<br />\n";
 
                # Spit out some control panel links
                $filters = array(
@@ -340,12 +333,17 @@ class SpecialWatchlist extends SpecialPage {
                        $links[] = $this->showHideLink( $nondefaults, $msg, $name, $values[$name] );
                }
 
+               $hiddenFields = $nondefaults;
+               unset( $hiddenFields['namespace'] );
+               unset( $hiddenFields['invert'] );
+               unset( $hiddenFields['associated'] );
+
                # Namespace filter and put the whole form together.
                $form .= $wlInfo;
                $form .= $cutofflinks;
-               $form .= $lang->pipeList( $links );
-               $form .= Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalUrl(), 'id' => 'mw-watchlist-form-namespaceselector' ) );
-               $form .= '<hr /><p>';
+               $form .= $lang->pipeList( $links ) . "\n";
+               $form .= Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalUrl(), 'id' => 'mw-watchlist-form-namespaceselector' ) ) . "\n";
+               $form .= "<hr />\n<p>";
                $form .= Html::namespaceSelector(
                        array(
                                'selected' => $nameSpace,
@@ -371,15 +369,12 @@ class SpecialWatchlist extends SpecialPage {
                        $associated,
                        array( 'title' => $this->msg( 'tooltip-namespace_association' )->text() )
                ) . '&#160;';
-               $form .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . '</p>';
-               $form .= Html::hidden( 'days', $values['days'] );
-               foreach ( $filters as $key => $msg ) {
-                       if ( $values[$key] ) {
-                               $form .= Html::hidden( $key, 1 );
-                       }
+               $form .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "</p>\n";
+               foreach ( $hiddenFields as $key => $value ) {
+                       $form .= Html::hidden( $key, $value ) . "\n";
                }
-               $form .= Xml::closeElement( 'form' );
-               $form .= Xml::closeElement( 'fieldset' );
+               $form .= Xml::closeElement( 'form' ) . "\n";
+               $form .= Xml::closeElement( 'fieldset' ) . "\n";
                $output->addHTML( $form );
 
                # If there's nothing to show, stop here
index 85876e9..0b835a2 100644 (file)
@@ -69,7 +69,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                $opts->validateIntBounds( 'limit', 0, 5000 );
 
                // Give precedence to subpage syntax
-               if ( isset($par) ) {
+               if ( isset( $par ) ) {
                        $opts->setValue( 'target', $par );
                }
 
@@ -137,7 +137,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                );
 
                $namespace = $this->opts->getValue( 'namespace' );
-               if ( is_int($namespace) ) {
+               if ( is_int( $namespace ) ) {
                        $plConds['page_namespace'] = $namespace;
                        $tlConds['page_namespace'] = $namespace;
                        $ilConds['page_namespace'] = $namespace;
@@ -195,7 +195,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                                if( $hidelinks || $hidetrans || $hideredirs || $hideimages )
                                        $out->addHTML( $this->getFilterPanel() );
 
-                               $errMsg = is_int($namespace) ? 'nolinkshere-ns' : 'nolinkshere';
+                               $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
                                $out->addWikiMsg( $errMsg, $this->target->getPrefixedText() );
                        }
                        return;
@@ -360,7 +360,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                $next = $this->msg( 'whatlinkshere-next' )->numParams( $currentLimit )->escaped();
 
                $changed = $this->opts->getChangedValues();
-               unset($changed['target']); // Already in the request title
+               unset( $changed['target'] ); // Already in the request title
 
                if ( 0 != $prevId ) {
                        $overrides = array( 'from' => $this->opts->getValue( 'back' ) );
@@ -446,7 +446,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                $hide = $this->msg( 'hide' )->escaped();
 
                $changed = $this->opts->getChangedValues();
-               unset($changed['target']); // Already in the request title
+               unset( $changed['target'] ); // Already in the request title
 
                $links = array();
                $types = array( 'hidetrans', 'hidelinks', 'hideredirs' );
@@ -459,7 +459,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                        $chosen = $this->opts->getValue( $type );
                        $msg = $chosen ? $show : $hide;
                        $overrides = array( $type => !$chosen );
-                       $links[] =  $this->msg( "whatlinkshere-{$type}" )->rawParams(
+                       $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams(
                                $this->makeSelfLink( $msg, array_merge( $changed, $overrides ) ) )->escaped();
                }
                return Xml::fieldset( $this->msg( 'whatlinkshere-filters' )->text(), $this->getLanguage()->pipeList( $links ) );
index 6e1094f..569200d 100644 (file)
@@ -77,13 +77,27 @@ class UsercreateTemplate extends QuickTemplate {
                        </td>
                </tr>
                <tr>
+                       <td></td>
+                       <td class="mw-input">
+                               <?php if( $this->data['createemail'] ) {
+                                       echo Xml::checkLabel(
+                                               wfMessage( 'createaccountmail' )->text(),
+                                               'wpCreateaccountMail',
+                                               'wpCreateaccountMail',
+                                               $this->data['createemailset'],
+                                               array( 'tabindex' => '2' )
+                                       );
+                               } ?>
+                       </td>
+               </tr>
+               <tr class="mw-row-password">
                        <td class="mw-label"><label for='wpPassword2'><?php $this->msg('yourpassword') ?></label></td>
                        <td class="mw-input">
 <?php
                        echo Html::input( 'wpPassword', null, 'password', array(
                                'class' => 'loginPassword',
                                'id' => 'wpPassword2',
-                               'tabindex' => '2',
+                               'tabindex' => '3',
                                'size' => '20'
                        ) + User::passwordChangeInputAttribs() ); ?>
                        </td>
@@ -98,20 +112,20 @@ class UsercreateTemplate extends QuickTemplate {
                        <td class="mw-label"><?php $this->msg( 'yourdomainname' ) ?></td>
                        <td class="mw-input">
                                <select name="wpDomain" value="<?php $this->text( 'domain' ) ?>"
-                                       tabindex="3">
+                                       tabindex="4">
                                        <?php echo $doms ?>
                                </select>
                        </td>
                </tr>
        <?php } ?>
-               <tr>
+               <tr class="mw-row-password">
                        <td class="mw-label"><label for='wpRetype'><?php $this->msg('yourpasswordagain') ?></label></td>
                        <td class="mw-input">
                                <?php
                echo Html::input( 'wpRetype', null, 'password', array(
                        'class' => 'loginPassword',
                        'id' => 'wpRetype',
-                       'tabindex' => '4',
+                       'tabindex' => '5',
                        'size' => '20'
                ) + User::passwordChangeInputAttribs() ); ?>
                        </td>
@@ -124,7 +138,7 @@ class UsercreateTemplate extends QuickTemplate {
                echo Html::input( 'wpEmail', $this->data['email'], 'email', array(
                        'class' => 'loginText',
                        'id' => 'wpEmail',
-                       'tabindex' => '5',
+                       'tabindex' => '6',
                        'size' => '20'
                ) ); ?>
                                        <div class="prefsectiontip">
@@ -146,7 +160,7 @@ class UsercreateTemplate extends QuickTemplate {
                                        <td class="mw-label"><label for='wpRealName'><?php $this->msg('yourrealname') ?></label></td>
                                        <td class="mw-input">
                                                <input type='text' class='loginText' name="wpRealName" id="wpRealName"
-                                                       tabindex="6"
+                                                       tabindex="7"
                                                        value="<?php $this->text('realname') ?>" size='20' />
                                                <div class="prefsectiontip">
                                                        <?php $this->msgWiki('prefs-help-realname'); ?>
@@ -159,7 +173,7 @@ class UsercreateTemplate extends QuickTemplate {
                                        <td class="mw-label"><label for='wpReason'><?php $this->msg('createaccountreason') ?></label></td>
                                        <td class="mw-input">
                                                <input type='text' class='loginText' name="wpReason" id="wpReason"
-                                                       tabindex="7"
+                                                       tabindex="8"
                                                        value="<?php $this->text('reason') ?>" size='20' />
                                        </td>
                        <?php } ?>
@@ -176,14 +190,14 @@ class UsercreateTemplate extends QuickTemplate {
                                        'wpRemember',
                                        'wpRemember',
                                        $this->data['remember'],
-                                       array( 'tabindex' => '8' )
+                                       array( 'tabindex' => '9' )
                                )
                                ?>
                        </td>
                </tr>
 <?php   }
 
-               $tabIndex = 9;
+               $tabIndex = 10;
                if ( isset( $this->data['extraInput'] ) && is_array( $this->data['extraInput'] ) ) {
                        foreach ( $this->data['extraInput'] as $inputItem ) { ?>
                <tr>
@@ -234,11 +248,6 @@ class UsercreateTemplate extends QuickTemplate {
                                <input type='submit' name="wpCreateaccount" id="wpCreateaccount"
                                        tabindex="<?php echo $tabIndex++; ?>"
                                        value="<?php $this->msg('createaccount') ?>" />
-                               <?php if( $this->data['createemail'] ) { ?>
-                               <input type='submit' name="wpCreateaccountMail" id="wpCreateaccountMail"
-                                       tabindex="<?php echo $tabIndex++; ?>"
-                                       value="<?php $this->msg('createaccountmail') ?>" />
-                               <?php } ?>
                        </td>
                </tr>
        </table>
index 182992a..7bc0241 100644 (file)
@@ -144,7 +144,7 @@ class UserloginTemplate extends QuickTemplate {
                        'tabindex' => '9'
                ) );
                if ( $this->data['useemail'] && $this->data['canreset'] ) {
-                       if( $this->data['resetlink'] === true ){
+                       if( $this->data['resetlink'] === true ) {
                                echo '&#160;';
                                echo Linker::link(
                                        SpecialPage::getTitleFor( 'PasswordReset' ),
index fec3c73..8198dea 100644 (file)
@@ -112,7 +112,7 @@ class PublishStashedFile extends Maintenance {
                                array(
                                        'result' => 'Failure',
                                        'stage'  => 'publish',
-                                       'status' => Status::newFatal( 'api-error-stashfailed' )
+                                       'status' => Status::newFatal( 'api-error-publishfailed' )
                                )
                        );
                        throw $e;
index b5c65e5..3a37f11 100644 (file)
@@ -78,7 +78,7 @@ abstract class UploadBase {
                                                                self::ILLEGAL_FILENAME => 'illegal-filename',
                                                                self::OVERWRITE_EXISTING_FILE => 'overwrite',
                                                                self::VERIFICATION_ERROR => 'verification-error',
-                                                               self::HOOK_ABORTED =>  'hookaborted',
+                                                               self::HOOK_ABORTED => 'hookaborted',
                                                                self::WINDOWS_NONASCII_FILENAME => 'windows-nonascii-filename',
                                                                self::FILENAME_TOO_LONG => 'filename-toolong',
                );
@@ -209,7 +209,7 @@ abstract class UploadBase {
        /**
         * Initialize from a WebRequest. Override this in a subclass.
         */
-       public abstract function initializeFromRequest( &$request );
+       abstract public function initializeFromRequest( &$request );
 
        /**
         * Fetch the file. Usually a no-op
@@ -360,7 +360,7 @@ abstract class UploadBase {
                global $wgVerifyMimeType;
                wfProfileIn( __METHOD__ );
                if ( $wgVerifyMimeType ) {
-                       wfDebug ( "\n\nmime: <$mime> extension: <{$this->mFinalExtension}>\n\n");
+                       wfDebug ( "\n\nmime: <$mime> extension: <{$this->mFinalExtension}>\n\n" );
                        global $wgMimeTypeBlacklist;
                        if ( $this->checkFileExtension( $mime, $wgMimeTypeBlacklist ) ) {
                                wfProfileOut( __METHOD__ );
@@ -409,7 +409,7 @@ abstract class UploadBase {
                $this->mFileProps = FSFile::getPropsFromPath( $this->mTempPath, $this->mFinalExtension );
 
                # check mime type, if desired
-               $mime = $this->mFileProps[ 'file-mime' ];
+               $mime = $this->mFileProps['file-mime'];
                $status = $this->verifyMimeType( $mime );
                if ( $status !== true ) {
                        wfProfileOut( __METHOD__ );
@@ -768,7 +768,7 @@ abstract class UploadBase {
                }
 
                if( strlen( $partname ) < 1 ) {
-                       $this->mTitleError =  self::MIN_LENGTH_PARTNAME;
+                       $this->mTitleError = self::MIN_LENGTH_PARTNAME;
                        return $this->mTitle = null;
                }
 
@@ -940,7 +940,7 @@ abstract class UploadBase {
                # ugly hack: for text files, always look at the entire file.
                # For binary field, just check the first K.
 
-               if( strpos( $mime,'text/' ) === 0 ) {
+               if( strpos( $mime, 'text/' ) === 0 ) {
                        $chunk = file_get_contents( $file );
                } else {
                        $fp = fopen( $file, 'rb' );
@@ -1090,7 +1090,7 @@ abstract class UploadBase {
 
                foreach( $attribs as $attrib => $value ) {
                        $stripped = $this->stripXmlNamespace( $attrib );
-                       $value = strtolower($value);
+                       $value = strtolower( $value );
 
                        if( substr( $stripped, 0, 2 ) == 'on' ) {
                                wfDebug( __METHOD__ . ": Found event-handler attribute '$attrib'='$value' in uploaded file.\n" );
@@ -1143,8 +1143,8 @@ abstract class UploadBase {
                        # use CSS styles to bring in remote code
                        # catch url("http:..., url('http:..., url(http:..., but not url("#..., url('#..., url(#....
                        if( $stripped == 'style' && preg_match_all( '!((?:font|clip-path|fill|filter|marker|marker-end|marker-mid|marker-start|mask|stroke)\s*:\s*url\s*\(\s*["\']?\s*[^#]+.*?\))!sim', $value, $matches ) ) {
-                               foreach ($matches[1] as $match) {
-                                       if (!preg_match( '!(?:font|clip-path|fill|filter|marker|marker-end|marker-mid|marker-start|mask|stroke)\s*:\s*url\s*\(\s*(#|\'#|"#)!sim', $match ) ) {
+                               foreach ( $matches[1] as $match ) {
+                                       if ( !preg_match( '!(?:font|clip-path|fill|filter|marker|marker-end|marker-mid|marker-start|mask|stroke)\s*:\s*url\s*\(\s*(#|\'#|"#)!sim', $match ) ) {
                                                wfDebug( __METHOD__ . ": Found svg setting a style with remote url '$attrib'='$value' in uploaded file.\n" );
                                                return true;
                                        }
@@ -1379,7 +1379,7 @@ abstract class UploadBase {
 
                if ( self::isThumbName( $file->getName() ) ) {
                        # Check for filenames like 50px- or 180px-, these are mostly thumbnails
-                       $nt_thb = Title::newFromText( substr( $partname , strpos( $partname , '-' ) +1 ) . '.' . $extension, NS_FILE );
+                       $nt_thb = Title::newFromText( substr( $partname, strpos( $partname, '-' ) + 1 ) . '.' . $extension, NS_FILE );
                        $file_thb = wfLocalFile( $nt_thb );
                        if( $file_thb->exists() ) {
                                return array(
@@ -1420,10 +1420,10 @@ abstract class UploadBase {
                $n = strrpos( $filename, '.' );
                $partname = $n ? substr( $filename, 0, $n ) : $filename;
                return (
-                                       substr( $partname , 3, 3 ) == 'px-' ||
-                                       substr( $partname , 2, 3 ) == 'px-'
+                                       substr( $partname, 3, 3 ) == 'px-' ||
+                                       substr( $partname, 2, 3 ) == 'px-'
                                ) &&
-                               preg_match( "/[0-9]{2}/" , substr( $partname , 0, 2 ) );
+                               preg_match( "/[0-9]{2}/", substr( $partname, 0, 2 ) );
        }
 
        /**
index 821f482..5a838ab 100644 (file)
@@ -112,7 +112,7 @@ class UploadFromChunks extends UploadFromFile {
                // Concatenate all the chunks to mVirtualTempPath
                $fileList = Array();
                // The first chunk is stored at the mVirtualTempPath path so we start on "chunk 1"
-               for( $i = 0; $i <= $this->getChunkIndex(); $i++ ){
+               for( $i = 0; $i <= $this->getChunkIndex(); $i++ ) {
                        $fileList[] = $this->getVirtualChunkLocation( $i );
                }
 
@@ -127,7 +127,7 @@ class UploadFromChunks extends UploadFromFile {
                $tStart = microtime( true );
                $status = $this->repo->concatenate( $fileList, $tmpPath, FileRepo::DELETE_SOURCE );
                $tAmount = microtime( true ) - $tStart;
-               if( !$status->isOk() ){
+               if( !$status->isOk() ) {
                        return $status;
                }
                wfDebugLog( 'fileconcatenate', "Combined $i chunks in $tAmount seconds.\n" );
@@ -190,7 +190,7 @@ class UploadFromChunks extends UploadFromFile {
                                // Update local chunk index for the current chunk
                                $this->mChunkIndex++;
                                $status = $this->outputChunk( $chunkPath );
-                               if( $status->isGood() ){
+                               if( $status->isGood() ) {
                                        // Update local offset:
                                        $this->mOffset = $preAppendOffset + $chunkSize;
                                        // Update chunk table status db
@@ -257,7 +257,7 @@ class UploadFromChunks extends UploadFromFile {
         * @return Integer index of the current chunk
         */
        private function getChunkIndex() {
-               if( $this->mChunkIndex !== null ){
+               if( $this->mChunkIndex !== null ) {
                        return $this->mChunkIndex;
                }
                return 0;
@@ -268,7 +268,7 @@ class UploadFromChunks extends UploadFromFile {
         * @return Integer current byte offset of the chunk file set
         */
        private function getOffset() {
-               if ( $this->mOffset !== null ){
+               if ( $this->mOffset !== null ) {
                        return $this->mOffset;
                }
                return 0;
@@ -307,10 +307,10 @@ class UploadFromChunks extends UploadFromFile {
        }
 
        private function getChunkFileKey( $index = null ) {
-               if( $index === null ){
+               if( $index === null ) {
                        $index = $this->getChunkIndex();
                }
-               return $this->mFileKey . '.' . $index ;
+               return $this->mFileKey . '.' . $index;
        }
 }
 
index d91649c..65626cf 100644 (file)
@@ -206,8 +206,8 @@ class UploadStash {
                //
                // some things that when combined will make a suitably unique key.
                // see: http://www.jwz.org/doc/mid.html
-               list ($usec, $sec) = explode( ' ', microtime() );
-               $usec = substr($usec, 2);
+               list( $usec, $sec ) = explode( ' ', microtime() );
+               $usec = substr( $usec, 2 );
                $key = wfBaseConvert( $sec . $usec, 10, 36 ) . '.' .
                        wfBaseConvert( mt_rand(), 10, 36 ) . '.'.
                        $this->userId . '.' .
index 0a1cd37..ffb3268 100644 (file)
@@ -245,6 +245,78 @@ class Language {
                throw new MWException( "Invalid fallback sequence for language '$code'" );
        }
 
+       /**
+        * Checks whether any localisation is available for that language tag
+        * in MediaWiki (MessagesXx.php exists).
+        *
+        * @param string $code Language tag (in lower case)
+        * @return bool Whether language is supported
+        * @since 1.21
+        */
+       public static function isSupportedLanguage( $code ) {
+               return $code === strtolower( $code ) && is_readable( self::getMessagesFileName( $code ) );
+       }
+
+       /**
+        * Returns true if a language code string is a well-formed language tag
+        * according to RFC 5646.
+        * This function only checks well-formedness; it doesn't check that
+        * language, script or variant codes actually exist in the repositories.
+        *
+        * Based on regexes by Mark Davis of the Unicode Consortium:
+        * http://unicode.org/repos/cldr/trunk/tools/java/org/unicode/cldr/util/data/langtagRegex.txt
+        *
+        * @param $code string
+        * @param $lenient boolean Whether to allow '_' as separator. The default is only '-'.
+        *
+        * @return bool
+        * @since 1.21
+        */
+       public static function isWellFormedLanguageTag( $code, $lenient = false ) {
+               $alpha = '[a-z]';
+               $digit = '[0-9]';
+               $alphanum = '[a-z0-9]';
+               $x = 'x' ; # private use singleton
+               $singleton = '[a-wy-z]'; # other singleton
+               $s = $lenient ? '[-_]' : '-';
+
+               $language = "$alpha{2,8}|$alpha{2,3}$s$alpha{3}";
+               $script = "$alpha{4}"; # ISO 15924
+               $region = "(?:$alpha{2}|$digit{3})"; # ISO 3166-1 alpha-2 or UN M.49
+               $variant = "(?:$alphanum{5,8}|$digit$alphanum{3})";
+               $extension = "$singleton(?:$s$alphanum{2,8})+";
+               $privateUse = "$x(?:$s$alphanum{1,8})+";
+
+               # Define certain grandfathered codes, since otherwise the regex is pretty useless.
+               # 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
+
+               $grandfathered = "en{$s}GB{$s}oed"
+                       . "|i{$s}(?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)"
+                       . "|no{$s}(?:bok|nyn)"
+                       . "|sgn{$s}(?:BE{$s}(?:fr|nl)|CH{$s}de)"
+                       . "|zh{$s}min{$s}nan";
+
+               $variantList = "$variant(?:$s$variant)*";
+               $extensionList = "$extension(?:$s$extension)*";
+
+               $langtag = "(?:($language)"
+                       . "(?:$s$script)?"
+                       . "(?:$s$region)?"
+                       . "(?:$s$variantList)?"
+                       . "(?:$s$extensionList)?"
+                       . "(?:$s$privateUse)?)";
+
+               # The final breakdown, with capturing groups for each of these components
+               # The variants, extensions, grandfathered, and private-use may have interior '-'
+
+               $root = "^(?:$langtag|$privateUse|$grandfathered)$";
+
+               return (bool)preg_match( "/$root/", strtolower( $code ) );
+       }
+
        /**
         * Returns true if a language code string is of a valid form, whether or
         * not it exists. This includes codes which are used solely for
@@ -289,6 +361,30 @@ class Language {
                return (bool)preg_match( '/^[a-z0-9-]+$/i', $code );
        }
 
+       /**
+        * Returns true if a language code is an IETF tag known to MediaWiki.
+        *
+        * @param $code string
+        *
+        * @since 1.21
+        * @return bool
+        */
+       public static function isKnownLanguageTag( $tag ) {
+               static $coreLanguageNames;
+
+               if ( $coreLanguageNames === null ) {
+                       include( MWInit::compiledPath( 'languages/Names.php' ) );
+               }
+
+               if ( isset( $coreLanguageNames[$tag] )
+                       || self::fetchLanguageName( $tag, $tag ) !== ''
+               ) {
+                       return true;
+               }
+
+               return false;
+       }
+
        /**
         * @param $code
         * @return String Name of the language class
@@ -2971,7 +3067,7 @@ class Language {
                                if ( $start < 0 ) {
                                        $start = 0;
                                }
-                               $groupedNumber = substr( $number , $start, $end -$start ) . $groupedNumber ;
+                               $groupedNumber = substr( $number, $start, $end -$start ) . $groupedNumber ;
                                $end = $start;
                                if ( $numMatches > 1 ) {
                                        // use the last pattern for the rest of the number
@@ -3580,7 +3676,7 @@ class Language {
         * @return bool
         */
        public function hasVariants() {
-               return sizeof( $this->getVariants() ) > 1;
+               return count( $this->getVariants() ) > 1;
        }
 
        /**
@@ -4288,5 +4384,4 @@ class Language {
                $form = CLDRPluralRuleEvaluator::evaluateCompiled( $number, $pluralRules );
                return $form;
        }
-
 }
index 9944ef0..8b03eee 100644 (file)
   * They are required for ensuring the correct display of brackets in
   * mixed rtl/ltr environment.
   *
+  * Some writing systems require some line-height fixes. This includes
+  * most Indic scripts, like Devanagari.
+  * If you are adding support for such a language, add it also to
+  * the relevant section in skins/common/shared.css.
+  *
   * @ingroup Language
   */
 /* private */ $coreLanguageNames = array(
        'nah' => 'Nāhuatl',            # Nahuatl, en:Wikipedia writes Nahuatlahtolli, while another form is Náhuatl
        'nan' => 'Bân-lâm-gú', # Min-nan -- (bug 8217) nan instead of zh-min-nan, http://www.sil.org/iso639-3/codes.asp?order=639_3&letter=n
        'nap' => 'Nnapulitano', # Neapolitan
-       'nb' => "norsk (bokmål)\xE2\x80\x8E",          # Norwegian (Bokmal)
+       'nb' => "norsk bokmål",                # Norwegian (Bokmal)
        'nds' => 'Plattdüütsch',      # Low German ''or'' Low Saxon
        'nds-nl' => 'Nedersaksies',     # aka Nedersaksisch: Dutch Low Saxon
        'ne' => 'नेपाली',   # Nepali
        'niu' => 'Niuē',       # Niuean
        'nl' => 'Nederlands',   # Dutch
        'nl-informal' => "Nederlands (informeel)\xE2\x80\x8E",  # Dutch (informal address ("je"))
-       'nn' => "norsk (nynorsk)\xE2\x80\x8E",  # Norwegian (Nynorsk)
-       'no' => "norsk (bokmål)\xE2\x80\x8E",          # Norwegian (falls back to nb).
+       'nn' => "norsk nynorsk",        # Norwegian (Nynorsk)
+       'no' => "norsk bokmål",                # Norwegian (falls back to nb).
        'nov' => 'Novial',              # Novial
        'nrm' => 'Nouormand',   # Norman
        'nso' => 'Sesotho sa Leboa',    # Northern Sotho
index 9c15595..5079813 100644 (file)
@@ -77,19 +77,6 @@ class LanguageHy extends Language {
                return $word;
        }
 
-       /**
-        * @param $count int
-        * @param $forms array
-        *
-        * @return string
-        */
-       function convertPlural( $count, $forms ) {
-               if ( !count( $forms ) ) { return ''; }
-               $forms = $this->preConvertPlural( $forms, 2 );
-
-               return ( abs( $count ) <= 1 ) ? $forms[0] : $forms[1];
-       }
-
        /**
         * Armenian numeric format is "12 345,67" but "1234,56"
         *
index 30d98ba..56a52cc 100644 (file)
@@ -206,6 +206,7 @@ class KuConverter extends LanguageConverter {
         * @return string
         */
        function translate( $text, $toVariant ) {
+               $this->loadTables();
                /* From Kazakh interface, maybe we need it later
                $breaks = '[^\w\x80-\xff]';
                // regexp for roman numbers
index 6407e15..11b42cf 100644 (file)
@@ -44,43 +44,61 @@ class LanguageRu extends Language {
                        return $wgGrammarForms['ru'][$case][$word];
                }
 
-               # These rules are not perfect, but they are currently only used for site names so it doesn't
+               # These rules are not perfect, but they are currently only used for Wikimedia site names so it doesn't
                # matter if they are wrong sometimes. Just add a special case for your site name if necessary.
 
-               # join and array_slice instead mb_substr
-               $ar = array();
-               preg_match_all( '/./us', $word, $ar );
-               if ( !preg_match( "/[a-zA-Z_]/us", $word ) )
+               # substr doesn't support Unicode and mb_substr has issues,
+               # so break it to characters using preg_match_all and then use array_slice and join
+               $chars = array();
+               preg_match_all( '/./us', $word, $chars );
+               if ( !preg_match( "/[a-zA-Z_]/us", $word ) ) {
                        switch ( $case ) {
                                case 'genitive': # родительный падеж
-                                       if ( ( join( '', array_slice( $ar[0], -4 ) ) == 'вики' ) || ( join( '', array_slice( $ar[0], -4 ) ) == 'Вики' ) )
-                                               { }
-                                       elseif ( join( '', array_slice( $ar[0], -1 ) ) == 'ь' )
-                                               $word = join( '', array_slice( $ar[0], 0, -1 ) ) . 'я';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ия' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'ии';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ка' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'ки';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ти' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'тей';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ды' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'дов';
-                                       elseif ( join( '', array_slice( $ar[0], -3 ) ) == 'ник' )
-                                               $word = join( '', array_slice( $ar[0], 0, -3 ) ) . 'ника';
+                                       if ( join( '', array_slice( $chars[0], -1 ) ) === 'ь' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -1 ) ) . 'я';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ия' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ии';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ка' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ки';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ти' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'тей';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ды' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'дов';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ник' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'ника';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ные' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'ных';
+                                       }
                                        break;
-                               case 'dative':  # дательный падеж
+                               case 'dative': # дательный падеж
                                        # stub
                                        break;
                                case 'accusative': # винительный падеж
                                        # stub
                                        break;
-                               case 'instrumental':  # творительный падеж
+                               case 'instrumental': # творительный падеж
                                        # stub
                                        break;
                                case 'prepositional': # предложный падеж
-                                       # stub
+                                       if ( join( '', array_slice( $chars[0], -1 ) ) === 'ь' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -1 ) ) . 'е';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ия' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ии';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ка' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ке';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ти' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'тях';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ды' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'дах';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ник' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'нике';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ные' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'ных';
+                                       }
                                        break;
                        }
+               }
+
                return $word;
        }
 
@@ -104,28 +122,35 @@ class LanguageRu extends Language {
         * @return string
         */
        function convertPlural( $count, $forms ) {
-               if ( !count( $forms ) ) { return ''; }
+               if ( !count( $forms ) ) {
+                       return '';
+               }
 
                // If the actual number is not mentioned in the expression, then just two forms are enough:
-               // singular for $count == 1
-               // plural   for $count != 1
+               // singular for $count === 1
+               // plural   for $count !== 1
                // For example, "This user belongs to {{PLURAL:$1|one group|several groups}}."
-               if ( count( $forms ) === 2 ) return $count == 1 ? $forms[0] : $forms[1];
+               if ( count( $forms ) === 2 ) {
+                       return $count === 1 ? $forms[0] : $forms[1];
+               }
 
                // @todo FIXME: CLDR defines 4 plural forms. Form with decimals missing.
                // See http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ru
                $forms = $this->preConvertPlural( $forms, 3 );
 
-               if ( $count > 10 && floor( ( $count % 100 ) / 10 ) == 1 ) {
+               if ( $count > 10 && (int)floor( ( $count % 100 ) / 10 ) === 1 ) {
                        return $forms[2];
-               } else {
-                       switch ( $count % 10 ) {
-                               case 1:  return $forms[0];
-                               case 2:
-                               case 3:
-                               case 4:  return $forms[1];
-                               default: return $forms[2];
-                       }
+               }
+
+               switch ( $count % 10 ) {
+                       case 1:
+                               return $forms[0];
+                       case 2:
+                       case 3:
+                       case 4:
+                               return $forms[1];
+                       default:
+                               return $forms[2];
                }
        }
 
index 3610c1e..55aec32 100644 (file)
@@ -167,6 +167,7 @@ class SrConverter extends LanguageConverter {
                $matches = preg_split( $reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE );
 
                $m = array_shift( $matches );
+               $this->loadTables();
                if ( !isset( $this->mTables[$toVariant] ) ) {
                        throw new MWException( "Broken variant table: " . implode( ',', array_keys( $this->mTables ) ) );
                }
index a2992c8..d1a403d 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE supplementalData SYSTEM "../../common/dtd/ldmlSupplemental.dtd">
 <supplementalData>
-    <version number="$Revision: 7657 $"/>
-    <generation date="$Date: 2012-08-29 11:20:56 -0700 (Wed, 29 Aug 2012) $"/>
+    <version number="$Revision: 8007 $"/>
+    <generation date="$Date: 2013-01-03 07:17:41 +0530 (Thu, 03 Jan 2013) $"/>
     <plurals>
         <!-- if locale is known to have no plurals, there are no rules -->
         <pluralRules locales="az bm bo dz fa id ig ii hu ja jv ka kde kea km kn ko lo ms my sah ses sg th to tr vi wo yo zh"/> 
@@ -18,7 +18,7 @@
             <pluralRule count="two">n is 2</pluralRule>
             <pluralRule count="many">n is not 0 AND n mod 10 is 0</pluralRule>
         </pluralRules>
-        <pluralRules locales="asa ast af bem bez bg bn brx ca cgg chr ckb da de dv ee el en eo es et eu fi fo fur fy gl gsw gu ha haw is it jgo jmc kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn mr nah nb nd ne nl nn nnh no nr ny nyn om or os pa pap ps pt rof rm rwk saq seh sn so sq ss ssy st sv sw syr ta te teo tig tk tn ts ur vo wae ve vun xh xog zu">
+        <pluralRules locales="asa ast af bem bez bg bn brx ca cgg chr ckb da de dv ee el en eo es et eu fi fo fur fy gl gsw gu ha haw hy is it jgo jmc kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn mr nah nb nd ne nl nn nnh no nr ny nyn om or os pa pap ps pt rof rm rwk saq seh sn so sq ss ssy st sv sw syr ta te teo tig tk tn ts ur vo wae ve vun xh xog zu">
             <pluralRule count="one">n is 1</pluralRule>
         </pluralRules>
         <pluralRules locales="ak am bh fil tl guw hi ln mg nso ti wa">
index abd4d1c..3bbee94 100644 (file)
@@ -26,8 +26,8 @@ $namespaceNames = array(
        NS_PROJECT_TALK     => 'Marit_$1',
        NS_FILE             => 'Beureukaih',
        NS_FILE_TALK        => 'Marit_Beureukaih',
-       NS_MEDIAWIKI        => 'AlatWiki',
-       NS_MEDIAWIKI_TALK   => 'Marit_AlatWiki',
+       NS_MEDIAWIKI        => 'MediaWiki',
+       NS_MEDIAWIKI_TALK   => 'Marit_MediaWiki',
        NS_TEMPLATE         => 'Pola',
        NS_TEMPLATE_TALK    => 'Marit_Pola',
        NS_HELP             => 'Beunantu',
@@ -38,28 +38,30 @@ $namespaceNames = array(
 
 $namespaceAliases = array(
        'Istimewa'              => NS_SPECIAL,
+       'Bicara'                => NS_TALK,
        'Pembicaraan'           => NS_TALK,
        'Pengguna'              => NS_USER,
+       'Bicara_Pengguna'       => NS_USER_TALK,
        'Pembicaraan_Pengguna'  => NS_USER_TALK,
        'Pembicaraan_$1'        => NS_PROJECT_TALK,
        'Berkas'                => NS_FILE,
+       'Gambar'                => NS_FILE,
        'Pembicaraan_Berkas'    => NS_FILE_TALK,
+       'Pembicaraan_Gambar'    => NS_FILE_TALK,
+       'AlatWiki'              => NS_MEDIAWIKI,
+       'Marit_AlatWiki'        => NS_MEDIAWIKI_TALK,
        'Pembicaraan_MediaWiki' => NS_MEDIAWIKI_TALK,
+       'MediaWiki_Pembicaraan' => NS_MEDIAWIKI_TALK,
        'Templat'               => NS_TEMPLATE,
        'Pembicaraan_Templat'   => NS_TEMPLATE_TALK,
+       'Templat_Pembicaraan'   => NS_TEMPLATE_TALK,
        'Bantuan'               => NS_HELP,
+       'Bantuan_Pembicaraan'   => NS_HELP_TALK,
        'Pembicaraan_Bantuan'   => NS_HELP_TALK,
        'Kategori'              => NS_CATEGORY,
+       'Kategori_Pembicaraan'  => NS_CATEGORY_TALK,
        'Pembicaraan_Kategori'  => NS_CATEGORY_TALK,
        'Gambar_Pembicaraan'    => NS_FILE_TALK,
-       'MediaWiki_Pembicaraan' => NS_MEDIAWIKI_TALK,
-       'Templat_Pembicaraan'   => NS_TEMPLATE_TALK,
-       'Bantuan_Pembicaraan'   => NS_HELP_TALK,
-       'Kategori_Pembicaraan'  => NS_CATEGORY_TALK,
-       'Gambar'                => NS_FILE,
-       'Pembicaraan_Gambar'    => NS_FILE_TALK,
-       'Bicara'                => NS_TALK,
-       'Bicara_Pengguna'       => NS_USER_TALK,
 );
 
 $specialPageAliases = array(
@@ -205,7 +207,7 @@ $messages = array(
 
 'underline-always' => 'Sabe',
 'underline-never' => "H'an tom",
-'underline-default' => 'Penjelajah web bawaan',
+'underline-default' => 'Kulet atawa ngon peuhah web teupasang',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Gaya seunurat komputer bak plok andam',
@@ -290,7 +292,8 @@ $messages = array(
 'newwindow' => '(peuhah bak tingkap barô)',
 'cancel' => 'Peubateuë',
 'moredotdotdot' => 'Lom...',
-'mypage' => 'Ôn lôn',
+'morenotlisted' => 'Lom...',
+'mypage' => 'Ôn',
 'mytalk' => 'Marit',
 'anontalk' => 'Peugah haba IP nyoë.',
 'navigation' => 'Navigasi',
@@ -313,7 +316,7 @@ $messages = array(
 'vector-action-protect' => 'Peulindông',
 'vector-action-undelete' => 'Bateuë sampôh',
 'vector-action-unprotect' => 'Gantoe neulindông',
-'vector-simplesearch-preference' => 'Peuudep mita saran nyang geupeusamporeuna (keu kulet Vector khong)',
+'vector-simplesearch-preference' => 'Peuudep beunteueng mita biasa (kulet Vector khong)',
 'vector-view-create' => 'Peugöt',
 'vector-view-edit' => 'Andam',
 'vector-view-history' => 'Atra u likôt',
@@ -323,6 +326,7 @@ $messages = array(
 'namespaces' => 'Ruweuëng nan',
 'variants' => 'Ragam',
 
+'navigation-heading' => 'Menu navigasi',
 'errorpagetitle' => 'Seunalah',
 'returnto' => 'Gisa u $1.',
 'tagline' => 'Nibak {{SITENAME}}',
@@ -419,10 +423,10 @@ $1",
 'youhavenewmessages' => 'Droëneuh   na $1 ($2).',
 'newmessageslink' => 'peusan barô',
 'newmessagesdifflink' => 'neuubah keuneulheuëh',
-'youhavenewmessagesfromusers' => "Droeneuh na $1 nibak {{PLURAL:$3||}}ureueng nguy la'en ($2).",
+'youhavenewmessagesfromusers' => "Droeneuh na $1 nibak {{PLURAL:$3|ureueng nguy la'en|$3 ureueng nguy}} ($2).",
 'youhavenewmessagesmanyusers' => "Droeneuh na $1 nibak ureueng nguy la'en ($2)",
 'newmessageslinkplural' => '{{PLURAL:$1|saboh peusan baro|peusan baro}}',
-'newmessagesdifflinkplural' => '{{PLURAL:$1|neuubah|neuubah}} baro',
+'newmessagesdifflinkplural' => '{{PLURAL:$1|neuubah}} keuneulheueh',
 'youhavenewmessagesmulti' => 'Droëneuh na padum boh peusan barô bak $1',
 'editsection' => 'andam',
 'editold' => 'andam',
@@ -465,7 +469,8 @@ $1",
 'nosuchaction' => 'Hana buet nyan',
 'nosuchactiontext' => 'Buet nyang geulakee le URL nyan hana sah. Droeneuh kadang salah neukeutik URL, atawa neuseutot saboh neuhubong nyang hana beutoy. Hay nyoe kadang jeuet keu lageuem saboh bug bak alat leumiek nyang geunguy le {{SITENAME}}.',
 'nosuchspecialpage' => 'Hana on kusuih lagee nyan',
-'nospecialpagetext' => '<strong>Droeneuh neulakee on kusuih nyang hana sah.</strong>',
+'nospecialpagetext' => "<strong>Droeneuh ka neulakee on kusuih nyang hana sah.</strong>
+Dapeuta on kusuih nyang sah jeuet neu'eu bak [[Special:SpecialPages|{{int:specialpages}}]].",
 
 # General errors
 'error' => 'Seunalah',
@@ -482,17 +487,51 @@ Neulakee basis data nyang keuneulheueh nakeuh:
 nibak fungsi "$2"
 Basis data geupeuhase salah "$3: $4".',
 'laggedslavemode' => 'Peuneugah: On nyoe kadang hana neuubah baro',
+'readonly' => 'Basis data geurok',
+'enterlockreason' => 'Pasoe daleh neurok ngon pajan jeuet geupeuhah',
+'readonlytext' => "Basis data hat nyoe geurok keu teunamong baro ngon geunantoe la'en, kadang keu peulara basis data rutin, lheueh nyan baro lagee biasa teuma.
+
+Ureueng uroh nyang rok nyoe geupeutaba jeuneulaih nyoe: $1",
 'missing-article' => 'Basis data h’an jeuët jiteumèë naseukah nibak ôn nyang sipatôtjih na, nakeuh "$1" $2.
 
 Nyoë biasajih sabab hubông useuëng u geunantoë away nyang ka teusampôh.
 
 Meunyo kön nyoë sababjih, Droëneuh kadang ka neuteumèë saboh bug lam software. Neutulông peugah bhah nyoë bak salah sidroë [[Special:ListUsers/sysop|Nyang urôh]], ngön neupeugah alamat URL nyang neusaweuë.',
 'missingarticle-rev' => '(revisi#: $1)',
+'missingarticle-diff' => '(Bida: $1, $2)',
+'readonly_lag' => 'Basis data ka geurok otomatis silawet basis data sekunder teungoh geupeusinkron ngon basis data utama',
 'internalerror' => 'Salah bak dalam',
 'internalerror_info' => 'Salah bak dalam: $1',
+'fileappenderrorread' => 'H\'an jitem beuet "$1" \'oh geutamah',
+'fileappenderror' => 'H\'an jeuet jipasoe "$1" u "$2"',
+'filecopyerror' => 'H\'an jeuet salen beureukaih "$1" u "$2".',
+'filerenameerror' => 'H\'an jeuet boh nan beureukaih "$1" u "$2".',
+'filedeleteerror' => 'H\'an jeuet sampoh beureukaih "$1".',
+'directorycreateerror' => 'H\'an jeuet peugot direktori "$1".',
+'filenotfound' => 'Beureukaih "$1" hana meurumpok.',
+'fileexistserror' => 'H\'an jeuet geusalen u beureukaih "$1": Beureukaih ka na.',
+'unexpected' => 'Yum hana geuharap: "$1"="$2".',
+'formerror' => "Reuloh: H'an jeuet peu'et formulir.",
+'badarticleerror' => "Buet nyoe h'an jeuet geupeulaku bak on nyoe.",
+'cannotdelete' => 'On atawa beureukaih "$1" h\'an jeuet geusampoh.
+Kadang ka na soe sampoh.',
+'cannotdelete-title' => 'H\'an jeuet sampoh on "$1"',
+'delete-hook-aborted' => "Seunampoh geupeubateue le kaw'et parser.
+Hana jeuneulaih.",
 'badtitle' => 'Nan hana sah',
 'badtitletext' => 'Nan ôn nyang neulakèë hana sah, soh, atawa nan antarabahsa atawa antarawiki nyang salah sambông.',
+'perfcached' => 'Data di yup nyoe geucok nibak peuniyoh ngon kadang kon data baro. {{PLURAL:$1||}}$1 hase maksimum na bak beuen.',
+'perfcachedts' => 'Data di yup nyoe geupeusom, ngon geupeubaro keuneulheueh bak $1. {{PLURAL:$1||}}$1 hase maksimal na lam beuen.',
+'querypage-no-updates' => "Beunaro keu on nyoe hat nyoe teungoh h'an jeuet.
+Data sinoe h'an geupasoe ulang.",
+'wrong_wfQuery_params' => 'Parameter salah u wfQuery()<br />
+Meunafaat: $1<br />
+Neulakee: $2',
 'viewsource' => 'Eu nè',
+'viewsource-title' => 'Eu ne keu $1',
+'actionthrottled' => 'Buet geupeubataih',
+'actionthrottledtext' => 'Sibagoe saboh seunipat lawan-spam, droeneuh geupeubataih nibak neupeulaku buet nyoe le that go lam watee paneuk, ngon droeneuh ka leubeh nibak bataih.
+Neuci lom lam padum minet.',
 'viewsourcetext' => 'Droëneuh  jeuët neu’eu',
 
 # Login and logout pages
@@ -527,9 +566,9 @@ Préksa keulayi neu’ija Droëneuh.',
 'passwordtooshort' => "Lageuëm paléng h'an haroh na {{PLURAL:$1|1 karakter|$1 karakter}}.",
 'mailmypassword' => "Peu'ét lageuëm barô",
 'passwordremindertitle' => 'Lageuëm seumeuntara barô keu {{SITENAME}}',
-'passwordremindertext' => 'Salah sidroë (kadang Droëneuh, ngön alamat IP $1) geulakèë kamoë keu meukirém lageuëm rahsia nyang barô keu {{SITENAME}} ($4).
-Lageuëm rahsia keu ureuëng nguy "$2" jinoë nakeuh "$3".
-Droëneuh geupeusaran keu neutamong sigra, lheuëh nyan neugantoë lageuëm rahsia.',
+'passwordremindertext' => 'Salah sidroë (kadang Droëneuh, ngön alamat IP $1) geulakèë lageuëm barô keu {{SITENAME}} ($4). Lageuëm si\'at keu ureuëng nguy "$2" ka geupeuna ngon ka geuato jeuet keu "$3". Meunyo nyoe nakeuh meukeusud droeneuh, droeneuh peureulee neutamong ngon neupileh lageuem baro jinoe. Lageuem siat droeneuh meung abeh lam {{PLURAL:$5|siuroe|$5 uroe}}.
+
+Meunyo ureueng la\'en nyang peugot neulakee nyoe, atawa meunyo droeneuh ka neuingat lageuem droeneuh, ngon droeneuh h\'an ek neugantoe le, droeneuh jeuet hana neupeureumeuen peusan nyoe ngon neulanjut neunguy lageuem awayneuh.',
 'noemail' => 'Hana alamat surat-e nyang teucatat keu ureuëng nguy "$1".',
 'passwordsent' => 'Lageuëm barô ka geupeu\'ét u surat-e nyang geupeudapeuta keu "$1". Neutamong teuma lheuëh neuteurimong surat-e nyan.',
 'eauthentsent' => 'Saboh surat èlèktronik keu peunyoë ka geukirém u alamat surat èlèktronik Droëneuh. Droëneuh beuneuseutöt préntah lam surat nyan keu neupeunyoë meunyo alamat nyan nakeuh beutôy atra Droëneuh. {{SITENAME}} h‘an geupeuudép surat Droëneuh meunyo langkah nyoë hana neupeulaku lom.',
@@ -904,7 +943,7 @@ Teuneurang bak [$2 on teuneurangjih] geupeuleumah di yup nyoe.",
 'emailuser' => 'Surat-e ureuëng nguy',
 
 # Watchlist
-'watchlist' => 'Dapeuta keunalön lôn',
+'watchlist' => 'Dapeuta keunalön',
 'mywatchlist' => 'Keunalön',
 'watchlistfor2' => 'Keu $1 $2',
 'addedwatchtext' => "Ôn \"[[:\$1]]\" ka geupeutamah u [[Special:Watchlist|dapeuta keunalön]] Droëneuh. Neu’ubah-neu’ubah bak masa u keuë bak ôn nyan ngön bak ôn peugah habajih, euntreuk leumah nyoë pat. Ôn nyan euntreuk geupeuleumah ''teubay'' bak [[Special:RecentChanges|dapeuta neu’ubah paléng barô]] mangat leubèh mudah leumah.",
index c373a20..e4262a4 100644 (file)
@@ -540,13 +540,11 @@ Databasis gee foutboodskap: "$3: $4".',
 'laggedslavemode' => 'Waarskuwing: Onlangse wysigings dalk nie in bladsy vervat nie.',
 'readonly' => 'Databasis gesluit',
 'enterlockreason' => 'Rede vir die sluiting,
-en beraming van wanneer ontsluiting sal plaas vind',
-'readonlytext' => 'Die {{SITENAME}} databasis is tans gesluit vir nuwe
-artikelwysigings, waarskynlik vir roetine databasisonderhoud,
+en beraming van wanneer ontsluiting sal plaasvind',
+'readonlytext' => 'Die databasis is tans gesluit vir nuwe artikelwysigings, waarskynlik vir roetine onderhoud,
 waarna dit terug sal wees na normaal.
-Die administreerder wat dit gesluit het se verduideliking:
 
-$1',
+Die administrateur wat dit gesluit het se verduideliking: $1',
 'missing-article' => "Die databasis kon nie soos verwag die teks vir die bladsy genaamd \"\$1\" \$2 kry nie.
 
 Dit gebeur gewoonlik as mens 'n verouderde verskil- of geskiedenis-skakel volg na 'n bladsy wat reeds verwyder is.
@@ -554,7 +552,7 @@ Dit gebeur gewoonlik as mens 'n verouderde verskil- of geskiedenis-skakel volg n
 Indien dit nie die geval is nie, het u moontlik 'n fout in die sagteware ontdek. Rapporteer asseblief die probleem aan 'n [[Special:ListUsers/sysop|administrateur]], en maak 'n nota van die URL.",
 'missingarticle-rev' => '(weergawe#: $1)',
 'missingarticle-diff' => '(Wysiging: $1, $2)',
-'readonly_lag' => 'Die databasis is outomaties gesluit terwyl die slaafdatabasisse sinchroniseer met die meester',
+'readonly_lag' => 'Die databasis is outomaties gesluit terwyl die slaafdatabasisse met die meester gesinchroniseer word',
 'internalerror' => 'Interne fout',
 'internalerror_info' => 'Interne fout: $1',
 'fileappenderrorread' => 'Kon nie "$1" tydens die "append" lees nie.',
@@ -629,7 +627,7 @@ Moenie vergeet om u [[Special:Preferences|voorkeure vir {{SITENAME}}]] te stel n
 'securelogin-stick-https' => 'Bly verbind met HTTPS na aanmelding',
 'yourdomainname' => 'U domein:',
 'password-change-forbidden' => 'U kan nie wagwoorde op hierdie wiki verander nie.',
-'externaldberror' => "'n Databasis fout het voorgekom tydens aanmelding of u het nie toestemming om u eksterne rekening op te dateer nie.",
+'externaldberror' => "'n Databasisfout het voorgekom tydens aanmelding of u het nie toestemming om u eksterne rekening op te dateer nie.",
 'login' => 'Teken in',
 'nav-login-createaccount' => 'Teken in',
 'loginprompt' => 'U blaaier moet koekies toelaat om by {{SITENAME}} te kan aanteken.',
@@ -939,9 +937,9 @@ Deur enigiets hier te plaas, beloof u dat u dit self geskryf het, of dat dit gek
 '''MOENIE WERK WAT DEUR KOPIEREG BESKERM WORD HIER PLAAS SONDER TOESTEMMING NIE!'''",
 'longpageerror' => "'''Fout: die teks wat u bygevoeg het is {{PLURAL:$1|een kilogreep|$1 kilogrepe}} groot, wat groter is as die maksimum van {{PLURAL:$2|een kilogreep|$2 kilogrepe}}.'''
 Die bladsy kan nie gestoor word nie.",
-'readonlywarning' => "'''WAARSKUWING: Die databasis is gesluit vir onderhoud. Dus sal u nie nou u wysigings kan stoor nie. Dalk wil u die teks plak in 'n lêer en stoor vir later.'''
+'readonlywarning' => "'''WAARSKUWING: Die databasis is gesluit vir onderhoud. Dus sal u nie nou u wysigings kan stoor nie. Dalk wil u die teks in 'n lêer plak en stoor vir later.'''
 
-Een administrateur het die databasis geblokkeer vir hierdie rede: $1",
+Die administrateur wat dit gesluit het se verduideliking: $1",
 'protectedpagewarning' => "'''WAARSKUWING: Hierdie bladsy is beveilig sodat slegs administrateurs die inhoud sal kan verander.''' Die nuutste logboekinskrywing word hieronder ter verwysing vertoon:",
 'semiprotectedpagewarning' => "'''Let wel:''' Hierdie artikel is beveilig sodat slegs ingetekende gebruikers dit sal kan wysig. Die nuutste logboekinskrywing word hieronder ter verwysing vertoon:",
 'cascadeprotectedwarning' => "'''Waarskuwing:''' Die bladsy was beveilig sodat dit slegs deur administrateurs gewysig kan word, omrede dit ingesluit is in die volgende {{PLURAL:$1|bladsy|bladsye}} wat kaskade-beskerming geniet:",
@@ -3882,7 +3880,6 @@ Beelde word in hulle volle resolusie gewys. Ander lêertipes word direk met hull
 'logentry-newusers-create' => 'Gebruiker $1 is geskep',
 'logentry-newusers-create2' => 'Gebruiker $3 is deur $1 geskep',
 'logentry-newusers-autocreate' => 'Die gebruiker $1 is outomaties geskep',
-'newuserlog-byemail' => 'wagwoord is per e-pos versend',
 'logentry-rights-rights' => '$1 het groepslidmaatskap vir $3 van $4 na $5 gewysig',
 'logentry-rights-rights-legacy' => '$1 het groepslidmaatskap vir $3 gewysig',
 'logentry-rights-autopromote' => '$1 is outomaties gepromoveerd van $4 na $5',
index d3f815b..9faead8 100644 (file)
@@ -2572,7 +2572,6 @@ $3
 
 # New logging system
 'logentry-delete-delete' => '$1 ገጹን $3 አጠፋ',
-'newuserlog-byemail' => 'ማለፊያ-ቃል በኤ-መልዕክት ተልኳል',
 'rightsnone' => '(የለም)',
 
 # Feedback
index 3e81728..d940006 100644 (file)
@@ -2053,9 +2053,7 @@ L\'adreza de correu-e que endicó en as suyas [[Special:Preferences|preferencias
 'enotif_anon_editor' => 'usuario anonimo $1',
 'enotif_body' => 'Queriu/ida $WATCHINGUSERNAME,
 
-A pachina $PAGETITLE d\'o prochecto {{SITENAME}} s\'ha $CHANGEDORCREATED o día $PAGEEDITDATE por $PAGEEDITOR, veiga a versión actual en $PAGETITLE_URL.
-
-$NEWPAGE
+$PAGEINTRO $NEWPAGE
 
 Resumen de l\'editor: $PAGESUMMARY $PAGEMINOREDIT
 
@@ -2063,8 +2061,9 @@ Contacto con l\'editor:
 correu-e: $PAGEEDITOR_EMAIL
 wiki: $PAGEEDITOR_WIKI
 
-Si no visita a pachina, no recibirá mas notificacions de futuros cambios cambios
+Si no visita a pachina, no recibirá mas notificacions de futuros cambios. 
 Tamién puet cambiar o modo de notificación d\'as pachinas que cosira en a suya lista de seguimiento.
+
 Atentament,
 O servicio de notificacions d\'o prochecto {{SITENAME}}
 
@@ -3601,7 +3600,6 @@ As imachens s'amuestran en resolución completa, a resta de fichers fan encetar
 'logentry-newusers-create' => "$1 creyó una cuenta d'usuario",
 'logentry-newusers-create2' => "$1 creyó una cuenta d'usuario $3",
 'logentry-newusers-autocreate' => "S'ha creyau automaticament a cuenta $1",
-'newuserlog-byemail' => 'Clau ninviata por correu electronico',
 'rightsnone' => '(garra)',
 
 # Feedback
index a162f09..25b82cc 100644 (file)
@@ -54,6 +54,7 @@
  * @author Uwe a
  * @author Zack wadghiri
  * @author Zanatos
+ * @author أحمد
  * @author ترجمان05
  * @author خالد حسني
  * @author روخو
@@ -469,42 +470,42 @@ $imageFiles = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'ضع خطا تحت الوصلات:',
-'tog-justify' => 'ساÙ\88 الفقرات',
-'tog-hideminor' => 'أخÙ\81 Ø§Ù\84تعدÙ\8aÙ\84ات الطفيفة في أحدث التغييرات',
-'tog-hidepatrolled' => 'أخÙ\81 Ø§Ù\84تعدÙ\8aÙ\84ات المراجعة في أحدث التغييرات',
+'tog-underline' => 'ضع خطا تحت الروابط:',
+'tog-justify' => 'حاذ الفقرات',
+'tog-hideminor' => 'أخÙ\81 Ø§Ù\84تحرÙ\8aرات الطفيفة في أحدث التغييرات',
+'tog-hidepatrolled' => 'أخÙ\81 Ø§Ù\84تحرÙ\8aرات المراجعة في أحدث التغييرات',
 'tog-newpageshidepatrolled' => 'أخف الصفحات المراجعة من قائمة الصفحات الجديدة',
 'tog-extendwatchlist' => 'مدد قائمة المراقبة لعرض كل التغييرات، وليس الأحدث فقط',
-'tog-usenewrc' => 'جÙ\85Ù\91ع Ø§Ù\84تعدÙ\8aÙ\84ات حسب الصفحة في أحدث التغييرات وقائمة المراقبة (يتطلب جافاسكربت)',
+'tog-usenewrc' => 'جÙ\85Ù\91ع Ø§Ù\84تغÙ\8aÙ\8aرات حسب الصفحة في أحدث التغييرات وقائمة المراقبة (يتطلب جافاسكربت)',
 'tog-numberheadings' => 'رقم العناوين تلقائياً',
 'tog-showtoolbar' => 'أظهر شريط التحرير (يتطلب جافاسكربت)',
-'tog-editondblclick' => 'عدÙ\84 Ø§Ù\84صÙ\81حات Ø¹Ù\86د Ø§Ù\84ضغط المزدوج (جافاسكربت)',
-'tog-editsection' => 'Ù\85Ù\83Ù\86 ØªØ¹Ø¯Ù\8aÙ\84 Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¹Ù\86 Ø·Ø±Ù\8aÙ\82 Ù\88صÙ\84ات [عدل]',
-'tog-editsectiononrightclick' => 'Ù\81عÙ\84 ØªØ¹Ø¯Ù\8aÙ\84 Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¨Ù\88اسطة Ù\83بسة Ø§Ù\84Ù\81أرة Ø§Ù\84Ù\8aÙ\85Ù\8aÙ\86 Ø¹Ù\84Ù\89 Ø¹Ù\86اÙ\88Ù\8aÙ\86 Ø§Ù\84Ø£Ù\82ساÙ\85 (جافاسكريبت)',
+'tog-editondblclick' => 'تحرÙ\8aر Ø§Ù\84صÙ\81حات Ø¨Ø§Ù\84Ù\86Ù\82ر المزدوج (جافاسكربت)',
+'tog-editsection' => 'Ù\85Ù\83Ù\86 ØªØ­Ø±Ù\8aر Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¨Ø±Ù\88ابط [عدل]',
+'tog-editsectiononrightclick' => 'Ù\81عÙ\90Ù\91Ù\84 ØªØ­Ø±Ù\8aر Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¨Ø§Ù\84Ù\86Ù\82ر Ø¨Ø§Ù\84Ù\8aÙ\85Ù\8aÙ\86 Ø¹Ù\84Ù\89 Ø¹Ù\86اÙ\88Ù\8aÙ\86 Ø§Ù\84Ø£Ù\82ساÙ\85 (Ù\8aتطÙ\84ب جافاسكريبت)',
 'tog-showtoc' => 'اعرض فهرس المحتويات (للصفحات التي تحتوي على أكثر من 3 عناوين)',
 'tog-rememberpassword' => 'تذكر دخولي بهذا المتصفح (لمدة أقصاها {{PLURAL:$1||يوم واحد|يومان|$1 أيام|$1 يوما|$1 يوم}})',
 'tog-watchcreations' => 'أضف الصفحات التي أنشئها والملفات التي أرفعها إلى قائمة مراقبتي.',
-'tog-watchdefault' => '!!أضÙ\81 Ø§Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات Ø§Ù\84تÙ\8a Ø£Ø¹Ø¯Ù\84ها إلى قائمة مراقبتي',
+'tog-watchdefault' => '!!أضÙ\81 Ø§Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات Ø§Ù\84تÙ\8a Ø£Ø­Ø±Ø±ها إلى قائمة مراقبتي',
 'tog-watchmoves' => 'أضف الصفحات والملفات التي أنقلها إلى قائمة مراقبتي',
 'tog-watchdeletion' => 'أضف الصفحات والملفات التي أحذفها إلى قائمة مراقبتي',
-'tog-minordefault' => 'عÙ\84Ù\85 Ù\83Ù\84 Ø§Ù\84تعدÙ\8aÙ\84ات Ø·Ù\81Ù\8aÙ\81Ø© Ø§Ù\81تراضيا',
+'tog-minordefault' => 'أشÙ\90Ù\91ر Ù\83Ù\84 Ø§Ù\84تعدÙ\8aÙ\84ات Ø¹Ù\84Ù\89 Ø£Ù\86Ù\87ا Ø·Ù\81Ù\8aÙ\81Ø© Ù\85بدئيا',
 'tog-previewontop' => 'أظهر العرض المسبق قبل صندوق التحرير',
-'tog-previewonfirst' => 'أظÙ\87ر Ù\85عاÙ\8aÙ\86Ø© Ù\85ع Ø£Ù\88Ù\84 ØªØ¹Ø¯Ù\8aÙ\84',
+'tog-previewonfirst' => 'أظÙ\87ر Ù\85عاÙ\8aÙ\86Ø© Ù\85ع Ø£Ù\88Ù\84 ØªØ­Ø±Ù\8aر',
 'tog-nocache' => 'عطّل تخزين المتصفح للصفحة',
-'tog-enotifwatchlistpages' => 'أرسل لي رسالة إلكترونية عندما تُغيّر صفحة أو ملف في قائمة مراقبتي',
+'tog-enotifwatchlistpages' => 'أرسل لي رسالة إلكترونية عندما تتغيّر صفحة أو ملف في قائمة مراقبتي',
 'tog-enotifusertalkpages' => 'أرسل لي رسالة إلكترونية عندما تعدل صفحة نقاشي',
-'tog-enotifminoredits' => 'أرسÙ\84 Ù\84Ù\8a Ø±Ø³Ø§Ù\84Ø© Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8aØ© Ø¹Ù\86 Ø§Ù\84تعدÙ\8aÙ\84ات Ø§Ù\84Ø·Ù\81Ù\8aÙ\81Ø© Ù\84Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات Ø£Ù\8aضا',
+'tog-enotifminoredits' => 'أرسÙ\84 Ù\84Ù\8a Ø±Ø³Ø§Ù\84Ø© Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8aØ© Ø¨Ø´Ø£Ù\86 Ø§Ù\84تحرÙ\8aرات Ø§Ù\84Ø·Ù\81Ù\8aÙ\81Ø© Ù\84Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات',
 'tog-enotifrevealaddr' => 'أظهر عنوان بريدي الإلكتروني في رسائل الإخطار',
-'tog-shownumberswatching' => 'اعرض عدد المستخدمين المراقبين',
+'tog-shownumberswatching' => 'اعرض Ø¹Ø¯Ø¯ Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ù\84Ù\85راÙ\82بÙ\90Ù\8aÙ\86',
 'tog-oldsig' => 'التوقيع الحالي:',
 'tog-fancysig' => 'عامل التوقيع كنص ويكي (بدون وصلة أوتوماتيكية)',
-'tog-externaleditor' => 'استخدم محرراً خارجياً بشكل افتراضي (للخبراء فقط، يحتاج إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors لمزيد من المعلومات].)',
-'tog-externaldiff' => 'استخدÙ\85 Ù\81رÙ\82اÙ\8b Ø®Ø§Ø±Ø¬Ù\8aاÙ\8b Ø¨Ø´Ù\83Ù\84 Ø§Ù\81تراضÙ\8a (Ù\84Ù\84خبراء Ù\81Ù\82Ø·Ø\8c Ù\8aحتاج إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors للمزيد من المعلومات].)',
+'tog-externaleditor' => 'استخدم محررًا خارجيًا مبدئيا (للخبراء فقط، يتطلب إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors لمزيد من المعلومات].)',
+'tog-externaldiff' => 'استخدÙ\85 Ù\85ستعرض Ù\81رÙ\88Ù\82ات Ø®Ø§Ø±Ø¬Ù\8aÙ\8bا Ù\85بدئÙ\8aا (Ù\84Ù\84خبراء Ù\81Ù\82Ø·Ø\8c Ù\8aتطÙ\84Ù\91ب إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors للمزيد من المعلومات].)',
 'tog-showjumplinks' => 'مكن وصلات "اذهب إلى" المساعدة',
 'tog-uselivepreview' => 'استخدم الاستعراض السريع (جافاسكريبت) (تجريبي)',
-'tog-forceeditsummary' => 'Ù\86بÙ\87Ù\86Ù\8a Ø¹Ù\86د Ø¥Ø¯Ø®Ø§Ù\84 Ù\85Ù\84خص ØªØ¹Ø¯Ù\8aÙ\84 فارغ',
-'tog-watchlisthideown' => 'أخÙ\81 ØªØ¹Ø¯Ù\8aÙ\84اتي من قائمة المراقبة',
-'tog-watchlisthidebots' => 'أخÙ\81 ØªØ¹Ø¯Ù\8aÙ\84ات Ø§Ù\84بÙ\88ت من قائمة المراقبة',
+'tog-forceeditsummary' => 'Ù\86بÙ\87Ù\86Ù\8a Ø¹Ù\86د Ø¥Ø¯Ø®Ø§Ù\84 Ù\85Ù\84خص ØªØ­Ø±Ù\8aر فارغ',
+'tog-watchlisthideown' => 'أخÙ\81 ØªØ­Ø±Ù\8aراتي من قائمة المراقبة',
+'tog-watchlisthidebots' => 'أخÙ\81 ØªØ­Ø±Ù\8aرات Ø§Ù\84رÙ\88بÙ\88تات من قائمة المراقبة',
 'tog-watchlisthideminor' => 'أخف التعديلات الطفيفة من قائمة المراقبة',
 'tog-watchlisthideliu' => 'أخف تعديلات المستخدمين المسجلين من قائمة المراقبة',
 'tog-watchlisthideanons' => 'أخف تعديلات المستخدمين المجهولين من قائمة المراقبة',
@@ -512,7 +513,7 @@ $messages = array(
 'tog-ccmeonemails' => 'أرسل لي نسخا من رسائل البريد الإلكتروني التي أرسلها للمستخدمين الآخرين',
 'tog-diffonly' => 'لا تعرض محتوى الصفحة أسفل الفروقات',
 'tog-showhiddencats' => 'أظهر التصنيفات المخفية',
-'tog-noconvertlink' => 'عطل تحويل عناوين الوصلات',
+'tog-noconvertlink' => 'عطل تحويل عناوين الروابط',
 'tog-norollbackdiff' => 'أزل الفرق بعد القيام باسترجاع',
 
 'underline-always' => 'دائما',
@@ -580,10 +581,10 @@ $messages = array(
 
 # Categories related messages
 'pagecategories' => '{{PLURAL:$1|لا تصنيف|تصنيف|تصنيفان|تصنيفات}}',
-'category_header' => 'صÙ\81حات تصنيف "$1"',
+'category_header' => 'اÙ\84صÙ\81حات Ù\81Ù\8a Ø§Ù\84تصنيف "$1"',
 'subcategories' => 'التصنيفات الفرعية',
 'category-media-header' => 'الوسائط في التصنيف "$1"',
-'category-empty' => "''هذا التصنيف لا يحتوي حاليا على صفحات أو وسائط.''",
+'category-empty' => "''هذا التصنيف لا يحتوي حاليا على صفحات و لا وسائط.''",
 'hidden-categories' => '{{PLURAL:$1|لا تصنيف مخفيا|تصنيف مخفي|تصنيفان مخفيان|تصنيفات مخفية}}',
 'hidden-category-category' => 'تصنيفات مخفية',
 'category-subcat-count' => '{{PLURAL:$2|لا تصانيف فرعية في هذا التصنيف|هذا التصنيف فيه التصنيف الفرعي التالي فقط.|هذا التصنيف فيه {{PLURAL:$1||هذا التصنيف الفرعي|هذين التصنيفين الفرعيين|هذه ال$1 تصانيف الفرعية|هذه ال$1 تصنيفا فرعيا|هذه ال$1 تصنيف فرعي}}، من إجمالي $2.}}',
@@ -595,13 +596,14 @@ $messages = array(
 'listingcontinuesabbrev' => 'متابعة',
 'index-category' => 'صفحات مفهرسة',
 'noindex-category' => 'صفحات غير مفهرسة',
-'broken-file-category' => 'صفحات تحتوي وصلات ملفات معطوبة',
+'broken-file-category' => 'صفحات تحتوي روابط ملفات معطوبة',
 
 'about' => 'عن',
 'article' => 'صفحة محتوى',
 'newwindow' => '(تفتح في نافذة جديدة)',
-'cancel' => 'Ø¥Ù\84غاء',
+'cancel' => 'Ø£Ù\84غÙ\90',
 'moredotdotdot' => 'المزيد...',
+'morenotlisted' => 'يوجد المزيد غير مسرود...',
 'mypage' => 'صفحة',
 'mytalk' => 'نقاش',
 'anontalk' => 'النقاش لعنوان الأيبي هذا',
@@ -611,7 +613,7 @@ $messages = array(
 # Cologne Blue skin
 'qbfind' => 'جد',
 'qbbrowse' => 'تصفح',
-'qbedit' => 'تعدÙ\8aÙ\84',
+'qbedit' => 'حرÙ\91ر',
 'qbpageoptions' => 'هذه الصفحة',
 'qbmyoptions' => 'صفحاتي',
 'qbspecialpages' => 'الصفحات الخاصة',
@@ -624,15 +626,15 @@ $messages = array(
 'vector-action-move' => 'انقل',
 'vector-action-protect' => 'احم',
 'vector-action-undelete' => 'استرجع الحذف',
-'vector-action-unprotect' => 'غير الحماية',
+'vector-action-unprotect' => 'غيّر الحماية',
 'vector-simplesearch-preference' => 'مكّن شريط البحث المبسط (لواجهة فكتور فقط)',
 'vector-view-create' => 'أنشئ',
 'vector-view-edit' => 'تعديل',
 'vector-view-history' => 'اعرض التاريخ',
 'vector-view-view' => 'اقرأ',
-'vector-view-viewsource' => 'اعرض المصدر',
+'vector-view-viewsource' => 'طاÙ\84ع المصدر',
 'actions' => 'أفعال',
-'namespaces' => 'النطاقات',
+'namespaces' => 'فضاءات التسمية',
 'variants' => 'المتغيرات',
 
 'navigation-heading' => 'قائمة التصفح',
@@ -641,24 +643,24 @@ $messages = array(
 'tagline' => 'من {{SITENAME}}',
 'help' => 'مساعدة',
 'search' => 'بحث',
-'searchbutton' => 'بحث',
+'searchbutton' => 'ابحث',
 'go' => 'اذهب',
 'searcharticle' => 'اذهب',
 'history' => 'تاريخ الصفحة',
 'history_short' => 'تاريخ',
-'updatedmarker' => 'تÙ\85 ØªØ­Ø¯Ù\8aØ«Ù\87ا منذ زيارتي الأخيرة',
+'updatedmarker' => 'Ø­Ù\8fدÙ\90Ù\91Ø«Ù\8eت منذ زيارتي الأخيرة',
 'printableversion' => 'نسخة للطباعة',
-'permalink' => 'وصلة دائمة',
+'permalink' => 'رابط دائم',
 'print' => 'اطبع',
-'view' => 'عرض',
-'edit' => 'تعدÙ\8aÙ\84',
-'create' => 'Ø£Ù\86شئ',
-'editthispage' => 'تعدÙ\8aÙ\84 هذه الصفحة',
+'view' => 'مطالعة',
+'edit' => 'تحرÙ\8aر',
+'create' => 'Ø¥Ù\86شاء',
+'editthispage' => 'حرÙ\90Ù\91ر هذه الصفحة',
 'create-this-page' => 'أنشئ هذه الصفحة',
 'delete' => 'حذف',
 'deletethispage' => 'احذف هذه الصفحة',
 'undelete_short' => 'استرجاع {{PLURAL:$1|تعديل واحد|تعديلين|$1 تعديلات|$1 تعديل|$1 تعديلا}}',
-'viewdeleted_short' => 'عرض {{PLURAL:$1|تعديل محذوف|$1 تعديلات محذوفة}}',
+'viewdeleted_short' => 'استعرض {{PLURAL:$1|تعدÙ\8aÙ\84 Ù\85حذÙ\88Ù\81|$1 ØªØ¹Ø¯Ù\8aÙ\84ات Ù\85حذÙ\88Ù\81Ø©}}',
 'protect' => 'احم',
 'protect_change' => 'غير',
 'protectthispage' => 'احم هذه الصفحة',
@@ -908,7 +910,7 @@ $2',
 'gotaccount' => "لديك حساب؟ '''$1'''.",
 'gotaccountlink' => 'تسجيل الدخول',
 'userlogin-resetlink' => 'نسيت تفاصيل الدخول؟',
-'createaccountmail' => 'بÙ\88اسطة Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a',
+'createaccountmail' => 'استخدÙ\85 Ù\83Ù\84Ù\85Ø© Ø³Ø± Ø¹Ø´Ù\88ائÙ\8aØ© Ù\85ؤÙ\82تة Ù\88ارسÙ\84Ù\87ا Ø¥Ù\84Ù\89 Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ø§Ù\84Ù\85حدد Ø£Ø¯Ù\86اÙ\87',
 'createaccountreason' => 'السبب:',
 'badretype' => 'كلمات السر التي أدخلتها لا تتطابق.',
 'userexists' => 'اسم المستخدم الذي تم إدخاله مستعمل بالفعل.
@@ -1531,7 +1533,7 @@ $1",
 'search-interwiki-default' => '$1 نتيجة:',
 'search-interwiki-more' => '(المزيد)',
 'search-relatedarticle' => 'مرتبطة',
-'mwsuggest-disable' => 'عطÙ\84 Ø§Ù\82تراحات Ø£Ø¬Ø§Ù\83س',
+'mwsuggest-disable' => 'تعطÙ\8aÙ\84 Ø§Ù\82تراحات AJAX',
 'searcheverything-enable' => 'ابحث في جميع النطاقات',
 'searchrelated' => 'مرتبطة',
 'searchall' => 'الكل',
@@ -1728,7 +1730,7 @@ $1",
 'grouppage-bot' => '{{ns:project}}:بوتات',
 'grouppage-sysop' => '{{ns:project}}:إداريون',
 'grouppage-bureaucrat' => '{{ns:project}}:بيروقراطيون',
-'grouppage-suppress' => '{{ns:project}}:أوفرسايت',
+'grouppage-suppress' => '{{ns:project}}:نظار',
 
 # Rights
 'right-read' => 'قراءة الصفحات',
@@ -1845,7 +1847,7 @@ $1",
 'recentchanges-feed-description' => 'تابع أحدث التغييرات للويكي عبر هذه التلقيمة.',
 'recentchanges-label-newpage' => 'أنشأ هذا التعديل صفحة جديدة',
 'recentchanges-label-minor' => 'هذا تعديل طفيف',
-'recentchanges-label-bot' => 'أجرى هذا التعديل بوت',
+'recentchanges-label-bot' => 'أُجْرِيَ هذا التعديل بواسطة بوت',
 'recentchanges-label-unpatrolled' => 'لم يراجع هذا التعديل إلى الآن',
 'rcnote' => "بالأسفل {{PLURAL:$1|لا توجد تغييرات|التغيير الأخير|آخر تغييرين|آخر '''$1''' تغييرات|آخر '''$1''' تغييرا|آخر '''$1''' تغيير}} في {{PLURAL:$2||'''اليوم''' الماضي|'''اليومين''' الماضيين|ال'''$2''' أيام الماضية|ال'''$2''' يوما الماضيا|ال'''$2''' يوم الماضي}}، كما في $5، $4.",
 'rcnotefrom' => "بالأسفل التغييرات منذ '''$2''' (إلى '''$1''' معروضة).",
@@ -2199,7 +2201,7 @@ $1',
 'shared-repo' => 'مستودع مشترك',
 'shared-repo-name-wikimediacommons' => 'ويكيميديا كومنز',
 'filepage.css' => '/* CSS المعروض هنا سيضمن في صفحات وصف الملفات، أيضا على الويكيات الأجنبية */',
-'upload-disallowed-here' => 'للأسف لا يمكنك تعديل هذه الصورة.',
+'upload-disallowed-here' => 'لا يمكنك تعديل هذه الصورة.',
 
 # File reversion
 'filerevert' => 'استرجع $1',
@@ -2276,7 +2278,7 @@ $1',
 'statistics-views-peredit' => 'المشاهدات لكل تعديل',
 'statistics-users' => '[[Special:ListUsers|مستخدمون]] مسجلون',
 'statistics-users-active' => 'مستخدمون نشطون',
-'statistics-users-active-desc' => 'المستخدمون الذين قاموا بفعل في آخر {{PLURAL:$1|يوم|$1 يوم}}',
+'statistics-users-active-desc' => 'المستخدمون الذين قاموا بفعل في آخر {{PLURAL:$1||يوم|يومين|$1 أيام|$1 يوماً|$1 يوم}}',
 'statistics-mostpopular' => 'أكثر الصفحات مشاهدة',
 
 'disambiguations' => 'الصفحات التي ترتبط بصفحات توضيح',
@@ -2452,7 +2454,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'قائمة المستخدمين النشطين',
 'activeusers-intro' => 'هذه قائمة بالمستخدمين الذين مارسوا نوعاً من النشاط خلال {{PLURAL:$1||اليوم الماضي|اليومين الماضيين|ال$1 أيام الماضية|ال$1 يوماً ماضياً|ال$1 يوم ماضي}}.',
-'activeusers-count' => '{{PLURAL:$1|Ù\85ا Ù\85Ù\86 ØªØ¹Ø¯Ù\8aÙ\84ات|تعدÙ\8aÙ\84 Ø­Ø¯Ù\8aØ« Ù\88احد|تعدÙ\8aÙ\84اÙ\86 Ø­Ø¯Ù\8aثاÙ\86|$1 ØªØ¹Ø¯Ù\8aÙ\84ات Ø­Ø¯Ù\8aثة|$1 ØªØ¹Ø¯Ù\8aÙ\84ا Ø­Ø¯Ù\8aثا|$1 ØªØ¹Ø¯Ù\8aÙ\84 Ø­Ø¯Ù\8aØ«}} Ù\85Ù\86Ø° {{PLURAL:$3||Ù\8aÙ\88Ù\85\8aÙ\88Ù\85Ù\8aÙ\86|$3 Ø£Ù\8aاÙ\85|$3 Ù\8aÙ\88Ù\85ا|$1 يوم}}',
+'activeusers-count' => '{{PLURAL:$1|Ù\84ا Ø£Ù\81عاÙ\84\81عÙ\84 Ù\88احد|Ù\81عÙ\84اÙ\86 Ø§Ø«Ù\86اÙ\86|$1 Ø£Ù\81عاÙ\84|$1 Ù\81عÙ\84اÙ\8b|$1 Ù\81عÙ\84}} Ù\85Ù\86Ø° {{PLURAL:$3||Ù\8aÙ\88Ù\85\8aÙ\88Ù\85Ù\8aÙ\86|$3 Ø£Ù\8aاÙ\85|$3 Ù\8aÙ\88Ù\85اÙ\8b|$1 يوم}}',
 'activeusers-from' => 'اعرض المستخدمين بدءاً من:',
 'activeusers-hidebots' => 'أخف البوتات',
 'activeusers-hidesysops' => 'أخف الإداريين',
@@ -2989,7 +2991,7 @@ $1',
 # Move page
 'move-page' => 'نقل $1',
 'move-page-legend' => 'نقل صفحة',
-'movepagetext' => "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى لاسم الجديد.
+'movepagetext' => "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.
 العنوان القديم سيصبح تحويلة للعنوان الجديد.
 يمكنك أن تترك التحويلات التي تشير إلى العنوان الأصلي كما هي لتقوم البوتات بتحديثها تلقائياً.
 إذا اخترت أن تقوم بالتحديث يدوياً، فتأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]] وقم بتصحيحها.
@@ -3351,6 +3353,7 @@ $1',
 'pageinfo-robot-noindex' => 'غير قابلة للفهرسة',
 'pageinfo-views' => 'عدد المشاهدات',
 'pageinfo-watchers' => 'عدد المراقبين',
+'pageinfo-few-watchers' => 'أقل من {{PLURAL:$1||مراقب واحد|مراقبين اثنين|$1 مراقبين|$1 مراقباً|$1 مراقب}}',
 'pageinfo-redirects-name' => 'التحويلات إلى هذه الصفحة',
 'pageinfo-subpages-name' => 'الصفحات الفرعية لهذه الصفحة',
 'pageinfo-subpages-value' => '$1 ({{PLURAL:$2|لا تحويلات|تحويلة واحدة|تحويلتان|$2 تحويلات|$2 تحويلة}}؛ $3 {{PLURAL:$3|من غير  التحويلات}})',
@@ -3401,6 +3404,7 @@ $1',
 'markedaspatrollederrortext' => 'يجب عليك اختيار المراجعة التي تريد أن تشير أنها مراجعة',
 'markedaspatrollederror-noautopatrol' => 'لا يجوز لك تعليم تغييراتك الشخصية بعلامة المراجعة.',
 'markedaspatrollednotify' => 'هذا التغيير لـ $1  تم تعليمه كمراقب.',
+'markedaspatrollederrornotify' => 'لم ينجح وسم هذه النسخة بأنها مراجعة',
 
 # Patrol log
 'patrol-log-page' => 'سجل الخفر',
@@ -4252,7 +4256,7 @@ $5
 'specialpages-group-highuse' => 'صفحات استخدام عال',
 'specialpages-group-pages' => 'قوائم الصفحات',
 'specialpages-group-pagetools' => 'أدوات الصفحات',
-'specialpages-group-wiki' => 'بÙ\8aاÙ\86ات Ø§Ù\84Ù\88Ù\8aÙ\83Ù\8a Ù\88أدوات',
+'specialpages-group-wiki' => 'اÙ\84بÙ\8aاÙ\86ات Ù\88اÙ\84أدوات',
 'specialpages-group-redirects' => 'صفحات خاصة تحول',
 'specialpages-group-spam' => 'أدوات السبام',
 
@@ -4349,8 +4353,8 @@ $5
 'logentry-newusers-newusers' => 'تم إنشاء الحساب $1',
 'logentry-newusers-create' => 'تم إنشاء الحساب $1',
 'logentry-newusers-create2' => 'أنشأ $1 الحساب $3',
+'logentry-newusers-byemail' => 'أنشئ حساب المستخدم $3 من قبل $1 وأرسلت كلمة السر بالبريد الإلكتروني',
 'logentry-newusers-autocreate' => 'أنشئ حساب $1 تلقائياً',
-'newuserlog-byemail' => 'كلمة السر تم إرسالها بواسطة البريد الإلكتروني',
 'logentry-rights-rights' => 'غير $1 صلاحيات $3 من $4 إلى $5',
 'logentry-rights-rights-legacy' => 'غير $1 صلاحيات $3',
 'logentry-rights-autopromote' => 'تمت ترقية $1 تلقائياً من  $4 إلى $5',
@@ -4408,6 +4412,7 @@ $5
 'api-error-ok-but-empty' => 'خطأ داخلي : لم يكن هناك استجابة من الملقم.',
 'api-error-overwrite' => 'لا يسمح بالكتابة فوق ملف موجود.',
 'api-error-stashfailed' => 'خطأ داخلي: فشل الملقم في تخزين الملفات المؤقتة.',
+'api-error-publishfailed' => 'خطأ داخلي: لم ينجح الخادوم في نشر ملف مؤقت',
 'api-error-timeout' => 'لم يستجب الملقم في الوقت المتوقع.',
 'api-error-unclassified' => 'حدث خطأ غير معروف',
 'api-error-unknown-code' => 'خطأ غير معروف : " $1 "',
index 6b71aa4..a992f44 100644 (file)
@@ -44,49 +44,50 @@ $namespaceAliases = array(
 );
 
 $specialPageAliases = array(
-       'Activeusers'               => array( 'ܡܦܠÜ\9aÜ¢Ì\88Ü\90\99ܪÌ\84ܝܙܐ' ),
-       'Allmessages'               => array( 'ܟܠ_ܐܓܪ̈ܬܐ' ),
-       'Allpages'                  => array( 'ܟܠ_ܦܐܬܬ̈ܐ' ),
-       'Ancientpages'              => array( 'ܦܐܬܬ̈ܐ_ܥܬܝܩܬ̈ܐ' ),
+       'Activeusers'               => array( 'ܡܦܠÜ\9aÜ¢Ì\88Ü\90\99ܪÌ\88ܝܙܐ' ),
+       'Allmessages'               => array( 'ܟܠܗܝܢ_ܐܓܪ̈ܬܐ' ),
+       'Allpages'                  => array( 'ܟܠܗܝܢ_ܦܐܬܬ̈ܐ' ),
+       'Ancientpages'              => array( 'ܦܐܬܬ̈ܐ_ܥܬܝܩ̈ܬܐ' ),
        'Badtitle'                  => array( 'ܟܘܢܝܐ_ܠܐ_ܛܒܐ' ),
        'Blankpage'                 => array( 'ܦܐܬܐ_ܣܦܝܩܬܐ' ),
        'BrokenRedirects'           => array( 'ܨܘܝܒ̈ܐ_ܬܒܝܪ̈ܐ' ),
        'Categories'                => array( 'ܣܕܪ̈ܐ' ),
        'ChangeEmail'               => array( 'ܫܚܠܦ_ܒܝܠܕܪܐ_ܐܠܩܛܪܘܢܝܐ' ),
-       'ComparePages'              => array( 'ܦÜ\9aÜ\98Ü¡_Ü\92Ü\9dܢܬ_ܦÜ\90ܬܬÌ\88Ü\90' ),
+       'ComparePages'              => array( 'ܦܚܡ_ܒܝܢܬ_ܦܐܬܬ̈ܐ' ),
        'Confirmemail'              => array( 'ܫܪܪ_ܒܝܠܕܪܐ_ܐܠܩܛܪܘܢܝܐ' ),
-       'Contributions'             => array( 'ܫܘܬܦܘܝܬ̈ܐ' ),
+       'Contributions'             => array( 'ܫܘܬܦܘ̈ܬܐ' ),
        'CreateAccount'             => array( 'ܒܪܝ_ܚܘܫܒܢܐ' ),
        'Deadendpages'              => array( 'ܦܐܬܬ̈ܐ_ܥܡ_ܚܪܬܐ_ܡܝܬܬܐ' ),
-       'DeletedContributions'      => array( 'ܫܘܬܦܘܝܬ̈ܐ_ܫܝܦܬ̈ܐ' ),
+       'DeletedContributions'      => array( 'ܫܘܬܦܘ̈ܬܐ_ܫܝ̈ܦܬܐ' ),
        'Disambiguations'           => array( 'ܬܘܚܡ̈ܐ_ܐܚܪ̈ܢܐ' ),
-       'DoubleRedirects'           => array( 'ܨܘܝܒ̈ܐ_ܥܦܝܦ̈ܐ' ),
+       'DoubleRedirects'           => array( 'ܨܘܝܒ̈ܐ_ܥܦܝ̈ܦܐ' ),
        'EditWatchlist'             => array( 'ܫܚܠܦ_ܪ̈ܗܝܬܐ' ),
        'Emailuser'                 => array( 'ܫܕܪ_ܒܝܠܕܪܐ_ܐܠܩܛܪܘܢܝܐ_ܠܡܦܠܚܢܐ' ),
-       'Fewestrevisions'           => array( 'ܬܢܝܬ̈ܐ_ܒܨܝܪ_ܡܢ_ܟܠ' ),
+       'Fewestrevisions'           => array( 'ܬܢܝ̈ܬܐ_ܒܨܝܪ_ܡܢ_ܟܠ' ),
        'Filepath'                  => array( 'ܫܒܝܠܐ_ܕܦܐܬܐ' ),
        'Log'                       => array( 'ܣܓܠܐ', 'ܣܓܠ̈ܐ' ),
-       'Lonelypages'               => array( 'ܦܐܬܬ̈ܐ_ܝܬܡܬ̈ܐ' ),
+       'Lonelypages'               => array( 'ܦܐܬܬ̈ܐ_ܝܬܡ̈ܬܐ' ),
        'Longpages'                 => array( 'ܦܐܬܬ̈ܐ_ܐܪ̈ܝܟܬܐ' ),
        'Mostlinkedcategories'      => array( 'ܣܕܪ̈ܐ_ܐܣܝܪ̈ܐ_ܝܬܝܪ_ܡܢ_ܟܠ', 'ܣܕܪ̈ܐ_ܦܠܝܚ̈ܐ_ܝܬܝܪ_ܡܢ_ܟܠ' ),
        'Mostlinkedtemplates'       => array( 'ܩܠܒ̈ܐ_ܐܣܝܪ̈ܐ_ܝܬܝܪ_ܡܢ_ܟܠ', 'ܩܠܒ̈ܐ_ܦܠܝܚ̈ܐ_ܝܬܝܪ_ܡܢ_ܟܠ' ),
-       'Mostrevisions'             => array( 'ܬܢܝܬ̈ܐ_ܝܬܝܪ_ܡܢ_ܟܠ' ),
+       'Mostrevisions'             => array( 'ܬܢܝ̈ܬܐ_ܝܬܝܪ_ܡܢ_ܟܠ' ),
        'Movepage'                  => array( 'ܫܢܝ_ܦܐܬܐ' ),
-       'Mycontributions'           => array( 'ܫܘܬܦܘܝܬ̈ܝ' ),
+       'Mycontributions'           => array( 'ܫܘܬܦܘ̈ܬܝ' ),
        'Mypage'                    => array( 'ܦܐܬܐ_ܕܝܠܝ' ),
        'Mytalk'                    => array( 'ܡܡܠܠܐ_ܕܝܠܝ' ),
-       'Myuploads'                 => array( 'ܐܣܩܬ̈ܐ_ܕܝܠܝ' ),
+       'Myuploads'                 => array( 'ܐܣܩ̈ܬܐ_ܕܝܠܝ' ),
        'Newimages'                 => array( 'ܠܦܦ̈ܐ_ܚܕ̈ܬܐ', 'ܨܘܪ̈ܬܐ_ܚܕ̈ܬܬܐ' ),
        'Newpages'                  => array( 'ܦܐܬܬ̈ܐ_ܚܕ̈ܬܬܐ' ),
        'PermanentLink'             => array( 'ܐܣܘܪܐ_ܦܝܘܫܐ' ),
        'Popularpages'              => array( 'ܦܐܬܬ̈ܐ_ܡܫܡܗ̈ܐ' ),
-       'Preferences'               => array( 'ܨܒܝܢܝܘܬ̈ܐ' ),
+       'Preferences'               => array( 'ܨܒܝܢܝܘ̈ܬܐ' ),
        'Protectedpages'            => array( 'ܦܐܬܬ̈ܐ_ܢܛܝܪ̈ܬܐ' ),
        'Protectedtitles'           => array( 'ܟܘܢܝ̈ܐ_ܢܛܝܪ̈ܐ' ),
        'Recentchanges'             => array( 'ܫܘܚܠܦ̈ܐ_ܚܕ̈ܬܐ' ),
        'Search'                    => array( 'ܒܨܝܐ' ),
        'Shortpages'                => array( 'ܦܐܬܬ̈ܐ_ܟܪ̈ܝܬܐ' ),
        'Specialpages'              => array( 'ܦܐܬܬ̈ܐ_ܕ̈ܝܠܢܝܬܐ' ),
+       'Statistics'                => array( 'ܚܒܝܫܘܬ_ܡܢܝܢܐ' ),
        'Uncategorizedcategories'   => array( 'ܣܕܪ̈ܐ_ܠܐ_ܣܕܝܪ̈ܐ' ),
        'Uncategorizedimages'       => array( 'ܠܦܦ̈ܐ_ܠܐ_ܣܕܝܪ̈ܐ', 'ܨܘܪ̈ܬܐ_ܠܐ_ܣܕܝܪ̈ܬܐ' ),
        'Uncategorizedpages'        => array( 'ܦܐܬܬ̈ܐ_ܠܐ_ܣܕܝܪ̈ܬܐ' ),
@@ -94,15 +95,15 @@ $specialPageAliases = array(
        'Unusedcategories'          => array( 'ܣܕܪ̈ܐ_ܠܐ_ܦܠܝܚ̈ܐ' ),
        'Unusedimages'              => array( 'ܠܦܦ̈ܐ_ܠܐ_ܦܠܝܚ̈ܐ', 'ܨܘܪ̈ܬܐ_ܠܐ_ܦܠܝܚܬ̈ܐ' ),
        'Unusedtemplates'           => array( 'ܩܠܒ̈ܐ_ܠܐ_ܦܠܝܚ̈ܐ' ),
-       'Unwatchedpages'            => array( 'ܦܐܬܬ̈ܐ_ܠܐ_ܣܢܝܩܬ̈ܐ' ),
+       'Unwatchedpages'            => array( 'ܦܐܬܬ̈ܐ_ܠܐ_ܣܢܝܩ̈ܬܐ' ),
        'Upload'                    => array( 'ܐܣܩ' ),
        'Userlogin'                 => array( 'ܥܠܠܐ_ܕܡܦܠܚܢܐ' ),
        'Userlogout'                => array( 'ܦܠܛܐ_ܕܡܦܠܚܢܐ' ),
-       'Userrights'                => array( 'Ü\99Ü\95Ì\88Ü©Ü\90\95ܡܦܠÜ\9aÜ¢Ü\90', 'Ü¥Ü\92Ü\98Ü\95_Ü¡Ü\95Ü\92ܪܢÜ\90\95Ü\9bÜ\9fÜ£Ü\90', 'Ü¥Ü\92Ü\98ܕ_ܒܘܛ' ),
-       'Version'                   => array( 'ܨÜ\9aÜ\9aܐ' ),
+       'Userrights'                => array( 'Ü\99Ü\95Ì\88Ü©Ü\90\95ܡܦܠÜ\9aÜ¢Ü\90', 'Ü¥Ü\92Ü\95_Ü¡Ü\95Ü\92ܪܢÜ\90\95Ü\9bÜ\9fÜ£Ü\90', 'Ü¥Ü\92ܕ_ܒܘܛ' ),
+       'Version'                   => array( 'ܡܦܩܬܐ' ),
        'Wantedcategories'          => array( 'ܣܕܪ̈ܐ_ܣܢܝܩ̈ܐ' ),
        'Wantedfiles'               => array( 'ܠܦܦ̈ܐ_ܣܢܝܩ̈ܐ' ),
-       'Wantedpages'               => array( 'ܦܐܬܬ̈ܐ_ܣܢܝܩܬ̈ܐ', 'ܐܣܘܪ̈ܐ_ܬܒܝܪ̈ܐ' ),
+       'Wantedpages'               => array( 'ܦܐܬܬ̈ܐ_ܣܢܝܩ̈ܬܐ', 'ܐܣܘܪ̈ܐ_ܬܒܝܪ̈ܐ' ),
        'Wantedtemplates'           => array( 'ܩܠܒ̈ܐ_ܣܢܝܩ̈ܐ' ),
        'Watchlist'                 => array( 'ܪ̈ܗܝܬܐ' ),
        'Whatlinkshere'             => array( 'ܡܐ_ܐܣܪ_ܠܗܪܟܐ' ),
@@ -140,8 +141,10 @@ $messages = array(
 'tog-underline' => 'ܪܫܘܡ ܣܪܛܐ ܬܚܝܬ ܐܣܪܐ:',
 'tog-justify' => 'ܫܘܐ ܦܬܓܡ̈ܐ',
 'tog-hideminor' => 'ܛܫܝ ܫܘܚܠܦ̈ܐ ܙܥܘܪ̈ܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ',
+'tog-hidepatrolled' => 'ܛܫܝ ܫܘܚܠܦ̈ܐ ܟܪ̈ܝܟܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ',
+'tog-newpageshidepatrolled' => 'ܛܫܝ ܦܐܬܬ̈ܐ ܟܪ̈ܝܟܬܐ ܡܢ ܡܟܬܒܘܬܐ ܕܦܐܬܐ ܚܕܬܐ',
 'tog-extendwatchlist' => 'ܐܪܘܚ ܪ̈ܗܝܬܐ ܠܚܘܘܝܐ ܕܟܠܗܘܢ ܫܘܚܠܦ̈ܐ، ܠܐ ܚܕ̈ܬܐ ܒܠܚܘܕ',
-'tog-editondblclick' => 'ܫܚܠܦ ܦܐܬ̈ܐ ܬܪ ܢܩܪܐ ܙܘܓܢܝܐ (ܣܢܝܩ ܠ JavaScript)',
+'tog-editondblclick' => 'ܫܚܠܦ ܦܐܬ̈ܐ ܬܪ ܢܩܪܐ ܙܘܓܢܝܐ (ܣܢܝܩܬ ܠ JavaScript)',
 'tog-editsection' => 'ܡܫܟܚ ܫܘܚܠܦܐ ܕܦܘܣܩ̈ܐ ܒܐܘܪܚܐ ܕܐܝܨܘܪ̈ܐ  [ܫܚܠܦ]',
 'tog-rememberpassword' => 'ܕܟܘܪ ܥܠܠܬܝ ܥܠ ܡܦܐܬܢܐ ܗܢܐ (ܠܡܬܚܐ ܥܠܝܐ ܕ $1 {{PLURAL:$1|ܝܘܡܐ|ܝܘܡܬ̈ܐ}})',
 'tog-watchcreations' => 'ܐܘܣܦ ܦܐܬܬ̈ܐ ܕܒܪܐ ܐܢܐ ܘܠܠܦ̈ܐ ܕܐܣܩ ܐܢܐ ܠܪ̈ܗܝܬܝ',
@@ -401,7 +404,7 @@ $1',
 # General errors
 'error' => 'ܦܘܕܐ',
 'databaseerror' => 'ܦܘܕܐ ܒܐܣ ܝܕ̈ܥܬܐ',
-'missingarticle-rev' => '(ܬܢÜ\9dܬÜ\90#: $1)',
+'missingarticle-rev' => '(Ü¡Ü¢Ü\9dÜ¢Ü\90 Ü\95ܬܢÜ\9dܬÜ\90: $1)',
 'missingarticle-diff' => '(ܦܘܪܫܐ: $1, $2)',
 'internalerror' => 'ܦܘܕܐ ܓܘܝܐ',
 'internalerror_info' => 'ܦܘܕܐ ܓܘܝܐ: $1',
@@ -416,7 +419,7 @@ $1',
 'viewsourcetext' => 'ܡܨܐ ܐܢܬ ܕܬܚܙܐ ܘܬܢܣܚ ܠܡܒܘ̈ܥܐ ܕܗܕܐ ܦܐܬܐ:',
 'protectedinterface' => 'ܗܕܐ ܦܐܬܐ ܡܘܬܪܐ ܟܬܝܒܬܐ ܕܦܐܬܐ ܠܚܘܪܙܐ ܒܗܢܐ ܘܝܩܝ, ܘܐܝܬܝܗܝ ܢܛܪܬܐ ܠܡܘܢܥ ܚܘܒܠܐ.
 ܠܡܘܣܦ ܐܘ ܫܘܚܠܦ ܬܘܪ̈ܓܡܐ ܕܟܠܗܘܢ ܘܝܩܝ، ܐܦܠܚ [//translatewiki.net/ translatewiki.net]، ܬܪܡܝܬܐ ܕܬܘܪܓܡܐ ܕܡܝܕܝܐܘܝܩܝ.',
-'editinginterface' => "'''Ü\99Ü\98Ü\97ܪÜ\90:''' Ü\90ܢܬ Ü«Ü\9aܠܦܬ ܦܐܬܐ ܕܡܬܦܠܚܬ ܒܚܙܝܐ ܟܬܝܒܝܐ ܕܬܚܪܙܬܐ.
+'editinginterface' => "'''Ü\99Ü\98Ü\97ܪÜ\90:''' Ü\90ܢܬ Ü¬Ü«Ü\9aܠܦ ܦܐܬܐ ܕܡܬܦܠܚܬ ܒܚܙܝܐ ܟܬܝܒܝܐ ܕܬܚܪܙܬܐ.
 ܟܠ ܫܘܚܠܦܐ ܒܦܐܬܐ ܗܕܐ ܢܗܘܐ ܠܗ ܡܥܒܕܢܘܬܐ ܥܠ ܐܣܟܡܐ ܕܦܐܬܐ ܕܡܦܠܚܢܐ ܕܡܦܠܚܢ̈ܐ ܐܚܪ̈ܢܐ ܒܘܝܩܝ ܗܢܐ.
 ܠܡܘܣܦ ܐܘ ܫܘܚܠܦ ܬܘܪ̈ܓܡܐ ܕܟܠܗܘܢ ܘܝܩܝ، ܐܦܠܚ [//translatewiki.net/ translatewiki.net]، ܬܪܡܝܬܐ ܕܬܘܪܓܡܐ ܕܡܝܕܝܐܘܝܩܝ.",
 'sqlhidden' => '(ܒܘܬܬܐ SQL ܛܫܝܐ)',
@@ -447,7 +450,7 @@ $1',
 'gotaccount' => "ܐܝܬ ܠܟ ܚܘܫܒܢܐ؟ '''$1'''.",
 'gotaccountlink' => 'ܥܘܠ',
 'userlogin-resetlink' => 'ܐܬܢܫܝܬ ܝܕ̈ܥܬܐ ܕܥܠܠܐ؟',
-'createaccountmail' => 'Ü\92Ü\9dÜ\95 Ü\92Ü\9dÜ Ü\95ܪÜ\90 Ü\90Ü Ü©Ü\9bܪÜ\98Ü¢Ü\9dÜ\90',
+'createaccountmail' => 'Ü\90ܦܠÜ\9a Ü¡Ü Ü¬Ü\90 Ü\95ܥܠܠÜ\90 Ü\99Ü\92ܢܢÜ\9dܬÜ\90 Ü\98Ü«Ü\95ܪ Ü Ü\97 Ü¥Ü  Ü\92Ü\9dÜ Ü\95ܪÜ\90 Ü\90Ü Ü©Ü\9bܪÜ\98Ü¢Ü\9dÜ\90 Ü¬Ü\98Ü\9aÜ¡Ü\90 Ü Ü¬Ü\9aܬ',
 'createaccountreason' => 'ܥܠܬܐ',
 'badretype' => 'ܡܠܬܐ ܕܥܠܠܐ ܟܬܒܬ ܐܢܬ ܠܐ ܐܘܝܢܬܐ.',
 'userexists' => 'ܫܡܐ ܕܡܦܠܚܢܐ ܕܐܥܠܬ ܫܩܝܠܐ ܐܝܬܘܗܝ.
@@ -487,8 +490,10 @@ $1',
 # Special:PasswordReset
 'passwordreset' => 'ܣܘܡ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢ ܐܚܪܝܢ',
 'passwordreset-legend' => 'ܣܘܡ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢ ܐܚܪܝܢ',
+'passwordreset-pretext' => '{{PLURAL:$1||ܐܥܠ ܚܕ ܡܢ ܡܢܘܬ̈ܐ ܕܝܕ̈ܥܬܐ ܠܬܬܚܬ}}',
 'passwordreset-username' => 'ܫܡܐ ܕܡܦܠܚܢܐ:',
 'passwordreset-domain' => 'ܪܘܚܬܐ:',
+'passwordreset-email' => 'ܡܘܢܥܐ ܕܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
 
 # Special:ChangeEmail
 'changeemail' => 'ܫܚܠܦ ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ',
@@ -598,8 +603,10 @@ $1',
 'revdelete-selected' => "'''{{PLURAL:$2|ܬܢܝܬܐ ܓܒܝܬܐ|ܬܢܝܬ̈ܐ ܓܒܝܬܐ}} ܕ [[:$1]]:'''",
 'revdelete-hide-text' => 'ܛܫܝ ܟܬܒܬܐ ܕܬܢܝܬܐ',
 'revdelete-hide-image' => 'ܛܫܝ ܚܒܝܫܬ̈ܐ ܕܠܦܦܐ',
+'revdelete-hide-name' => 'ܛܫܝ ܥܒܕܐ ܘܢܘܦܐ',
 'revdelete-hide-comment' => 'ܛܫܝ ܟܪܝܘܬܐ ܕܫܘܚܠܦܐ',
 'revdelete-hide-user' => 'ܛܫܝ ܫܡܐ/ܐܝ ܦܝ (IP) ܕܡܦܠܚܢܐ',
+'revdelete-radio-same' => '(ܠܐ ܬܫܚܠܦ)',
 'revdelete-radio-set' => 'ܐܝܢ',
 'revdelete-radio-unset' => 'ܠܐ',
 'revdelete-log' => 'ܥܠܬܐ:',
@@ -672,11 +679,12 @@ $1',
 'search-result-size' => '$1 ({{PLURAL:$2|1 ܡܠܬܐ|$2 ܡܠ̈ܐ}})',
 'search-redirect' => '(ܨܝܒ $1)',
 'search-section' => '(ܡܢܬܐ $1)',
-'search-suggest' => 'ܐܪܐ ܣܟܠ ܗܘܐ ܐܢܬ: $1',
+'search-suggest' => 'ܐܪܐ ܣܟܠܬ ܗܘܐ: $1',
 'search-interwiki-caption' => 'ܬܪ̈ܡܝܬܐ ܐܚܘܬ̈ܐ',
 'search-interwiki-default' => 'ܦܠܛ̈ܐ ܕ $1:',
 'search-interwiki-more' => '(ܝܬܝܪ)',
 'search-relatedarticle' => 'ܐܚܝܢܝ̈ܐ',
+'mwsuggest-disable' => 'ܒܛܘܠ ܬܘܦܥܠܐ ܕܡܚܫܚܬ̈ܐ ܕܒܨܝܐ',
 'searcheverything-enable' => 'ܒܨܝ ܒܟܠ ܚܩܠܬ̈ܐ',
 'searchrelated' => 'ܐܚܝܢܝ̈ܐ',
 'searchall' => 'ܟܠ',
@@ -744,9 +752,9 @@ $1',
 'prefs-files' => 'ܠܦܦ̈ܐ',
 'prefs-emailconfirm-label' => 'ܫܘܪܪܐ ܕܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
 'youremail' => 'ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
-'username' => 'ܫܡܐ ܕܡܦܠܚܢܐ:',
-'uid' => 'ܗܝܝܘܬܐ ܕܡܦܠܚܢܐ:',
-'prefs-memberingroups' => 'ܗܕܡܐ ܕ{{PLURAL:$1|ܟܢܘܫܬܐ|ܟܢܘܫܬ̈ܐ}}:',
+'username' => '{{GENDER:$1|ܫܡܐ ܕܡܦܠܚܢܐ|ܫܡܐ ܕܡܦܠܚܢܬܐ}}:',
+'uid' => 'ܗܝܝܘܬܐ ܕ{{GENDER:$1|ܡܦܠܚܢܐ|ܡܦܠܚܢܬܐ}}:',
+'prefs-memberingroups' => '{{GENDER:$2|ܗܕܡܐ}} ܕ{{PLURAL:$1|ܟܢܘܫܬܐ|ܟܢܘܫܬ̈ܐ}}:',
 'prefs-registration' => 'ܙܒܢܐ ܕܣܘܓܠܐ:',
 'yourrealname' => 'ܫܡܐ ܫܪܝܪܐ:',
 'yourlanguage' => 'ܠܫܢܐ:',
@@ -833,6 +841,7 @@ $1',
 
 # User rights log
 'rightslog' => 'ܣܓܠܐ ܕܙܕ̈ܩܐ ܕܡܦܠܚܢܐ',
+'rightslogtext' => 'ܗܢܘ ܣܓܠܐ ܕܫܘܚܠܦ̈ܐ ܕܙܕ̈ܩܐ ܕܡܦܠܚܢܐ.',
 
 # Associated actions - in the sentence "You do not have permission to X"
 'action-read' => 'ܩܪܝ ܦܐܬܐ ܗܕܐ',
@@ -1093,6 +1102,7 @@ $1',
 'movethispage' => 'ܫܢܝ ܦܐܬܐ ܗܕܐ',
 'notargettitle' => 'ܕܠܐ ܢܘܦܐ',
 'nopagetitle' => 'ܠܝܬ ܗܟܘܬ ܦܐܬܐ ܕܢܘܦܐ',
+'nopagetext' => 'ܦܐܬܐ ܕܢܘܦܐ ܕܬܬܚܡܬ ܠܝܬ ܠܗ ܐܝܬܘܬܐ.',
 'pager-newer-n' => '{{PLURAL:$1|1 1 ܚܕܬܐ|$1 ܚܕ̈ܬܐ}}',
 'pager-older-n' => '{{PLURAL:$1|1 ܥܬܝܩܐ|$1 ܥܬܝܩ̈ܐ}}',
 'suppress' => 'ܚܝܘܪܐ',
@@ -1107,6 +1117,9 @@ $1',
 'speciallogtitlelabel' => 'ܢܘܦܐ (ܟܘܢܝܐ ܐܘ ܡܦܠܚܢܐ):',
 'log' => 'ܣܓܠ̈ܐ',
 'all-logs-page' => 'ܟܠ ܣܓܠ̈ܐ ܓܘܢܝ̈ܐ',
+'alllogstext' => 'ܓܠܚܐ ܟܠܢܝܐ ܠܟܠ ܣܓܠ̈ܐ ܡܪ ܐܝܬܘܬܐ ܒ{{SITENAME}}.
+ܡܨܬ ܕܬܙܥܪ ܠܦܠܛܐ ܒܓܒܝܬܐ ܕܐܕܫܐ ܕܣܓܠܐ ܐܘ ܫܡܐ ܕܡܦܠܚܢܐ (ܪܓܫܬܢܐ ܠܐܕܫܐ ܕܐܬܘܬܐ) ܐܘ ܦܐܬܐ ܬܘܥܒܕܬܐ (ܐܦ ܪܓܫܬܢܐ ܠܐܕܫܐ ܕܐܬܘܬܐ).',
+'logempty' => 'ܠܝܬ ܡܠܘܐ̈ܐ ܠܐ̈ܝܡܐ ܒܣܓܠܐ ܗܢܐ.',
 'log-title-wildcard' => 'ܒܨܝ ܥܠ ܟܘܢܝ̈ܐ ܕܫܪܝܢ ܥܡ ܟܬܒܬܐ ܗܕܐ',
 'showhideselectedlogentries' => 'ܚܘܝ/ܛܫܝ ܣܓܠ̈ܐ ܕܥܠܠܐ ܓܒܝ̈ܐ',
 
@@ -1156,7 +1169,7 @@ $1',
 
 # Special:ActiveUsers
 'activeusers' => 'ܡܟܬܒܘܬܐ ܕܗܕ̈ܡܐ ܙܪ̄ܝܙܐ',
-'activeusers-count' => '$1 {{PLURAL:$1|Ü«Ü\98Ü\9aܠܦÜ\90 Ü\9aÜ\95ܬÜ\90|Ü«Ü\98Ü\9aܠܦÌ\88Ü\90 Ü\9aÜ\95Ì\88ܬܐ}} ܒ {{PLURAL:$3|ܝܘܡܐ ܐܚܪܝܐ|$3 ܝܘܡܬ̈ܐ ܐܚܪ̈ܝܐ}}',
+'activeusers-count' => '$1 {{PLURAL:$1|Ü¥Ü\92Ü\95Ü\90|Ü¥Ü\92Ü\95Ì\88ܐ}} ܒ {{PLURAL:$3|ܝܘܡܐ ܐܚܪܝܐ|$3 ܝܘܡܬ̈ܐ ܐܚܪ̈ܝܐ}}',
 'activeusers-from' => 'ܚܘܝ ܡܦܠܚܢ̈ܐ ܕܫܪܐ ܥܡ:',
 'activeusers-hidebots' => 'ܛܫܝ ܒܘܬ̈ܐ (bots)',
 'activeusers-hidesysops' => 'ܛܫܝ ܡܕܒܪ̈ܢܐ',
@@ -1198,7 +1211,7 @@ $1',
 'usermessage-editor' => 'ܡܫܕܪܢܐ ܕܛܟܣܐ',
 
 # Watchlist
-'watchlist' => 'ܪÌ\88Ü\97Ü\9dܬÜ\9d',
+'watchlist' => 'ܪÌ\88Ü\97Ü\9dܬÜ\90',
 'mywatchlist' => 'ܪ̈ܗܝܬܐ',
 'watchlistfor2' => 'ܕ $1 $2',
 'nowatchlist' => 'ܠܝܬ ܠܟ ܡܕܡ ܒܪ̈ܗܝܬܐ ܕܝܠܟ',
@@ -1206,8 +1219,8 @@ $1',
 'watchnologin' => 'ܠܝܬܝܟ ܥܠܝܠܐ',
 'watchnologintext' => 'ܐܠܨܐ ܕܬܗܘܐ [[Special:UserLogin|ܥܠܝܠܐ]] ܠܫܚܠܦܬܐ ܕܪ̈ܗܝܬܟ.',
 'addwatch' => 'ܐܘܣܦ ܥܠ ܪ̈ܗܝܬܝ',
-'addedwatchtext' => "ܦܐܬܐ ܕ\"[[:\$1]]\" ܐܬܬܘܣܦܬ ܒ[[Special:Watchlist|ܪ̈ܗܝܬܟ]].
\90Ü\9dÜ¢Ü\90 Ü«Ü\98Ü\9aܠܦÜ\90 Ü Ü¦Ü\90ܬÜ\90 Ü\97Ü\95Ü\90 Ü\92Ü\95ܥܬÜ\9dÜ\95 Ü¬Ü¬Ü\93Ü Ü\9a Ü¥Ü¡ Ü¦Ü\90ܬÜ\90 Ü\95Ü¡Ü¡Ü Ü Ü\90 Ü\95Ü\9dÜ Ü\97 Ü¬Ü¡Ü¢, Ü\98ܦÜ\90ܬÜ\90 Ü¬Ü\97Ü\98Ü\90 Ü\92ܣܪÜ\9bÜ\90 '''Ü\9aÜ Ü\9dÜ¡Ü\90''' Ü\92ܦÜ\90ܬÜ\90 Ü\95[[Special:RecentChanges|Ü«Ü\98Ü\9aܠܦÌ\88Ü\90 Ü\9aÜ\95Ì\88ܬÜ\90]] Ü Ü¦Ü«Ü\9bܬÜ\90 Ü\95Ü«Ü\9fÜ\9aܬÜ\97.",
+'addedwatchtext' => 'ܦܐܬܐ ܕ"[[:$1]]" ܐܬܬܘܣܦܬ ܠ[[Special:Watchlist|ܪ̈ܗܝܬܟ]].
\90Ü\9dÜ¢Ü\90 Ü«Ü\98Ü\9aܠܦÜ\90 Ü¥Ü  Ü¦Ü\90ܬÜ\90 Ü\97Ü\95Ü\90 Ü\92Ü\95ܥܬÜ\9dÜ\95 Ü¬Ü¬Ü\93Ü Ü\9a Ü¥Ü¡ Ü¦Ü\90ܬÜ\90 Ü\95Ü¡Ü¡Ü Ü Ü\90 Ü\95Ü\9dÜ Ü\97 Ü¬Ü¡Ü¢.',
 'removewatch' => 'ܫܩܘܠ ܡܢ ܪ̈ܗܝܬܝ',
 'removedwatchtext' => 'ܦܐܬܐ ܕ "[[:$1]]" ܐܫܬܩܠܬ ܡܢ [[Special:Watchlist|ܪ̈ܗܝܬܟ]].',
 'watch' => 'ܪܗܝ',
@@ -1244,6 +1257,7 @@ $1',
 'actioncomplete' => 'ܥܡܠܝܬܐ ܓܡܪܬ',
 'actionfailed' => 'ܥܡܠܝܬܐ ܠܐ ܢܨܚܬ',
 'dellogpage' => 'ܣܓܠܐ ܕܫܝܦܐ',
+'dellogpagetext' => 'ܠܬܚܬ ܡܟܬܒܘܬܐ ܕܦܐܬܬ̈ܐ ܫܝܦܬ̈ܐ ܚܕ̈ܬܬܐ.',
 'deletionlog' => 'ܣܓܠܐ ܕܫܝܦܐ',
 'deletecomment' => 'ܥܠܬܐ:',
 'deleteotherreason' => 'ܥܠܬܐ ܐܚܪܬܐ/ܝܬܝܪܬܐ:',
@@ -1253,7 +1267,7 @@ $1',
 # Rollback
 'rollbacklink' => 'ܐܦܢܝ',
 'editcomment' => "ܦܣܝܩܬ̈ܐ ܕܫܘܚܠܦܐ ܗܘܐ: \"''\$1''\".",
-'revertpage' => 'ܐܗܦܟ ܫܘܚܠܦ̈ܐ ܒܝܕ [[Special:Contributions/$2|$2]] ([[User talk:$2|ܡܡܠܠܐ]]) ܠܬܢܝܬܐ ܐܚܪܬܐ ܒܝܕ [[User:$1|$1]]',
+'revertpage' => 'Ü\90Ü\97ܦÜ\9f Ü«Ü\98Ü\9aܠܦÌ\88Ü\90 Ü\92Ü\9dÜ\95 [[Special:Contributions/$2|$2]] ([[User talk:$2|Ü¡Ü¡Ü Ü Ü\90]]) Ü Ü¬Ü¢Ü\9dܬÜ\90 Ü\90Ü\9aܪÜ\9dܬÜ\90 Ü\92Ü\9dÜ\95 [[User:$1|$1]]',
 
 # Edit tokens
 'sessionfailure-title' => 'ܡܘܬܒܐ ܠܐ ܢܨܚܬ',
@@ -1261,23 +1275,27 @@ $1',
 # Protect
 'protectlogpage' => 'ܣܓܠܐ ܕܢܛܪܐ',
 'protectedarticle' => 'ܢܛܪ "[[$1]]"',
+'modifiedarticleprotection' => 'ܫܚܠܦ ܫܘܝܐ ܕܢܛܪܐ ܕ"[[$1]]"',
 'unprotectedarticle' => 'ܫܩܘܠ ܢܛܝܪܘܬܐ ܡܢ "[[$1]]"',
 'movedarticleprotection' => 'ܫܢܐ ܛܘܝܒ̈ܐ ܕܢܛܪܐ ܡܢ "[[$2]]" ܠ "[[$1]]"',
+'protect-title' => 'ܫܚܠܦ ܫܘܝܐ ܕܢܛܪܐ ܕ"$1"',
+'protect-title-notallowed' => 'ܚܘܝ ܫܘܝܐ ܕܢܛܪܐ ܕ"$1"',
 'prot_1movedto2' => '[[$1]] ܐܬܫܢܝܬ ܠ [[$2]]',
 'protect-legend' => 'ܫܪܪ ܢܘܛܪܐ',
 'protectcomment' => 'ܥܠܬܐ:',
 'protect-default' => 'ܦܣܣܐ ܠܟܠ ܡܦܠܚܢ̈ܐ',
-'protect-fallback' => 'Ü\92Ü¥Ü\9d "$1" Ü¦Ü£Ü£Ü\90',
-'protect-level-autoconfirmed' => 'Ü\9aܪÜ\98Ü¡ Ü¡Ü¦Ü Ü\9aÜ¢Ì\88Ü\90 Ü\9aÜ\95Ì\88ܬÜ\90 Ü\98Ü Ü\90 Ü¥Ü Ü\9dÜ Ì\88Ü\90',
-'protect-level-sysop' => 'ܡܕܒܪ̈ܢܐ ܒܠܚܘܕ',
+'protect-fallback' => 'ܦܣܣ Ü Ü¡Ü¦Ü Ü\9aÜ¢Ì\88Ü\90 Ü¥Ü¡ "$1" Ü¦Ü£Ü£Ü\90 Ü\92Ü Ü\9aÜ\98Ü\95',
+'protect-level-autoconfirmed' => 'ܦܣܣ Ü Ü¡Ü¦Ü Ü\9aÜ¢Ì\88Ü\90 Ü\9aܬÜ\9dܬÌ\88Ü\90 Ü\9dܬÜ\90Ü\9dܬ Ü\92Ü Ü\9aÜ\98Ü\95',
+'protect-level-sysop' => 'ܦܣܣ Ü Ü¡Ü\95Ü\92ܪÌ\88Ü¢Ü\90 Ü\92Ü Ü\9aÜ\98Ü\95',
 'protect-expiring' => 'ܬܦܪܘܩ ܒ $1 (UTC)',
+'protect-expiring-local' => 'ܬܦܪܘܩ ܒ $1',
 'protect-expiry-indefinite' => 'ܠܥܠܡ',
-'protect-othertime' => 'Ü¥Ü\95Ü¢Ü\90 Ü\90Ü\9aܪܬܐ:',
-'protect-othertime-op' => 'Ü¥Ü\95Ü¢Ü\90 Ü\90Ü\9aܪܬܐ',
+'protect-othertime' => 'Ü¥Ü\95Ü¢Ü\90 Ü\90Ü\9aܪܢܐ:',
+'protect-othertime-op' => 'Ü¥Ü\95Ü¢Ü\90 Ü\90Ü\9aܪܢܐ',
 'protect-otherreason' => 'ܥܠܬܐ ܐܚܪܬܐ/ܢܩܝܦܬܐ:',
 'protect-otherreason-op' => 'ܥܠܬܐ ܐܚܪܬܐ',
 'protect-edit-reasonlist' => 'ܫܚܠܦ ܥܠܬܐ ܕܢܛܪܐ',
-'protect-expiry-options' => '1 Ü«Ü¥Ü¬Ü\90:1 hour,1 Ü\9dÜ\98Ü¡Ü\90:1 day,1 Ü«Ü\92Ü\98Ü¥Ü\90:1 week,2 Ü«Ü\92Ü\98Ü¥Ì\88Ü\90:2 weeks,1 Ü\9dܪÜ\9aÜ\90:1 month,3 Ü\9dܪÌ\88Ü\9aÜ\90:3 months,6 Ü\9dܪÌ\88Ü\9aÜ\90:6 months,1 Ü«Ü¢Ü¬ܐ:1 year,ܠܥܠܡ:infinite',
+'protect-expiry-options' => '1 Ü«Ü¥Ü\90:1 hour,1 Ü\9dÜ\98Ü¡:1 day,1 Ü«Ü\92Ü\98Ü¥:1 week,2 Ü«Ü\92Ü\98Ü¥Ì\88Ü\9dÜ¢:2 weeks,1 Ü\9dܪÜ\9a:1 month,3 Ü\9dܪÌ\88Ü\9aÜ\9dÜ¢:3 months,6 Ü\9dܪÌ\88Ü\9aÜ\9dÜ¢:6 months,1 Ü«Ü¢ܐ:1 year,ܠܥܠܡ:infinite',
 'restriction-type' => 'ܦܣܣܐ:',
 'restriction-level' => 'ܫܘܝܐ ܕܣܘܝܟܐ:',
 'minimum-size' => 'ܡܬܚܐ ܬܚܬܝܐ  ܕܥܓܪܐ',
@@ -1378,8 +1396,8 @@ $1',
 'ipbreason' => 'ܥܠܬܐ:',
 'ipbreasonotherlist' => 'ܥܠܬܐ ܐܚܪܬܐ',
 'ipbsubmit' => 'ܚܪܘܡ ܡܦܠܚܢܐ ܗܢܐ',
-'ipbother' => 'Ü¥Ü\95Ü¢Ü\90 Ü\90Ü\9aܪܬܐ',
-'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',
+'ipbother' => 'Ü¥Ü\95Ü¢Ü\90 Ü\90Ü\9aܪܢܐ',
+'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',
 'ipbotheroption' => 'ܐܚܪܢܐ',
 'ipbotherreason' => 'ܥܠܬܐ ܐܚܪܬܐ/ܢܩܝܦܬܐ:',
 'ipbhidename' => 'ܛܫܝ ܫܡܐ ܕܡܦܠܚܢܐ ܡܢ ܫܘܚܠܦ̈ܐ ܘܡܟܬܒܘܬ̈ܐ',
@@ -1451,9 +1469,13 @@ Do you want to change the settings?',
 # Namespace 8 related
 'allmessages' => 'ܐܓܪ̈ܬܐ ܕܛܟܣܐ',
 'allmessagesname' => 'ܫܡܐ',
+'allmessagesdefault' => 'ܐܓܪܬܐ ܕܟܬܒܬܐ ܡܬܚܫܒܢܝܬܐ',
 'allmessagescurrent' => 'ܟܬܒܬܐ ܗܫܝܬܐ ܕܐܓܪܬܐ',
 'allmessages-filter-legend' => 'ܡܨܦܝܢܝܬܐ',
+'allmessages-filter' => 'ܨܦܝ ܐܝܟ ܐܝܟܢܝܘܬܐ ܕܡܬܕܝܠܢܘܬܐ:',
+'allmessages-filter-unmodified' => 'ܠܐ ܫܘܓܢܝܐ',
 'allmessages-filter-all' => 'ܟܠ',
+'allmessages-filter-modified' => 'ܫܘܓܢܝܐ',
 'allmessages-prefix' => 'ܡܨܦܝܢܝܬܐ ܐܝܟ ܫܘܪܝܐ',
 'allmessages-language' => 'ܠܫܢܐ:',
 'allmessages-filter-submit' => 'ܙܠ',
@@ -1551,6 +1573,17 @@ Do you want to change the settings?',
 'pageinfo-contentpage-yes' => 'ܐܝܢ',
 'pageinfo-protect-cascading-yes' => 'ܐܝܢ',
 
+# Patrolling
+'markaspatrolleddiff' => 'ܫܘܕܥ ܐܝܟ ܟܪܝܟܬܐ',
+'markaspatrolledtext' => 'ܫܘܕܥ ܦܐܬܐ ܗܕܐ ܐܝܟ ܟܪܝܟܬܐ',
+'markedaspatrolled' => 'ܫܘܕܥܬ ܐܝܟ ܟܪܝܟܬܐ',
+'markedaspatrollednotify' => 'ܫܘܚܠܦܐ ܗܢܐ ܥܠ $1 ܐܫܬܘܕܥ ܐܝܟ ܟܪܝܟܐ.',
+'markedaspatrollederrornotify' => 'ܠܐ ܐܬܢܨܚ ܫܘܘܕܥܐ ܐܝܟ ܟܪܝܟܬܐ',
+
+# Patrol log
+'patrol-log-page' => 'ܣܓܠܐ ܕܟܪܟܐ',
+'log-show-hide-patrol' => '$1 ܣܓܠܐ ܕܟܪܟܐ',
+
 # Image deletion
 'filedeleteerror-short' => 'ܦܘܕܐ ܒܫܝܦܐ ܕܠܦܦܐ: $1',
 'filedeleteerror-long' => 'ܦܘܕ̈ܐ ܐܫܟܚܬ ܟܕ ܫܝܦܐ ܠܦܦܐ:
@@ -1588,6 +1621,7 @@ $1',
 'hours' => '{{PLURAL:$1|$1 ܫܥܬܐ|$1 ܫܥܬ̈ܐ}}',
 'days' => '{{PLURAL:$1|$1 ܝܘܡܐ|$1 ܝܘܡܬ̈ܐ}}',
 'ago' => 'ܩܕܡ $1',
+'just-now' => 'ܗܫܐ ܒܪ ܫܥܬܗ',
 
 # Metadata
 'metadata' => 'ܓܠܝܬ̈ܐ ܕܡܝܛܐ',
@@ -1656,6 +1690,8 @@ $1',
 'exif-gpsdirection-t' => 'ܨܘܒܐ ܬܪܝܨܐ',
 'exif-gpsdirection-m' => 'ܨܘܒܐ ܡܓܢܛܝܣܝܐ',
 
+'exif-dc-contributor' => 'ܫܘܬܦܢ̈ܐ',
+
 # 'all' in various places, this might be different for inflected languages
 'watchlistall2' => 'ܟܠ',
 'namespacesall' => 'ܟܠ',
@@ -1748,7 +1784,7 @@ $1',
 'specialpages-group-highuse' => 'ܦܐܬܬ̈ܐ ܕܡܬܚܫܚܢܘܬܐ ܥܠܝܬܐ',
 'specialpages-group-pages' => 'ܡܟܬܒܘܬ̈ܐ ܕܦܐܬܬ̈ܐ',
 'specialpages-group-pagetools' => 'ܡܐܢ̈ܐ ܕܦܐܬܐ',
-'specialpages-group-wiki' => 'ܓܠܝܬ̈ܐ ܘܡܐܢ̈ܐ ܕܘܝܩܝ',
+'specialpages-group-wiki' => 'ܓܠܝܬ̈ܐ ܘܡܐܢ̈ܐ',
 'specialpages-group-redirects' => 'ܨܘܝܒܐ ܕܦܐܬܐ ܕܝܠܢܝܬܐ',
 
 # Special:BlankPage
@@ -1756,7 +1792,10 @@ $1',
 
 # Special:Tags
 'tags' => 'ܚܬ̈ܡܐ ܕܫܘܚܠܦܐ ܬܪܝܨܐ',
+'tag-filter' => 'ܡܨܦܝܢܝܬܐ ܕ[[Special:Tags|ܪܘܫܡܐ]]:',
 'tag-filter-submit' => 'ܡܨܦܝܢܝܬܐ',
+'tags-title' => 'ܪ̈ܘܫܡܐ',
+'tags-tag' => 'ܫܡܐ ܕܪܘܫܡܐ',
 'tags-edit' => 'ܫܚܠܦ',
 'tags-hitcount' => '$1 {{PLURAL:$1|ܫܘܚܠܦܐ|ܫܘܚܠܦ̈ܐ}}',
 
@@ -1780,11 +1819,12 @@ $1',
 'logentry-move-move-noredirect' => '$1 ܫܢܐ ܦܐܬܐ ܕ $3 ܠ $4 ܕܠܐ ܫܒܩܐ ܦܐܬܐ ܕܨܘܝܒܐ',
 'logentry-move-move_redir' => '$1 ܫܢܐ ܦܐܬܐ ܕ $3 ܠ $4 ܕܐܝܬܘܗܝ ܦܐܬܐ ܕܨܘܝܒܐ',
 'logentry-move-move_redir-noredirect' => '$1 ܫܢܐ ܦܐܬܐ ܕ $3 ܠ $4 ܕܐܝܬܘܗܝ ܦܐܬܐ ܕܨܘܝܒܐ ܘܕܠܐ ܫܒܩܐ ܦܐܬܐ ܕܨܘܝܒܐ',
+'logentry-patrol-patrol' => '$1 ܫܘܕܥ ܬܢܝܬܐ $4 ܕܦܐܬܐ $3 ܟܪܝܟܬܐ',
+'logentry-patrol-patrol-auto' => '$1 ܝܬܐܝܬ ܫܘܕܥ ܬܢܝܬܐ $4 ܕܦܐܬܐ $3 ܟܪܝܟܬܐ',
 'logentry-newusers-newusers' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $1 ܐܬܒܪܐ',
 'logentry-newusers-create' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $1 ܐܬܒܪܐ',
 'logentry-newusers-create2' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $3 ܐܬܒܪܐ ܒܝܕ $1',
 'logentry-newusers-autocreate' => 'ܚܘܫܒܢܐ $1 ܐܬܒܪܝ ܝܬܐܝܬ',
-'newuserlog-byemail' => 'ܡܠܬܐ ܕܥܠܠܐ ܐܫܬܕܪܬ ܒܝܕ ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ',
 'rightsnone' => '(ܠܐ ܡܕܡ)',
 
 # Feedback
index c4014a1..2213623 100644 (file)
@@ -2711,7 +2711,6 @@ jrreb l-ĝṛḍ l-ĝadi.',
 # New logging system
 'revdelete-restricted' => 'tḅḅq ḍ-ḍawaḅit ll-idariyyin',
 'revdelete-unrestricted' => 'ḫyyd ḍ-ḍawaḅit ll-idariyyin',
-'newuserlog-byemail' => "lmot de passe raha tsiftat f l'email",
 'rightsnone' => '(walo)',
 
 );
index 1155020..f532760 100644 (file)
@@ -3475,7 +3475,6 @@ $5
 # New logging system
 'revdelete-restricted' => 'طبق التعليمات على السيسوبات',
 'revdelete-unrestricted' => 'شيل الضوابط من على السيسوبات',
-'newuserlog-byemail' => 'الباسورد اتبعتت بالايميل',
 'rightsnone' => '(فاضى)',
 
 # Search suggestions
index 76bd39e..bcd5f06 100644 (file)
@@ -3864,7 +3864,6 @@ $5
 'logentry-newusers-create' => "ব্যৱহাৰকাৰী একাউণ্ট $1 সৃষ্টি কৰা হ'ল",
 'logentry-newusers-create2' => "$1ৰ দ্বাৰা এটা ব্যৱহাৰকাৰী একাউণ্ট $3 সৃষ্টি কৰা হ'ল",
 'logentry-newusers-autocreate' => '$1’ৰ একাউণ্ট স্বয়ংক্ৰিয়ভাৱে সৃষ্টি কৰা হৈছিল',
-'newuserlog-byemail' => 'গুপ্তশব্দ ই-মেইল কৰি পঠোৱা হৈছে',
 'logentry-rights-rights' => "$1ৰ গোট সদস্যপদ $3ৰ পৰা $4লৈ $5 লৈ সলনি কৰা হ'ল",
 'logentry-rights-rights-legacy' => "$1-ৰ গোট সদস্যপদ $3-লৈ সলনি কৰা হ'ল",
 'logentry-rights-autopromote' => '$1ক  $4ৰ পৰা $5লৈ স্বয়ংক্ৰিয়ভাৱে পদোন্নীত কৰা হ’ল',
index c6b25e0..f71437c 100644 (file)
@@ -497,7 +497,7 @@ Nun t'escaezas d'escoyer les tos [[Special:Preferences|preferencies de {{SITENAM
 'gotaccount' => '¿Ya tienes una cuenta? $1.',
 'gotaccountlink' => 'Identificase',
 'userlogin-resetlink' => "¿Escaecisti los datos d'identificación?",
-'createaccountmail' => 'Per corréu electrónicu',
+'createaccountmail' => 'Usar una contraseña al debalu temporal y unviala a la direición de corréu electrónicu conseñada más abaxo',
 'createaccountreason' => 'Motivu:',
 'badretype' => "Les claves qu'escribisti nun concuayen.",
 'userexists' => "El nome d'usuariu conseñáu yá ta usándose.
@@ -578,6 +578,7 @@ Por favor espera enantes d'intentalo otra vuelta.",
 # E-mail sending
 'php-mail-error-unknown' => 'Fallu desconocíu na función mail() de PHP.',
 'user-mail-no-addy' => 'Intentasti unviar un corréu electrónicu ensin direición.',
+'user-mail-no-body' => "Trató d'unviar un corréu electrónicu con un cuerpu baleru o curtiu enforma.",
 
 # Change password dialog
 'resetpass' => 'Camudar la clave',
@@ -818,7 +819,7 @@ Amás tas dexándonos afitao qu'escribisti esto tu mesmu, o que lo copiasti d'un
 'longpageerror' => "'''ERROR: El testu qu'unviasti tien {{PLURAL:$1|un quilobyte|$1 quilobytes}}, que pasa del máximu de {{PLURAL:$2|un quilobyte|$2 quilobytes}}.'''
 Nun se pue grabar.",
 'readonlywarning' => "'''Avisu: La base de datos ta candada por mantenimientu, polo que nun vas poder guardar les tos ediciones nestos momentos.'''
-Seique habríes copiar el testu nun ficheru de testu y guardalu pa intentalo llueu.
+Seique habríes copiar y apegar el testu nun ficheru de testu y guardalu pa intentalo más sero.
 
 L'alministrador que la candó dio esta esplicación: $1",
 'protectedpagewarning' => "'''Avisu: Esta páxina ta candada pa que sólo los alministradores puean editala.'''
@@ -1125,7 +1126,7 @@ Se puen alcontrar más detalles nel [{{fullurl:{{#Special:Log}}/delete|page={{FU
 'search-interwiki-default' => '$1 resultaos:',
 'search-interwiki-more' => '(más)',
 'search-relatedarticle' => 'Rellacionáu',
-'mwsuggest-disable' => 'Desactivar les suxerencies AJAX',
+'mwsuggest-disable' => 'Desactivar les suxerencies de gueta',
 'searcheverything-enable' => 'Buscar en tolos espacios de nome',
 'searchrelated' => 'rellacionáu',
 'searchall' => 'toos',
@@ -2038,7 +2039,7 @@ Necesita polo menos un dominiu de primer nivel, como "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => "Llista d'usuarios activos",
 '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}} nos caberos {{PLURAL:$3|día|$3 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',
@@ -2103,7 +2104,7 @@ La direición de corréu electrónicu qu\'especificasti nes [[Special:Preference
 'usermessage-editor' => 'Mensaxería del sistema',
 
 # Watchlist
-'watchlist' => 'La mio llista de vixilancia',
+'watchlist' => 'Llista de vixilancia',
 'mywatchlist' => 'Llista de vixilancia',
 'watchlistfor2' => 'Pa $1 $2',
 'nowatchlist' => 'La to llista de vixilancia ta vacia.',
@@ -2270,9 +2271,9 @@ la base de datos. Esta ye la configuración actual de la páxina '''$1''':",
 Esta ye la configuración actual pa la páxina '''$1''':",
 'protect-cascadeon' => "Esta páxina ta protexida nestos momentos porque ta inxerida {{PLURAL:$1|na siguiente páxina, que tien|nes siguientes páxines, que tienen}} activada la proteición en cascada. Pues camudar el nivel de proteición d'esta páxina, pero nun va afeutar a la proteición en cascada.",
 'protect-default' => 'Permitir tolos usuarios',
-'protect-fallback' => 'Requier el permisu "$1"',
-'protect-level-autoconfirmed' => 'Bloquiar usuarios nuevos y non rexistraos',
-'protect-level-sysop' => 'Namái alministradores',
+'protect-fallback' => 'Permitir namái usuarios con permisu "$1"',
+'protect-level-autoconfirmed' => 'Permitir namái usuarios autoconfirmaos',
+'protect-level-sysop' => 'Permitir namái alministradores',
 'protect-summary-cascade' => 'en cascada',
 'protect-expiring' => "caduca'l $1 (UTC)",
 'protect-expiring-local' => 'caduca el $1',
@@ -2565,16 +2566,16 @@ Como nun tienes permisos p'anubrir usuarios, nun pues ver o editar el bloquéu d
 'move-page' => 'Treslladar $1',
 'move-page-legend' => 'Treslladar páxina',
 'movepagetext' => "Usando'l siguiente formulariu vas renomar una páxina, treslladando'l so historial al nuevu nome.
-El nome vieyu va convertise nuna redireición al nuevu.
-Pues actualizar redireiciones qu'enllacien al títulu orixinal automáticamente.
+El nome vieyu va convertise nuna páxina de redireición al títulu nuevu.
+Pues actualizar les redireiciones qu'enllacien al títulu orixinal automáticamente.
 Si prefieres nun lo facer, asegúrate de que nun dexes [[Special:DoubleRedirects|redireiciones dobles]] o [[Special:BrokenRedirects|rotes]].
-Tu yes el responsable de facer que los enllaces queden apuntando aonde se supón qu'han apuntar.
+Tu yes el responsable de facer que los enllaces queden apuntando au se supón que tienen d'apuntar.
 
-Recuerda que la páxina '''nun''' va movese si yá hai una páxina col nuevu títulu, a nun ser que tea vacia o seya una redireición que nun tenga historial.
-Esto significa que pues volver a renomar una páxina col nome orixinal si t'enquivoques, y que nun pues sobreescribir una páxina yá esistente.
+Recuerda que la páxina '''nun''' va movese si yá hai una páxina col nuevu títulu, a nun ser que la mesma seya una redireición y nun tenga historial.
+Esto significa que pues volver a renomar una páxina col nome orixinal si t'enquivoques, y nun pues sobreescribir una páxina yá esistente.
 
-¡AVISU!'''
-Esti pue ser un cambéu importante y inesperáu pa una páxina popular;
+¡Avisu!'''
+Esti pue ser un cambéu importante ya inesperáu pa una páxina popular;
 por favor, asegúrate d'entender les consecuencies de lo que vas facer enantes de siguir.",
 'movepagetext-noredirectfixer' => "Usando'l siguiente formulariu vas renomar una páxina, treslladando'l so historial al nuevu nome.
 El nome vieyu va convertise nuna redireición al nuevu.
@@ -2923,6 +2924,7 @@ Probablemente tea causao por un enllaz a un sitiu esternu de la llista prieta.',
 'pageinfo-robot-noindex' => 'Nun pue ser índiz',
 'pageinfo-views' => 'Númberu de visites',
 'pageinfo-watchers' => 'Númberu de vixilantes de la páxina',
+'pageinfo-few-watchers' => 'Menos de $1 {{PLURAL:$1|vixilante|vixilantes}}',
 'pageinfo-redirects-name' => 'Redireiciones a esta páxina',
 'pageinfo-subpages-name' => "Subpáxines d'esta páxina",
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redireición|redireiciones}}; $3 {{PLURAL:$3|non-redireición|non-redireiciones}})',
@@ -3700,7 +3702,7 @@ Les imáxenes amuésense a resolución completa; les demás tribes d'archivu exe
 'specialpages-group-highuse' => 'Páxines mui usaes',
 'specialpages-group-pages' => 'Llistes de páxines',
 'specialpages-group-pagetools' => 'Ferramientes de páxina',
-'specialpages-group-wiki' => 'Datos wiki y ferramientes',
+'specialpages-group-wiki' => 'Datos y ferramientes',
 'specialpages-group-redirects' => 'Páxines especiales de redireición',
 'specialpages-group-spam' => 'Ferramientes pa spam',
 
@@ -3797,8 +3799,8 @@ Les imáxenes amuésense a resolución completa; les demás tribes d'archivu exe
 'logentry-newusers-newusers' => "Se creó la cuenta d'usuariu $1",
 'logentry-newusers-create' => "Se creó la cuenta d'usuariu $1",
 'logentry-newusers-create2' => "$1 creó la cuenta d'usuariu $3",
+'logentry-newusers-byemail' => "$1 creó la cuenta d'usuariu $3 y la contraseña uviose per corréu electrónicu",
 'logentry-newusers-autocreate' => 'La cuenta $1 se creó automáticamente',
-'newuserlog-byemail' => 'conseña unviada per corréu electrónicu',
 'logentry-rights-rights' => '$1 camudó la pertenencia a grupos de $3 dende $4 a $5',
 'logentry-rights-rights-legacy' => '$1 camudó la pertenencia a grupos de $3',
 'logentry-rights-autopromote' => '$1 promocionó automáticamente de $4 a $5',
@@ -3856,6 +3858,7 @@ D\'otra miente, pues usar el formulariu cenciellu d\'abaxo. El to comentariu apa
 'api-error-ok-but-empty' => 'Fallu internu: nun hai respuesta del sirvidor.',
 'api-error-overwrite' => 'Nun ta permitío sobroscribir un ficheru esistente.',
 'api-error-stashfailed' => 'Fallu internu: el sirvidor nun pudo guardar el ficheru temporal.',
+'api-error-publishfailed' => 'Fallu internu: el sirvidor nun pudo espublizar el ficheru temporal.',
 'api-error-timeout' => 'El sirvidor nun respondió nel tiempu esperáu.',
 'api-error-unclassified' => 'Hebo un fallu desconocíu',
 'api-error-unknown-code' => 'Fallu desconocíu: «$1»',
index 0dfc520..7895ca4 100644 (file)
@@ -2385,7 +2385,6 @@ This confirmation code will expire at $4.',
 # New logging system
 'revdelete-restricted' => 'irutara rewana pu ristusik',
 'revdelete-unrestricted' => 'irutara tiolteyena pu ristusik',
-'newuserlog-byemail' => 'remravlem staksayan kan e-mail',
 'rightsnone' => '(mek)',
 
 );
index 619364b..bfdc182 100644 (file)
@@ -16,6 +16,7 @@
  * @author Erdemaslancan
  * @author Gulmammad
  * @author Kaganer
+ * @author Khan27
  * @author PPerviz
  * @author PrinceValiant
  * @author Sortilegus
@@ -113,7 +114,7 @@ $messages = array(
 'tog-externaleditor' => 'Susmaya görə xarici müqayisə proqramlarından istifadə et',
 'tog-externaldiff' => 'Susmaya görə xarici müqayisə proqramlarından istifadə et',
 'tog-showjumplinks' => '"Keçid et:" linklərini aktivləşdir',
-'tog-uselivepreview' => 'Canlı sınaq baxışı xüsusiyyətini istifadə et (JavaScript, sınaq mərhələsində)',
+'tog-uselivepreview' => 'Canlı sınaq baxışı xüsusiyyətindən istifadə et (JavaScript tələb edir, sınaq mərhələsindədir)',
 'tog-forceeditsummary' => 'Qısa məzmunu boş saxladıqda mənə bildir',
 'tog-watchlisthideown' => 'Mənim redaktələrimi izləmə siyahısında gizlət',
 'tog-watchlisthidebots' => 'Bot redaktələrini izləmə siyahısında gizlət',
@@ -248,6 +249,7 @@ $messages = array(
 'namespaces' => 'Adlar fəzası',
 'variants' => 'Variantlar',
 
+'navigation-heading' => 'Naviqasiya menyusu',
 'errorpagetitle' => 'Xəta',
 'returnto' => '$1 səhifəsinə qayıt.',
 'tagline' => '{{SITENAME}} saytından',
@@ -477,12 +479,16 @@ Göstərilən səbəb: "\'\'$2\'\'".',
 'logouttext' => "'''Sistemdən çıxdınız.'''
 
 Siz {{SITENAME}} saytını anonim olaraq istifadə etməyə davam edə bilər və ya eyni, yaxud başqa istifadəçi adı ilə <span class='plainlinks'>[$1 yenidən daxil ola]</span> bilərsiniz. Veb-brauzerin keş yaddaşını təmizləyənədək bəzi səhifələr hələ də sistemdə imişsiniz kimi görünə bilər.",
+'welcomeuser' => 'Xoş gəldin $1!',
+'welcomecreation-msg' => 'Hesabınız yaradıldı.
+[[Special:Preferences|{{SITENAME}} nizamlamalarınızı]] dəyişdirməyi unutmayın.',
 'yourname' => 'İstifadəçi adı',
 'yourpassword' => 'Parol:',
 'yourpasswordagain' => 'Parolu təkrar yazın:',
 'remembermypassword' => 'Məni bu kompyuterdə xatırla (maksimum $1 {{PLURAL:$1|gün|gün}})',
 'securelogin-stick-https' => 'Daxil olduqdan sonra HTTPS-lə əlaqədə qal',
 'yourdomainname' => 'Sizin domain',
+'password-change-forbidden' => 'Bu vikidə parolunuzu dəyişdirə bilməzsiniz.',
 'externaldberror' => 'Verilənlər bazasının doğruluğunu yoxlamada xəta baş verib və yaxud sizin xarici istifadəçi qeydiyyatını yeniləmək hüququnuz yoxdur.',
 'login' => 'Daxil ol',
 'nav-login-createaccount' => 'Daxil ol / hesab yarat',
@@ -544,6 +550,7 @@ Aşağıdakı xidmətlərin heç biri üçün Sizə e-məktub göndərilməyəc
 'emailconfirmlink' => 'E-poçt ünvanını təsdiq et',
 'invalidemailaddress' => 'E-poçt ünvanınızı qeyri-düzgün formatda olduğu üçün qəbul edə bilmirik.
 Xahiş edirik düzgün formatlı ünvan daxil edin və ya bu sahəni boş qoyun.',
+'emaildisabled' => 'Bu saytdan e-poçt göndərə bilməzsiniz.',
 'accountcreated' => 'Hesab yaradıldı',
 'accountcreatedtext' => '$1 üçün istifadəçi hesabı yaradıldı.',
 'createaccount-title' => '{{SITENAME}} hesabın yaradılması',
@@ -2985,7 +2992,6 @@ Bu saytda texniki problemlər var.',
 'logentry-newusers-create' => '$1 istifadəçi hesabı yaratdı',
 'logentry-newusers-create2' => '$1 $3 üçün istifadəçi hesabı yaratdı',
 'logentry-newusers-autocreate' => '$1 hesabı avtomatik yaradıldı',
-'newuserlog-byemail' => 'parol e-maillə göndərildi',
 'rightsnone' => '(yoxdur)',
 
 # Feedback
index da965d9..53fd602 100644 (file)
 $fallback = 'fa';
 $rtl = true;
 
+$namespaceNames = array(
+       NS_MEDIA            => 'مئدیا',
+       NS_SPECIAL          => 'اؤزل',
+       NS_MAIN             => '',
+       NS_TALK             => 'دانیشیق',
+       NS_USER             => 'ایستیفاده‌چی',
+       NS_USER_TALK        => 'ایستیفاده‌چی_دانیشیغی',
+       NS_PROJECT_TALK     => '$1_دانیشیق',
+       NS_FILE             => 'فایل',
+       NS_FILE_TALK        => 'فایل_دانیشیغی',
+       NS_MEDIAWIKI        => 'مئدیا‌ویکی',
+       NS_MEDIAWIKI_TALK   => 'مئدیا‌ویکی_دانیشیغی',
+       NS_TEMPLATE         => 'شابلون',
+       NS_TEMPLATE_TALK    => 'شابلون_دانیشیغی',
+       NS_HELP             => 'یاردیم',
+       NS_HELP_TALK        => 'یاردیم_دانیشیغی',
+       NS_CATEGORY         => 'بؤلمه',
+       NS_CATEGORY_TALK    => 'بؤلمه_دانیشیغی',
+);
+
+$specialPageAliases = array(
+       'Activeusers'               => array( 'چالیشقان_ایستسفاده‌چیلر' ),
+       'Allmessages'               => array( 'بوتون_مئساژلار' ),
+       'Allpages'                  => array( 'بوتون_صحیفه‌لر' ),
+       'Ancientpages'              => array( 'اسکی_صحیفه‌لر' ),
+       'Badtitle'                  => array( 'پیس_آد' ),
+       'Blankpage'                 => array( 'بوش_صحیفه' ),
+       'ChangePassword'            => array( 'رمزی_دَییش' ),
+       'CreateAccount'             => array( 'حساب_یارات' ),
+       'Mycontributions'           => array( 'چالیشمالاریم' ),
+       'Mypage'                    => array( 'صحیفه‌م' ),
+       'Mytalk'                    => array( 'دانیشیغیم' ),
+       'Myuploads'                 => array( 'یوکله‌دیکلریم' ),
+       'Newimages'                 => array( 'یئنی_فایل‌لار' ),
+       'Newpages'                  => array( 'یئنی_صحیفه‌لر' ),
+       'PasswordReset'             => array( 'رمز_دَییشمه‌' ),
+       'Randompage'                => array( 'راست‌گله' ),
+       'Recentchanges'             => array( 'سون_دَییشیکلر' ),
+       'Search'                    => array( 'آختار' ),
+       'Shortpages'                => array( 'قیسسا_صحیفه‌لر' ),
+       'Specialpages'              => array( 'اؤزل_صحیفه‌لر' ),
+       'Statistics'                => array( 'آمار' ),
+       'Unusedcategories'          => array( 'ایشلنممیش_بؤلمه‌لر' ),
+       'Unusedimages'              => array( 'ایشلنممیش_فایل‌لار' ),
+       'Unusedtemplates'           => array( 'ایشلنممیش_شابلونلار' ),
+       'Unwatchedpages'            => array( 'باخیلمامیش_صحیفه‌لر' ),
+       'Upload'                    => array( 'یوکله' ),
+       'Version'                   => array( 'نوسخه' ),
+       'Watchlist'                 => array( 'ایزله‌دیکلر' ),
+);
+
+$magicWords = array(
+       'numberofpages'             => array( '1', 'صحیفه‌لر_ساییسی', 'تعدادصفحه‌ها', 'NUMBEROFPAGES' ),
+       'numberofarticles'          => array( '1', 'مقاله‌لر_ساییسی', 'تعدادمقاله‌ها', 'NUMBEROFARTICLES' ),
+       'numberoffiles'             => array( '1', 'قایل‌لار_ساییسی', 'تعدادپرونده‌ها', 'NUMBEROFFILES' ),
+       'numberofusers'             => array( '1', 'ایستیفاده‌چیلر_ساییسی', 'تعدادکاربران', 'NUMBEROFUSERS' ),
+       'numberofactiveusers'       => array( '1', 'چالیشقان_ایستیفاده‌چیلر', 'کاربران‌فعال', 'کاربران_فعال', 'NUMBEROFACTIVEUSERS' ),
+       'numberofedits'             => array( '1', 'دَییشدیرمه_ساییسی', 'تعدادویرایش‌ها', 'NUMBEROFEDITS' ),
+       'pagename'                  => array( '1', 'صحیفه‌نین_آدی', 'نام‌صفحه', 'نام_صفحه', 'PAGENAME' ),
+       'img_right'                 => array( '1', 'ساغ', 'راست', 'right' ),
+       'img_left'                  => array( '1', 'سول', 'چپ', 'left' ),
+       'img_none'                  => array( '1', 'هئچ', 'هیچ', 'none' ),
+       'img_framed'                => array( '1', 'قابیق', 'قاب', 'framed', 'enframed', 'frame' ),
+);
+
 $messages = array(
 # User preference toggles
 'tog-underline' => 'باغلانتی‌لارین آلتینی خطله:',
@@ -456,7 +521,7 @@ $2',
 'gotaccount' => 'اؤنجه‌دن حسابینیز وارمی؟ $1.',
 'gotaccountlink' => 'گیریش',
 'userlogin-resetlink' => 'گیریش بیلگیلرینیزی اونوتموسونوز؟',
-'createaccountmail' => 'اÛ\8cÙ\85Û\8cÙ\84 Ø§Û\8cÙ\84Ù\87',
+'createaccountmail' => 'بÛ\8cر Ú¯Ø¦Ú\86Û\8cجÛ\8c Ø±Ø§Ø³Øªâ\80\8cÚ¯Ù\84Ù\87 Ø±Ù\85ز Ø§Û\8cØ´Ù\84ت Ù\88 Ø§Ù\88Ù\86Ù\88 Ø¢Ø´Ø§ØºÛ\8cدا Ø¨Ù\84Ù\84Ù\86دÛ\8cرÙ\86 Ø§Û\8cÙ\85Û\8cÙ\84 Ø¢Ø¯Ø±Ø³Û\8cÙ\86Ù\87 Ú¯Ø¤Ù\86در',
 'createaccountreason' => 'نَدَن‌لیک:',
 'badretype' => 'یازدیغینیز رمزلر بیر دئییل‌لر.',
 'userexists' => 'یازدیغینیز آد، اؤنجه‌دن ایشده‌دیر.
@@ -752,9 +817,9 @@ $2
 آیریجا بو علاوه یازینی سیزین یازدیغینیزدان یا دا سربست کوپیالاما ایجازه‌سی وئرن بیر قایناق‌دان کوپیالادیغینیزی بیزه اؤهده‌لرینه ائتمکدسینیز (دئتال‌لار اوچون ایستیناد: $1).',
 'longpageerror' => "خطا: داخیل متنین اوزون‌لوغو قبول ائدیله بیلر ان چوخ اوزونلوق اولان {{PLURAL: $2 | بیر کیلوبایت | $2 کیلوبایت}} دان چوخ‌دور و {{PLURAL: $1 | بیر کیلوبایت | $1 کیلوبایت}} بؤیوکلوگونده‌دیر.'
 دییشیک‌لیگی‌نین کایدئدیلئمئز.",
-'readonlywarning' => "'''دیققت: باخیم سببی ایله وئریلن‌لر بازاسی بو آندا کیلیدلی‌دیر. بو سببله دییشیک‌لیک‌لری‌نین بو آندا قئیدئدیل میجاغدیر. یازدیق‌لارینیزی باشقا بیر پرونده ده آلیب ساخلایا و داها سونرا تکرار بورا گتیریب یازا بیلرسینیز '
+'readonlywarning' => "'''دیقت: باخیم سببی ایله دیتابیس بو آندا قیفیللی‌دیر. بو سببله دییشیک‌لیکلری‌نین بو آندا قئید ائدیل میه‌جکدیر. یازدیقلارینیزی باشقا بیر فایل‌دا آلیب ساخلایا و داها سونرا یئنی‌دن بورا گتیریب یازا بیلرسینیز.
 
-کیلیدله‌ین خیدمتله بو شرحی علاوه ائتمیش‌دیر: $1",
+اونو قیفیل‌لایان ایداره‌چی، بو شرحی وئریب‌دیر: $1",
 'protectedpagewarning' => "' 'خاطیرلیریق: بو ​​صحیفه باغلانیب دیر و یالنیز مودیر اولان‌لار طرفین‌دن دییش‌دیریله بیلر.'
 سون گونده‌لیک گیردی‌سی ایستیناد مقصدلی آشاغیدا وئریلمیش‌دیر:",
 'semiprotectedpagewarning' => "'قئید:' بو صحیفه محافظه‌لی اولدوغو اوچون یالنیز قئیدیات‌دان کئچمیش ایستیفاده‌چی‌لر دییشدیر ائده بیلرلر.",
@@ -1962,7 +2027,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization صحیفه‌‌سین
 # Special:ActiveUsers
 'activeusers' => 'چالیشان ایستیفاده‌چیلرین لیستی',
 'activeusers-intro' => 'بوردا سون {{PLURAL:$1|بیر|$1}} گون‌ده بیر ایشلر گؤرن ایستیفاده‌چیلرین لیستی گؤستریلیر.',
-'activeusers-count' => 'سون {{PLURAL:$3|بیر|$3}} گون‌ده، {{PLURAL:$1|بیر|$1}} دَییشیکلیک.',
+'activeusers-count' => 'سون {{PLURAL:$3|گون|$3 گون}}‌ده، {{PLURAL:$1|$1}} چالیشما',
 'activeusers-from' => 'بوندان باشلایاراق ایستیفاده‌چیلری گؤستر:',
 'activeusers-hidebots' => 'بوتلاری گیزلت',
 'activeusers-hidesysops' => 'ایداره‌چیلری گیزلت',
@@ -2585,9 +2650,9 @@ $1 آدلی ایستیفاده‌چی‌نین باغلانما سببی: "$2"',
 'exportlistauthors' => 'هر صحیفه‌‌ اوچون دَییشدیرمه ائدن سیياهیسینی اؤزونده ساخلايین',
 'export-submit' => 'ایخراج',
 'export-addcattext' => 'صحیفه‌لری بو بولمه دن علاوه ائت:',
-'export-addcat' => 'عÙ\84اÙ\88Ù\87 Ø§Ø¦Øª',
+'export-addcat' => 'آرتÛ\8cر',
 'export-addnstext' => 'صحیفه‌لری آدلار فزاسین‌دان علاوه ائت:',
-'export-addns' => 'عÙ\84اÙ\88Ù\87 Ø§Ø¦Øª',
+'export-addns' => 'آرتÛ\8cر',
 'export-download' => 'فایلی قئید ائت',
 'export-templates' => 'شابلون‌لاری داخیل ائت',
 'export-pagelinks' => 'باغ‌لی صحیفه‌لری داخیل درین‌لیک:',
@@ -3564,7 +3629,7 @@ $5
 'specialpages-group-highuse' => 'ان چوخ ایستیفاده ائدیلن صحیفه‌لر',
 'specialpages-group-pages' => 'صحیفه‌لرین سیاهی‌لاری',
 'specialpages-group-pagetools' => 'صحیفه آلتلری',
-'specialpages-group-wiki' => 'ویکی بیلگیلری و آلت‌لری',
+'specialpages-group-wiki' => 'بیلگیلر و آلتلر',
 'specialpages-group-redirects' => 'خصوصی ایستیقامتلندیرمه صحیفه‌لری',
 'specialpages-group-spam' => 'هرزه یازماق آلت‌لری',
 
@@ -3662,8 +3727,8 @@ $5
 'logentry-newusers-newusers' => ' بیر ایستیفاده‌چی حسابی $1 یاراتدی',
 'logentry-newusers-create' => 'بیر ایستیفاده‌چی حسابی $1 یاراتدی',
 'logentry-newusers-create2' => 'بیر ایستیفاده‌چی $1 حسابی $3 یاراتدی',
+'logentry-newusers-byemail' => '$3 ایستیفاده‌چی حسابی، $1 ایله یارادیلیب و رمز، ایمیل ایله گؤندریلیب‌دیر',
 'logentry-newusers-autocreate' => '$1 حسابی اوتوماتیک یارادیلدی',
-'newuserlog-byemail' => 'رمز ایمیل ایله گؤندریلدی',
 'logentry-rights-rights' => '$1 $3-ین قروپ عوضولوگونو $4-دن $5-ه دَییشدیردی',
 'logentry-rights-rights-legacy' => '$1، $3-ین قروپ عوضولوگونو دَییشدیردی',
 'logentry-rights-autopromote' => '$1-ین مقامی اوتوماتیک $4-دن $5-ه آرتیریلدی',
@@ -3721,6 +3786,7 @@ $5
 'api-error-ok-but-empty' => 'ایچری خطا: خیدمتچی‌دن جاواب گلمه‌دی.',
 'api-error-overwrite' => 'بیر اولان فایلین اوستونه یازماغا ایجازه یوخدور.',
 'api-error-stashfailed' => 'ایچری خطا: خیدمتچی، گئچیجی فایلی ساخلایانمادی.',
+'api-error-publishfailed' => 'ایچری خطاسی: خیدمت‌چی، گئچیجی فایلی یایانمادی.',
 'api-error-timeout' => 'خیدمتچی، گؤزله‌نیلن واخت‌دا جاواب وئرمه‌دی.',
 'api-error-unclassified' => 'بیر تانینمامیش خطا قاباغا گلدی.',
 'api-error-unknown-code' => 'تانینمامیش خطا: «$1».',
index c978f66..1e54f43 100644 (file)
@@ -29,8 +29,8 @@ $namespaceNames = array(
        NS_USER             => 'Ҡатнашыусы',
        NS_USER_TALK        => 'Ҡатнашыусы_менән_һөйләшеү',
        NS_PROJECT_TALK     => '$1_буйынса_фекерләшеү',
-       NS_FILE             => 'РÓ\99Ñ\81ем',
-       NS_FILE_TALK        => 'РÓ\99Ñ\81ем_буйынса_фекерләшеү',
+       NS_FILE             => 'Файл',
+       NS_FILE_TALK        => 'Файл_буйынса_фекерләшеү',
        NS_MEDIAWIKI        => 'MediaWiki',
        NS_MEDIAWIKI_TALK   => 'MediaWiki_буйынса_фекерләшеү',
        NS_TEMPLATE         => 'Ҡалып',
@@ -46,6 +46,8 @@ $namespaceAliases = array(
        'Фекер_алышыу'                => NS_TALK,
        'Ҡатнашыусы_м-н_фекер_алышыу' => NS_USER_TALK,
        '$1_б-са_фекер_алышыу'        => NS_PROJECT_TALK,
+       'Рәсем'                       => NS_FILE,
+       'Рәсем_буйынса_фекерләшеү'    => NS_FILE_TALK,
        'Рәсем_б-са_фекер_алышыу'     => NS_FILE_TALK,
        'MediaWiki_б-са_фекер_алышыу' => NS_MEDIAWIKI_TALK,
        'Ҡалып_б-са_фекер_алышыу'     => NS_TEMPLATE_TALK,
@@ -3796,7 +3798,6 @@ MediaWiki файҙалы булыр, тигән өмөттә, ләкин БЕР
 'logentry-newusers-create' => '$1 ҡатнашыусыһының иҫәп яҙмаһы булдырылды',
 'logentry-newusers-create2' => '$3 ҡатнашыусыһының иҫәп яҙмаһы $1 тарафынан булдырылды',
 'logentry-newusers-autocreate' => 'Автоматик рәүештә $1 иҫәп яҙыуы яһалды',
-'newuserlog-byemail' => 'пароль электрон почта адресы аша ебәрелде',
 'logentry-rights-rights' => '$1 $3 ҡулланыусыһының төркөмдәрҙәге ағзалығын $4 икән, $5 тип үҙгәртте',
 'logentry-rights-rights-legacy' => '$1 $3 ҡулланыусыһының төркөм ағзалығын үҙгәртте',
 'logentry-rights-autopromote' => '$1 автоматик рәүештә $2 икән, $3 ителде.',
index db8921a..3132f72 100644 (file)
 
 $fallback = 'de';
 
+$namespaceNames = array(
+       NS_MEDIA            => 'Media',
+       NS_SPECIAL          => 'Spezial',
+       NS_TALK             => 'Dischkrian',
+       NS_USER             => 'Nutza',
+       NS_USER_TALK        => 'Nutza_Dischkrian',
+       NS_PROJECT_TALK     => '$1_Dischkrian',
+       NS_FILE             => 'Datei',
+       NS_FILE_TALK        => 'Datei_Dischkrian',
+       NS_MEDIAWIKI        => 'MediaWiki',
+       NS_MEDIAWIKI_TALK   => 'MediaWiki_Dischkrian',
+       NS_TEMPLATE         => 'Vorlog',
+       NS_TEMPLATE_TALK    => 'Vorlog_Dischkrian',
+       NS_HELP             => 'Huif',
+       NS_HELP_TALK        => 'Huif_Dischkrian',
+       NS_CATEGORY         => 'Kategorie',
+       NS_CATEGORY_TALK    => 'Kategorie_Dischkrian',
+);
+
+$namespaceAliases = array(
+       # German namespaces
+       'Medium'               => NS_MEDIA,
+       'Diskussion'           => NS_TALK,
+       'Benutzer'             => NS_USER,
+       'Benutzer_Diskussion'  => NS_USER_TALK,
+       '$1_Diskussion'        => NS_PROJECT_TALK,
+       'Datei_Diskussion'     => NS_FILE_TALK,
+       'MediaWiki_Diskussion' => NS_MEDIAWIKI_TALK,
+       'Vorlage'              => NS_TEMPLATE,
+       'Vorlage_Diskussion'   => NS_TEMPLATE_TALK,
+       'Hilfe'                => NS_HELP,
+       'Hilfe_Diskussion'     => NS_HELP_TALK,
+       'Kategorie_Diskussion' => NS_CATEGORY_TALK,
+);
+
 $messages = array(
 # User preference toggles
 'tog-underline' => 'Links unterstreichen:',
index e99e889..274b1da 100644 (file)
@@ -3122,7 +3122,6 @@ $5
 # New logging system
 'revdelete-restricted' => 'محدودیت آن په مدیران سیستم بوت',
 'revdelete-unrestricted' => 'به زور چه مدیران سیستم محدودیتان',
-'newuserlog-byemail' => 'کلمه رمز گون ایمیل دیم دهگ بوت',
 'rightsnone' => '(هچ یک)',
 
 );
index 9f52508..ad1147b 100644 (file)
@@ -3762,7 +3762,6 @@ Ining sityo igwang naeksperiyensiyahan na mga kakundian sa teknikal.',
 'logentry-newusers-create' => 'An paragamit na panindog $1 pinagmukna na',
 'logentry-newusers-create2' => 'An paragamit na panindog $3 pinagmukna na ni $1',
 'logentry-newusers-autocreate' => 'An paragamit na panindog $1 awtomatikong pinagmukna na',
-'newuserlog-byemail' => 'an pasa-taramon ipinadara na sa paagi kan e-surat',
 'logentry-rights-rights' => '$1 nagliwat kan pangrupong pagkamiyembro para sa $3 gikan sa $4 pasiring sa $5',
 'logentry-rights-rights-legacy' => '$1 nagliwat kan pangrupong pagkamiyembro para sa $3',
 'logentry-rights-autopromote' => '$1 awtomatikong pinagpalangkaw gikan sa $4 pasiring sa $5',
index cf6dbb4..e910798 100644 (file)
@@ -32,8 +32,8 @@ $namespaceNames = array(
        NS_USER             => 'Удзельнік',
        NS_USER_TALK        => 'Размовы_з_удзельнікам',
        NS_PROJECT_TALK     => 'Размовы_пра_{{GRAMMAR:вінавальны|$1}}',
-       NS_FILE             => 'Ð\92Ñ\8bÑ\8fва',
-       NS_FILE_TALK        => 'Размовы_пра_выяву',
+       NS_FILE             => 'Файл',
+       NS_FILE_TALK        => 'Размовы_пра_файл',
        NS_MEDIAWIKI        => 'MediaWiki',
        NS_MEDIAWIKI_TALK   => 'Размовы_пра_MediaWiki',
        NS_TEMPLATE         => 'Шаблон',
@@ -46,6 +46,8 @@ $namespaceNames = array(
 
 $namespaceAliases = array(
        '$1_размовы' => NS_PROJECT_TALK,
+       'Выява' => NS_FILE,
+       'Размовы_пра_выяву' => NS_FILE_TALK,
 );
 
 $magicWords = array(
@@ -329,7 +331,7 @@ $1',
 'edithelp' => 'Даведка рэдактарскага акна',
 'edithelppage' => 'Help:Праўка',
 'helppage' => 'Help:Змест',
-'mainpage' => 'Ð\9fеÑ\80Ñ\88ая старонка',
+'mainpage' => 'Ð\93алоÑ\9eная старонка',
 'mainpage-description' => 'Першая старонка',
 'policy-url' => 'Project:Арганізацыйная палітыка',
 'portal' => 'Супольнасць',
@@ -3525,7 +3527,6 @@ MediaWiki распаўсюджваецца, спадзеючыся на прыд
 'logentry-newusers-create' => '$1 стварыў уліковы запіс удзельніка',
 'logentry-newusers-create2' => '$1 стварыў уліковы запіс удзельніка $3',
 'logentry-newusers-autocreate' => 'Аўтаматычна створаны ўліковы запіс $1',
-'newuserlog-byemail' => 'пароль адасланы эл.поштай',
 'rightsnone' => '(няма)',
 
 # Feedback
index c413039..5c69c17 100644 (file)
@@ -695,7 +695,7 @@ $2',
 'gotaccount' => "Ужо маеце рахунак? '''$1'''.",
 'gotaccountlink' => 'Увайдзіце',
 'userlogin-resetlink' => 'Забыліся пра зьвесткі для ўваходу?',
-'createaccountmail' => 'па Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\86е',
+'createaccountmail' => 'СÑ\82ваÑ\80Ñ\8bÑ\86Ñ\8c Ñ\87аÑ\81овÑ\8b Ð°Ð´Ð²Ð¾Ð»Ñ\8cнÑ\8b Ð¿Ð°Ñ\80олÑ\8c Ñ\96 Ð´Ð°Ñ\81лаÑ\86Ñ\8c Ñ\8fго Ð½Ð° e-mail Ð°Ð´Ñ\80аÑ\81, Ð¿Ð°Ð·Ð½Ð°Ñ\87анÑ\8b Ð½Ñ\96жÑ\8dй',
 'createaccountreason' => 'Прычына:',
 'badretype' => 'Уведзеныя Вамі паролі не супадаюць.',
 'userexists' => 'Уведзенае Вамі імя ўдзельніка ўжо выкарыстоўваецца кімсьці іншым. 
@@ -990,8 +990,8 @@ $2
 '''КАЛІ ЛАСКА, НЕ ЗЬМЯШЧАЙЦЕ ТУТ БЕЗ ДАЗВОЛУ МАТЭРЫЯЛЫ, ЯКІЯ АХОЎВАЮЦЦА АЎТАРСКІМ ПРАВАМ!'''",
 'longpageerror' => "'''Памылка: Аб’ём тэксту, які Вы спрабуеце запісаць складае $1 {{PLURAL:$1|кілябайт|кілябайты|кілябайтаў}}, што болей устаноўленага абмежаваньня на $2 {{PLURAL:$2|кілябайт|кілябайты|кілябайтаў}}.'''
 Старонка ня можа быць захаваная.",
-'readonlywarning' => "'''ПАПЯРЭДЖАНЬНЕ: База зьвестак была заблякаваная для тэхнічнага абслугоўваньня, таму немагчыма зараз захаваць Вашыя зьмены.
-Вы можаце скапіяваць тэкст у файл на Вашым кампутары, а пазьней захаваць сюды.'''
+'readonlywarning' => "'''ПАПЯРЭДЖАНЬНЕ: База зьвестак была заблякаваная для тэхнічнага абслугоўваньня, таму немагчыма зараз захаваць Вашыя зьмены.'''
+Вы можаце скапіяваць тэкст у файл на Вашым кампутары, а пазьней захаваць сюды.
 
 Адміністратар, які заблякаваў базу зьвестак, прапанаваў наступнае тлумачэньне: $1",
 'protectedpagewarning' => "'''Папярэджаньне: Гэтая старонка была абароненая, таму толькі адміністратары могуць рэдагаваць яе.'''
@@ -1066,7 +1066,7 @@ $2
 'undo-success' => 'Рэдагаваньне можа быць адмененае. Калі ласка, параўнайце адрозьненьні паміж вэрсіямі, каб упэўніцца, што гэта адпаведныя зьмены, а потым запішыце зьмены для сканчэньня рэдагаваньня.',
 'undo-failure' => 'Рэдагаваньне ня можа быць скасаванае праз канфлікт паміж папярэднімі рэдагаваньнямі.',
 'undo-norev' => 'Рэдагаваньне ня можа быць адмененае, таму што яно не існуе альбо было выдаленае.',
-'undo-summary' => 'Скасаваньне праўкі $1 удзельніка [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]])',
+'undo-summary' => 'Скасаваньне праўкі $1 {{GENDER:$2|удзельніка|удзельніцы}} [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]])',
 
 # Account creation failure
 'cantcreateaccounttitle' => 'Немагчыма стварыць рахунак',
@@ -1296,7 +1296,7 @@ $1",
 'search-interwiki-default' => 'вынікі з $1:',
 'search-interwiki-more' => '(яшчэ)',
 'search-relatedarticle' => 'Зьвязаны',
-'mwsuggest-disable' => 'Адключыць AJAX-падказкі',
+'mwsuggest-disable' => 'Адключыць пошукавыя падказкі',
 'searcheverything-enable' => 'Шукаць ва ўсіх прасторах назваў',
 'searchrelated' => 'зьвязаны',
 'searchall' => 'усе',
@@ -1322,7 +1322,7 @@ $1",
 'qbsettings-none' => 'Не паказваць',
 'qbsettings-fixedleft' => 'Замацаваная зьлева',
 'qbsettings-fixedright' => 'Замацаваная справа',
-'qbsettings-floatingleft' => 'РÑ\83Ñ\85омаÑ\8f зьлева',
+'qbsettings-floatingleft' => 'Ð\9fлавае зьлева',
 'qbsettings-floatingright' => 'Плавае справа',
 'qbsettings-directionality' => 'Замацаваная, у залежнасьці ад накірунку напісаньня ў Вашай мове',
 
@@ -1598,7 +1598,7 @@ $1",
 'action-userrights' => 'рэдагаваньне правоў усіх удзельнікаў',
 'action-userrights-interwiki' => 'рэдагаваньне правоў удзельнікаў у іншых вікі',
 'action-siteadmin' => 'блякаваньне і разблякаваньне базы зьвестак',
-'action-sendemail' => 'адпÑ\80аÑ\9eкÑ\83 Ñ\8dлекÑ\82Ñ\80оннÑ\8bÑ\85 Ð»Ñ\96Ñ\81Ñ\82оÑ\9e іншым удзельнікам',
+'action-sendemail' => 'адпÑ\80аÑ\9eлÑ\8fÑ\86Ñ\8c Ð»Ñ\96Ñ\81Ñ\82Ñ\8b іншым удзельнікам',
 
 # Recent changes
 'nchanges' => '$1 {{PLURAL:$1|зьмена|зьмены|зьменаў}}',
@@ -1710,10 +1710,8 @@ $1",
 'largefileserver' => 'Памер гэтага файла перавышае максымальна дазволены.',
 'emptyfile' => 'Загружаны файл, здаецца, пусты. Магчыма гэты адбылося з-за памылкі ў назьве файла.
 Удакладніце, ці Вы сапраўды жадаеце загрузіць гэты файл.',
-'windows-nonascii-filename' => '{{SITENAME}} не падтрымлівае назвы файлаў з спэцыяльнымі сымбалямі.',
-'fileexists' => 'Файл з такой назвай ужо існуе.
-Калі ласка, праверце <strong>[[:$1]]</strong>, калі Вы ня ўпэўненыя, што жадаеце яго замяніць.
-[[$1|thumb]]',
+'windows-nonascii-filename' => 'Гэтая вікі не падтрымлівае назвы файлаў з спэцыяльнымі сымбалямі.',
+'fileexists' => 'Файл з такой назвай ужо існуе. Калі ласка, праверце <strong>[[:$1]]</strong>, калі Вы ня ўпэўненыя, што жадаеце яго замяніць. [[$1|thumb]]',
 'filepageexists' => 'Старонка апісаньня для гэтага файла ўжо існуе як <strong>[[:$1]]</strong>, але файла з такой назвай няма.
 Апісаньне якое Вы дадалі ня зьявіцца на старонцы апісаньня.
 Каб яно там зьявілася, Вам трэба рэдагаваць яе самастойна.
@@ -2100,9 +2098,9 @@ $1',
 'listusers-editsonly' => 'Паказаць толькі ўдзельнікаў, якія маюць рэдагаваньні',
 'listusers-creationsort' => 'Адсартаваць па даце стварэньня',
 'usereditcount' => '$1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}}',
-'usercreated' => '{{GENDER:$3|}}Створаны $1 у $2',
+'usercreated' => '{{GENDER:$3|Створаны|Створаная}} $1 у $2',
 'newpages' => 'Новыя старонкі',
-'newpages-username' => 'Імя ўдзельніка/ўдзельніцы:',
+'newpages-username' => 'Імя ўдзельніка:',
 'ancientpages' => 'Найстарэйшыя старонкі',
 'move' => 'Перанесьці',
 'movethispage' => 'Перанесьці гэтую старонку',
@@ -2194,7 +2192,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Сьпіс актыўных удзельнікаў',
 'activeusers-intro' => 'Гэта сьпіс удзельнікаў, якія былі актыўнымі на працягу $1 {{PLURAL:$1|апошняга дня|апошніх дзён|апошніх дзён}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}} за $3 {{PLURAL:$3|апошні дзень|апошнія дні|апошніх дзён}}',
+'activeusers-count' => '$1 {{PLURAL:$1|дзеяньне|дзеяньні|дзеяньняў}} за $3 {{PLURAL:$3|апошні дзень|апошнія дні|апошніх дзён}}',
 'activeusers-from' => 'Паказваць ўдзельнікаў, пачынаючы з:',
 'activeusers-hidebots' => 'Схаваць робатаў',
 'activeusers-hidesysops' => 'Схаваць адміністратараў',
@@ -2250,14 +2248,14 @@ $1',
 'emailccsubject' => 'Копія Вашага ліста да $1: $2',
 'emailsent' => 'Ліст адасланы',
 'emailsenttext' => 'Ваш ліст быў адасланы.',
-'emailuserfooter' => 'Гэты ліст быў дасланы ўдзельнікам $1 да ўдзельніка $2 з дапамогай функцыі «Даслаць ліст» праекту {{SITENAME}}.',
+'emailuserfooter' => 'Гэты ліст быў дасланы ўдзельнікам $1 да {{GENDER:$2|ўдзельніка|ўдзельніцы}} $2 з дапамогай функцыі «Даслаць ліст» {{GRAMMAR:родны|{{SITENAME}}}}.',
 
 # User Messenger
 'usermessage-summary' => 'Паведамленьне пра выхад з сыстэмы.',
 'usermessage-editor' => 'Дастаўка сыстэмных паведамленьняў',
 
 # Watchlist
-'watchlist' => 'Ð\9cой Ñ\81ьпіс назіраньня',
+'watchlist' => 'Сьпіс назіраньня',
 'mywatchlist' => 'Сьпіс назіраньня',
 'watchlistfor2' => 'Для $1 $2',
 'nowatchlist' => 'Ваш сьпіс назіраньня пусты.',
@@ -3047,6 +3045,7 @@ $1',
 'pageinfo-robot-noindex' => 'Не індэксуецца',
 'pageinfo-views' => 'Колькасьць праглядаў',
 'pageinfo-watchers' => 'Колькасьць назіральнікаў і назіральніц',
+'pageinfo-few-watchers' => 'Менш за $1 {{PLURAL:$1|назіральніка|назіральнікаў}}',
 'pageinfo-redirects-name' => 'Перанакіраваньняў на гэтую старонку',
 'pageinfo-subpages-name' => 'Колькасьць падстаронак',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|перанакіраваньне|перанакіраваньні|перанакіраваньняў}}; $3 {{PLURAL:$3|звычайная|звычайныя|звычайных}})',
@@ -3834,7 +3833,7 @@ MediaWiki распаўсюджваецца з надзеяй, што будзе
 'specialpages-group-highuse' => 'Частаўжываныя старонкі',
 'specialpages-group-pages' => 'Сьпісы старонак',
 'specialpages-group-pagetools' => 'Інструмэнты для старонак',
-'specialpages-group-wiki' => 'Зьвесткі пра вікі і прылады',
+'specialpages-group-wiki' => 'Зьвесткі і прылады',
 'specialpages-group-redirects' => 'Спэцыяльныя старонкі-перанакіраваньні',
 'specialpages-group-spam' => 'Інструмэнты для барацьбы са спамам',
 
@@ -3903,7 +3902,7 @@ MediaWiki распаўсюджваецца з надзеяй, што будзе
 'sqlite-no-fts' => '$1 без падтрымкі поўнатэкстнага пошуку',
 
 # New logging system
-'logentry-delete-delete' => '$1 выдаліў старонку $3',
+'logentry-delete-delete' => '$1 {{GENDER:$2|выдаліў|выдаліла}} старонку $3',
 'logentry-delete-restore' => '$1 аднавіў старонку $3',
 'logentry-delete-event' => '$1 зьмяніў бачнасьць $5 {{PLURAL:$5|падзеі ў журнале|падзеяў у журнале|падзеяў у журнале}} на $3: $4',
 'logentry-delete-revision' => '$1 зьмяніў бачнасьць $5 {{PLURAL:$5|вэрсіі|вэрсіяў|вэрсіяў}} старонкі $3: $4',
@@ -3922,7 +3921,7 @@ MediaWiki распаўсюджваецца з надзеяй, што будзе
 'revdelete-uname-unhid' => 'імя ўдзельніка адкрытае',
 'revdelete-restricted' => 'ужыць абмежаваньні для адміністратараў',
 'revdelete-unrestricted' => 'зьнятыя абмежаваньні для адміністратараў',
-'logentry-move-move' => '$1 перанёс старонку $3 у $4',
+'logentry-move-move' => '$1 {{GENDER:$2|перанёс|перанесла}} старонку $3 у $4',
 'logentry-move-move-noredirect' => '$1 перанёс старонку $3 у $4 без пакінутага перанакіраваньня',
 'logentry-move-move_redir' => '$1 перанёс старонку $3 у $4 паўзьверх перанакіраваньня',
 'logentry-move-move_redir-noredirect' => '$1 перанёс старонку $3 у $4 паўзьверх перанакіраваньня без пакінутага перанакіраваньня',
@@ -3931,8 +3930,8 @@ MediaWiki распаўсюджваецца з надзеяй, што будзе
 'logentry-newusers-newusers' => 'Быў створаны рахунак $1',
 'logentry-newusers-create' => 'Быў створаны рахунак $1',
 'logentry-newusers-create2' => '$1 стварыў рахунак $3',
+'logentry-newusers-byemail' => '$1 {{GENDER:$2|стварыў|стварыла}} рахунак $3, пароль быў дасланы электроннай поштай',
 'logentry-newusers-autocreate' => 'Рахунак $1 быў створаны аўтаматычна',
-'newuserlog-byemail' => 'Пароль адасланы па электроннай пошце',
 'logentry-rights-rights' => '$1 {{GENDER:$1|зьмяніў|зьмяніла}} прыналежнасьць $3 да групы з $4 на $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|зьмяніў|зьмяніла}} прыналежнасьць $3 да групаў',
 'logentry-rights-autopromote' => '$1 {{GENDER:$1|быў аўтаматычна пераведзены|была аўтаматычна пераведзеная}} з групы $4 ў $5',
@@ -3990,6 +3989,7 @@ MediaWiki распаўсюджваецца з надзеяй, што будзе
 'api-error-ok-but-empty' => 'Унутраная памылка: няма адказу ад сэрвэра.',
 'api-error-overwrite' => 'Замена існуючага файла забароненая.',
 'api-error-stashfailed' => 'Унутраная памылка: сэрвэр ня змог захаваць часовы файл.',
+'api-error-publishfailed' => 'Унутраная памылка: сэрвэр ня змог захаваць часловы файл.',
 'api-error-timeout' => 'Сэрвэр не адказаў у чаканы тэрмін.',
 'api-error-unclassified' => 'Узьнікла невядомая памылка',
 'api-error-unknown-code' => 'Невядомая памылка: «$1».',
index e1ae315..7e76a2d 100644 (file)
@@ -613,9 +613,10 @@ $1',
 'protectedpagetext' => 'Тази страница е защитена, за да се предотвратят редактиране или други действия.',
 'viewsourcetext' => 'Можете да разгледате и да копирате кодa на страницата:',
 'viewyourtext' => "Можете да прегледате и копирате изходния код на '''вашите редакции''' на тази страница:",
-'protectedinterface' => 'Тази страница съдържа текст, нужен за работата на системата. Тя е защитена против редактиране, за да се предотвратят възможни злоупотреби.',
+'protectedinterface' => 'Тази страница съдържа текст, нужен за работата на системата. Тя е защитена против редактиране, за да се предотвратят възможни злоупотреби.
+За извършване на промяна за всички уикита, посетете [//translatewiki.net/ translatewiki.net], проектът за локализация на MediaWiki.',
 'editinginterface' => "'''Внимание:''' Редактирате страница, която се използва за интерфейса на софтуера. Промяната й ще повлияе на външния вид на уикито.
-За превеждане обмислете използването на [//translatewiki.net/wiki/Main_Page?setlang=bg translatewiki.net], проектът за локализиране на MediaWiki.",
+За превеждане, обмислете използването на [//translatewiki.net/ translatewiki.net], проектът за локализиране на MediaWiki.",
 'sqlhidden' => '(Заявка на SQL — скрита)',
 'cascadeprotected' => 'Тази страница е защитена против редактиране, защото е включена в {{PLURAL:$1|следната страница, която от своя страна има|следните страници, които от своя страна имат}} каскадна защита:
 $2',
@@ -625,9 +626,9 @@ $2',
 'ns-specialprotected' => 'Специалните страници не могат да бъдат редактирани.',
 'titleprotected' => "Тази страница е била защитена срещу създаване от [[User:$1|$1]].
 Посочената причина е ''$2''.",
-'filereadonlyerror' => "Файлът „$1“ не може да бъде променен, тъй като файловото хранилище „$2“ е в режим само за четене.
+'filereadonlyerror' => 'Файлът „$1“ не може да бъде променен, тъй като файловото хранилище „$2“ е в режим само за четене.
 
\94аденаÑ\82а Ð¿Ñ\80иÑ\87ина Ðµ â\80\9e''$3''â\80\9c.",
\90дминиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\8aÑ\82, ÐºÐ¾Ð¹Ñ\82о Ð³Ð¾ Ðµ Ð·Ð°ÐºÐ»Ñ\8eÑ\87ил, Ðµ Ð¿Ð¾Ñ\81оÑ\87ил Ñ\81леднаÑ\82а Ð¿Ñ\80иÑ\87ина: â\80\9e$3â\80\9c.',
 
 # Virus scanner
 'virus-badscanner' => "Лоша конфигурация: непознат скенер за вируси: ''$1''",
@@ -666,7 +667,7 @@ $2',
 'gotaccount' => "Имате ли вече сметка? '''$1'''.",
 'gotaccountlink' => 'Влизане',
 'userlogin-resetlink' => 'Забравени данни за влизане в системата?',
-'createaccountmail' => 'с писмо по електронната поща',
+'createaccountmail' => 'Използване на временна парола, която се изпраща по електронната поща, посочена по-долу',
 'createaccountreason' => 'Причина:',
 'badretype' => 'Въведените пароли не съвпадат.',
 'userexists' => 'Въведеното потребителско име вече се използва.
@@ -797,6 +798,7 @@ $2
 'changeemail-oldemail' => 'Текущ адрес за е-поща:',
 'changeemail-newemail' => 'Нов адрес за е-поща:',
 'changeemail-none' => '(няма)',
+'changeemail-password' => 'Парола за {{SITENAME}}:',
 'changeemail-submit' => 'Промяна на е-пощата',
 'changeemail-cancel' => 'Отказване',
 
@@ -913,8 +915,8 @@ $2
 'userinvalidcssjstitle' => "'''Внимание:''' Не съществува облик „$1“. Необходимо е да се знае, че имената на потребителските ви страници за CSS и Джаваскрипт трябва да се състоят от малки букви, например: „{{ns:user}}:Иван/vector.css“ (а не „{{ns:user}}:Иван/Vector.css“).",
 'updated' => '(обновена)',
 'note' => "'''Забележка:'''",
-'previewnote' => "'''Това е само предварителен преглед. Промените все още не са съхранени!'''",
-'continue-editing' => 'Ð\9fÑ\80одÑ\8aлжаване Ð½Ð° Ñ\80едакÑ\82иÑ\80анеÑ\82о',
+'previewnote' => "'''Ð\92ажно Ðµ Ð´Ð° Ñ\81е Ð¿Ð¾Ð¼Ð½Ð¸, Ñ\87е Ñ\82ова е само предварителен преглед. Промените все още не са съхранени!'''",
+'continue-editing' => 'Ð\9fÑ\80одÑ\8aлжаване ÐºÑ\8aм Ð¿Ð¾Ð»ÐµÑ\82о Ð·Ð° Ñ\80едакÑ\82иÑ\80ане',
 'previewconflict' => 'Този предварителен преглед отразява текста в горната текстова кутия така, както би се показал, ако съхраните.',
 'session_fail_preview' => "'''За съжаление редакцията ви не успя да бъде обработена поради загуба на данните за текущата сесия. Опитайте отново. Ако все още не работи, опитайте да [[Special:UserLogout|излезете]] и да влезете отново.'''",
 'session_fail_preview_html' => "'''За съжаление редакцията ви не беше записана поради изтичането на сесията ви.'''
@@ -953,7 +955,9 @@ $2
 <div style=\"font-variant:small-caps\">'''Не публикувайте произведения с авторски права без разрешение!'''</div>",
 'longpageerror' => "'''ГРЕШКА: Изпратеният текст е с големина {{PLURAL:$1|един килобайт|$1 килобайта}}, което надвишава позволения максимум от {{PLURAL:$2|един килобайт|$2 килобайта}}.'''
 Поради тази причина той не може да бъде съхранен.",
-'readonlywarning' => "'''ВНИМАНИЕ: Базата от данни беше затворена за поддръжка, затова в момента промените ви не могат да бъдат съхранени. Ако желаете, можете да съхраните страницата като текстов файл и да се опитате да я публикувате по-късно.'''
+'readonlywarning' => "'''ВНИМАНИЕ: Базата от данни беше затворена за поддръжка, затова в момента промените няма да могат да бъдат съхранени.'''
+
+Ако желаете, можете да съхраните страницата като текстов файл и да се опитате да я публикувате по-късно.
 
 Администраторът, който е затворил базата от данни, е посочил следната причина: $1",
 'protectedpagewarning' => "'''Внимание: Страницата е защитена и само потребители със статут на администратори могат да я редактират.'''
@@ -1152,6 +1156,7 @@ $1",
 'revdelete-reason-dropdown' => '* Стандартни причини за изтриване
 ** Нарушение на авторски права
 ** Неуместна лична информация
+** Неуместно потребителско име
 ** Потенциално клеветническа информация',
 'revdelete-otherreason' => 'Друга/допълнителна причина:',
 'revdelete-reasonotherlist' => 'Друга причина',
@@ -1355,7 +1360,7 @@ $1",
 'youremail' => 'Е-поща:',
 'username' => '{{GENDER:$1|Потребителско име}}:',
 'uid' => '{{GENDER:$1|Потребителски}} номер:',
-'prefs-memberingroups' => 'Член на {{PLURAL:$1|група|групи}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Член}} на {{PLURAL:$1|група|групи}}:',
 'prefs-registration' => 'Регистрация:',
 'yourrealname' => 'Истинско име:',
 'yourlanguage' => 'Език:',
@@ -1918,7 +1923,7 @@ $1',
 
 'disambiguations' => 'Страници, сочещи към пояснителни страници',
 'disambiguationspage' => 'Template:Пояснение',
-'disambiguations-text' => "Следните страници сочат към '''пояснителна страница''', вместо към истинската тематична страница.<br />Една страница се смята за пояснителна, ако ползва шаблон, към който се препраща от [[MediaWiki:Disambiguationspage]]",
+'disambiguations-text' => "Следните страници сочат към '''пояснителна страница''', вместо към истинската тематична страница.<br />Една страница се смята за пояснителна, ако ползва шаблон, към който се препраща от [[MediaWiki:Disambiguationspage]].",
 
 'doubleredirects' => 'Двойни пренасочвания',
 'doubleredirectstext' => 'Тази страница съдържа списък със страници, които пренасочват към друга пренасочваща страница.
@@ -2063,7 +2068,9 @@ $1',
 'linksearch-pat' => 'Търсене по:',
 'linksearch-ns' => 'Именно пространство:',
 'linksearch-ok' => 'Търсене',
-'linksearch-text' => 'Възможна е употребата на заместващи знаци като: „*.wikipedia.org“.<br />Поддържани протоколи: <code>$1</code>',
+'linksearch-text' => 'Възможна е употребата на заместващи знаци като: „*.wikipedia.org“.
+Необходим е поне домейн от най-високо ниво, например „*.org“.<br />
+{{PLURAL:$2|Поддържан протокол|Поддържани протоколи}}: <code>$1</code> (ако не е посочено, по подразбиране се използва http:// ).',
 'linksearch-line' => '$1 с препратка от $2',
 'linksearch-error' => 'Заместващите знаци могат да стоят само в началото на името на хоста.',
 
@@ -2272,6 +2279,7 @@ $UNWATCHURL
 'prot_1movedto2' => '„[[$1]]“ преместена като „[[$2]]“',
 'protect-badnamespace-title' => 'Незащитимо именно пространство',
 'protect-badnamespace-text' => 'Страниците в това именно пространство не могат да бъдат защитени.',
+'protect-norestrictiontypes-title' => 'Незащитима страница',
 'protect-legend' => 'Потвърждение на защитата',
 'protectcomment' => 'Причина:',
 'protectexpiry' => 'Изтича на:',
@@ -2285,8 +2293,8 @@ $UNWATCHURL
 'protect-cascadeon' => 'Тази страница е защитена против редактиране, защото е включена в {{PLURAL:$1|следната страница, която от своя страна има|следните страници, които от своя страна имат}} каскадна защита. Можете да промените нивото на защита на страницата, но това няма да повлияе върху каскадната защита.',
 'protect-default' => 'Позволяване за всички потребители',
 'protect-fallback' => 'Позволяване само за потребители с права на „$1“',
-'protect-level-autoconfirmed' => 'Ð\91локиÑ\80ане Ð½Ð° Ð½Ð¾Ð²Ð¸ Ð¸ Ð½ÐµÑ\80егиÑ\81Ñ\82Ñ\80иÑ\80ани потребители',
-'protect-level-sysop' => 'Само за администратори',
+'protect-level-autoconfirmed' => 'Ð\9fозволено Ñ\81амо Ð·Ð° Ð°Ð²Ñ\82омаÑ\82иÑ\87но Ð¾Ð´Ð¾Ð±Ñ\80ени потребители',
+'protect-level-sysop' => 'Ð\9fозволено Ñ\81амо за администратори',
 'protect-summary-cascade' => 'каскадно',
 'protect-expiring' => 'изтича на $1 (UTC)',
 'protect-expiring-local' => 'срок на изтичане $1',
@@ -2423,7 +2431,7 @@ $1',
 'whatlinkshere-hideredirs' => '$1 на пренасочващи страници',
 'whatlinkshere-hidetrans' => '$1 на включени страници',
 'whatlinkshere-hidelinks' => '$1 на препратки',
-'whatlinkshere-hideimages' => '$1 препратки към файла',
+'whatlinkshere-hideimages' => '$1 Ð½Ð° Ð¿Ñ\80епÑ\80аÑ\82ки ÐºÑ\8aм Ñ\84айла',
 'whatlinkshere-filters' => 'Филтри',
 
 # Block/unblock
@@ -2576,11 +2584,11 @@ $1',
 # Move page
 'move-page' => 'Преместване на $1',
 'move-page-legend' => 'Преместване на страница',
-'movepagetext' => "Ð\9fоÑ\81Ñ\80едÑ\81Ñ\82вом Ð´Ð¾Ð»Ð½Ð¸Ñ\8f Ñ\84оÑ\80мÑ\83лÑ\8fÑ\80 Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а, Ð¿Ñ\80емеÑ\81Ñ\82вайки Ñ\86Ñ\8fлаÑ\82а Ð¹ история на новото име. Старото заглавие ще се превърне в пренасочваща страница.
\9fÑ\80епÑ\80аÑ\82киÑ\82е ÐºÑ\8aм Ñ\81Ñ\82аÑ\80аÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а Ð½Ñ\8fма Ð´Ð° Ð±Ñ\8aдаÑ\82 Ð¿Ñ\80оменени; Ð·Ð°Ñ\82ова Ð¿Ñ\80овеÑ\80еÑ\82е Ð·Ð° Ð´Ð²Ð¾Ð¹Ð½Ð¸ Ð¸Ð»Ð¸ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð¸ Ð¿Ñ\80енаÑ\81оÑ\87ваниÑ\8f.
-Вие сами би трябвало да се убедите в това, дали препратките продължават да сочат там, където се предполага.
+'movepagetext' => "Ð\98зползванеÑ\82о Ð½Ð° Ñ\84оÑ\80мÑ\83лÑ\8fÑ\80а Ð¿Ð¾-долÑ\83 Ñ\89е Ð¿Ñ\80еименÑ\83ва Ñ\81Ñ\82Ñ\80аниÑ\86а, ÐºÐ°Ñ\82о Ñ\81е Ð¿Ñ\80емеÑ\81Ñ\82и Ñ\86Ñ\8fлаÑ\82а Ñ\9d Ñ\80едакÑ\86ионна Ð¸Ñ\81Ñ\82оÑ\80иÑ\8f история на новото име. Старото заглавие ще се превърне в пренасочваща страница.
\9cоже Ð´Ð° Ñ\81е Ð¸Ð·Ð±ÐµÑ\80е Ð²Ñ\8aзможноÑ\81Ñ\82 Ð¿Ñ\80енаÑ\81оÑ\87ваниÑ\8fÑ\82а ÐºÑ\8aм Ð¾Ñ\80игиналноÑ\82о Ð·Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ Ð´Ð° Ð±Ñ\8aдаÑ\82 Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð¸ Ð°Ð²Ñ\82омаÑ\82иÑ\87но. Ð\92 Ñ\81лÑ\83Ñ\87ай, Ñ\87е Ñ\82ази Ð²Ñ\8aзможноÑ\81Ñ\82 Ð½Ðµ Ðµ Ð¸Ð·Ð±Ñ\80ана, Ð¿Ñ\80епоÑ\80Ñ\8aÑ\87иÑ\82елно Ðµ Ð´Ð° Ñ\81е Ð¿Ñ\80овеÑ\80и Ð·Ð° [[Special:DoubleRedirects|двойни]] Ð¸Ð»Ð¸ [[Special:BrokenRedirects|невалидни Ð¿Ñ\80енаÑ\81оÑ\87ваниÑ\8f]].
+Вие сами би трябвало да се убедите в това дали препратките продължават да сочат там, където се предполага.
 
¡траницата '''няма''' да бъде преместена, ако вече съществува страница с новото име, освен ако е празна или пренасочване и няма редакционна история.
\9eбÑ\8aÑ\80неÑ\82е Ð²Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ, Ñ\87е Ñ\81траницата '''няма''' да бъде преместена, ако вече съществува страница с новото име, освен ако е празна или пренасочване и няма редакционна история.
 
 '''ВНИМАНИЕ!'''
 Това може да е голяма и неочаквана промяна за известна страница. Уверете се, че разбирате последствията, преди да продължите.",
@@ -2705,6 +2713,7 @@ $1',
 'thumbnail_error' => 'Грешка при създаване на миникартинка: $1',
 'djvu_page_error' => 'Номерът на DjVu-страницата е извън обхвата',
 'djvu_no_xml' => 'Не е възможно вземането на XML за DjVu-файла',
+'thumbnail-temp-create' => 'Временния файл с миникартинка не може да бъде създаден.',
 'thumbnail_invalid_params' => 'Параметрите за миникартинка са невалидни',
 'thumbnail_dest_directory' => 'Целевата директория не може да бъде създадена',
 'thumbnail_image-type' => 'Типът картинка не се поддържа',
@@ -2722,6 +2731,7 @@ $1',
 'import-interwiki-templates' => 'Включване на всички шаблони',
 'import-interwiki-submit' => 'Внасяне',
 'import-interwiki-namespace' => 'Целево именно пространство:',
+'import-interwiki-rootpage' => 'Целева основна страница (незадължително):',
 'import-upload-filename' => 'Име на файл:',
 'import-comment' => 'Коментар:',
 'importtext' => 'Изнесете файла от изходното уики чрез „[[Special:Export|инструмента за изнасяне]]“. Съхранете го на твърдия диск на компютъра си и го качете тук.',
@@ -2766,6 +2776,7 @@ $1',
 
 # JavaScriptTest
 'javascripttest-pagetext-noframework' => 'Тази страница е запазена за изпълнение на Джаваскрипт тестове.',
+'javascripttest-pagetext-skins' => 'Избор на облик за тестванията:',
 'javascripttest-qunit-intro' => 'Вижте [$1 тестовата документация] на mediawiki.org.',
 
 # Tooltip help for the actions
@@ -2877,8 +2888,10 @@ $1',
 'pageinfo-article-id' => 'Номер на страницата',
 'pageinfo-views' => 'Брой прегледи',
 'pageinfo-watchers' => 'Брой наблюдаващи страницата',
+'pageinfo-few-watchers' => 'Под $1 {{PLURAL:$1|наблюдаващ|наблюдаващи}}',
 'pageinfo-redirects-name' => 'Пренасочвания към тази страница',
 'pageinfo-subpages-name' => 'Подстраници на тази страница',
+'pageinfo-firsttime' => 'Дата на създаване на страницата',
 'pageinfo-lastuser' => 'Последeн редактор',
 'pageinfo-lasttime' => 'Дата на последнoто редактиране',
 'pageinfo-edits' => 'Общ брой редакции',
@@ -2887,6 +2900,9 @@ $1',
 'pageinfo-toolboxlink' => 'Информация за страницата',
 'pageinfo-contentpage-yes' => 'Да',
 'pageinfo-protect-cascading-yes' => 'Да',
+'pageinfo-category-pages' => 'Брой страници',
+'pageinfo-category-subcats' => 'Брой подкатегории',
+'pageinfo-category-files' => 'Брой файлове',
 
 # Skin names
 'skinname-standard' => 'Класика',
@@ -2950,6 +2966,8 @@ $1',
 'file-info-png-looped' => 'зациклен',
 'file-info-png-repeat' => 'изпълнено $1 {{PLURAL:$1|път|пъти}}',
 'file-info-png-frames' => '$1 {{PLURAL:$1|кадър|кадъра}}',
+'file-no-thumb-animation' => "'''Забележка: По технически причини миниатюрите на този файл няма да бъдат анимирани.'''",
+'file-no-thumb-animation-gif' => "'''Забележка: По технически причини миниатюрите на GIF файловете с висока резолюция като този няма да бъдат анимирани.'''",
 
 # Special:NewFiles
 'newimages' => 'Галерия на новите файлове',
@@ -2968,7 +2986,10 @@ $1',
 'minutes' => '{{PLURAL:$1|$1 минута|$1 минути}}',
 'hours' => '{{PLURAL:$1|$1 час|$1 часа}}',
 'days' => '{{PLURAL:$1|$1 ден|$1 дни}}',
+'months' => '{{PLURAL:$1|един месец|$1 месеца}}',
+'years' => '{{PLURAL:$1|една година|$1 години}}',
 'ago' => 'преди $1',
+'just-now' => 'току що',
 
 # Bad image list
 'bad_image_list' => 'Спазва се следният формат:
@@ -3110,8 +3131,14 @@ $1',
 'exif-gpsdifferential' => 'Диференциална корекция на GPS',
 'exif-jpegfilecomment' => 'Kоментар на JPEG файл',
 'exif-keywords' => 'Ключови думи',
+'exif-worldregioncreated' => 'Регион на света, където е направена снимката',
+'exif-countrycreated' => 'Държава, в която е направена снимката',
+'exif-countrycodecreated' => 'Код на държавата, където е направена снимката',
+'exif-provinceorstatecreated' => 'Област или щат, където е направена снимката',
+'exif-citycreated' => 'Град, в който е направена снимката',
 'exif-objectname' => 'Кратко заглавие',
 'exif-specialinstructions' => 'Специални инструкции',
+'exif-source' => 'Източник',
 'exif-contact' => 'Информация за контакти',
 'exif-languagecode' => 'Език',
 'exif-iimversion' => 'IIM версия',
@@ -3554,14 +3581,14 @@ MediaWiki се разпространява с надеждата, че ще б
 * <span class="mw-specialpagecached">Само складирани специални страници (възможно е да са остарели).</span>',
 'specialpages-group-maintenance' => 'Доклади по поддръжката',
 'specialpages-group-other' => 'Други специални страници',
-'specialpages-group-login' => 'Ð\92лизане / Ñ\80егиÑ\81Ñ\82Ñ\80иÑ\80ане',
+'specialpages-group-login' => 'Ð\92лизане / Ñ\81Ñ\8aздаване Ð½Ð° Ñ\81меÑ\82ка',
 'specialpages-group-changes' => 'Последни промени и дневници',
 'specialpages-group-media' => 'Доклади за файловете и качванията',
 'specialpages-group-users' => 'Потребители и права',
 'specialpages-group-highuse' => 'Широко използвани страници',
 'specialpages-group-pages' => 'Списъци на страниците',
 'specialpages-group-pagetools' => 'Инструменти за страниците',
-'specialpages-group-wiki' => 'Уики Ð´анни и инструменти',
+'specialpages-group-wiki' => 'Ð\94анни и инструменти',
 'specialpages-group-redirects' => 'Пренасочващи специални страници',
 'specialpages-group-spam' => 'Инструменти против спам',
 
@@ -3648,8 +3675,10 @@ MediaWiki се разпространява с надеждата, че ще б
 'logentry-newusers-newusers' => 'Потребителската сметка $1 беше създадена',
 'logentry-newusers-create' => 'Потребителската сметка $1 беше създадена',
 'logentry-newusers-create2' => '$1 създаде потребителска сметка $3',
+'logentry-newusers-byemail' => '$1 създаде потребителската сметка $3, паролата беше изпратена по електронна поща',
 'logentry-newusers-autocreate' => 'Сметката $1 беше създадена автоматично',
-'newuserlog-byemail' => 'паролата е изпратена по е-поща',
+'logentry-rights-rights' => '$1 промени потребителската група на $3 от $4 на $5',
+'logentry-rights-rights-legacy' => '$1 промени потребителската група на $3',
 'logentry-rights-autopromote' => '
 $1 е автоматично повишен от $4 до $5',
 'rightsnone' => '(никакви)',
@@ -3701,6 +3730,7 @@ $1 е автоматично повишен от $4 до $5',
 'api-error-ok-but-empty' => 'Вътрешна грешка: Няма отговор от сървъра.',
 'api-error-overwrite' => 'Не е позволено презаписването върху съществуващ файл.',
 'api-error-stashfailed' => 'Вътрешна грешка: Сървърът не успя да съхрани временния файл.',
+'api-error-publishfailed' => 'Вътрешна грешка: Сървърът не успя да съхрани временния файл.',
 'api-error-timeout' => 'Сървърът не отговори в рамките на предвиденото време.',
 'api-error-unclassified' => 'Възникна непозната грешка.',
 'api-error-unknown-code' => 'Непозната грешка: "$1"',
index e005efe..1ec602b 100644 (file)
 
 $fallback = 'bho';
 
-$messages = array(
-# User preference toggles
-'tog-underline' => 'लिंक के नीचे रेखा',
-'tog-justify' => 'पैराग्राफ जस्टीफाई',
-'tog-hideminor' => 'हाल के परिवर्तन में मामूली संपादन छुपाईं',
-'tog-numberheadings' => 'स्वयं-सांख्यिकी शिर्षक',
-'tog-rememberpassword' => 'इ ब्राउजर पर हमार प्रवेश जारी रहे (अधिकतम $1 {{PLURAL:$1|दिन|दिन}})',
-'tog-previewonfirst' => 'पहिलका सम्पादन पर पूर्वावलोकन देखीं',
-
-'underline-always' => 'हमेशा',
-'underline-never' => 'कभी ना',
-'underline-default' => 'डिफॉल्ट ब्राउजर',
-
-# Dates
-'sunday' => 'इतवार',
-'monday' => 'सोमवार',
-'tuesday' => 'मंगलवार',
-'wednesday' => 'बुधवार',
-'thursday' => 'गुरुवार',
-'friday' => 'शुक्रवार',
-'saturday' => 'शनिवार',
-'sun' => 'इत',
-'mon' => 'सोम',
-'tue' => 'मंगल',
-'wed' => 'बुध',
-'thu' => 'गुरु',
-'fri' => 'शुक्र',
-'sat' => 'शनि',
-'january' => 'जनवरी',
-'february' => 'फरवरी',
-'march' => 'मार्च',
-'april' => 'अप्रिल',
-'may_long' => 'मई',
-'june' => 'जून',
-'july' => 'जुलाई',
-'august' => 'अगस्त',
-'september' => 'सितम्बर',
-'october' => 'अक्टूबर',
-'november' => 'नवम्बर',
-'december' => 'दिसम्बर',
-'january-gen' => 'जनवरी',
-'february-gen' => 'फरवरी',
-'march-gen' => 'मार्च',
-'april-gen' => 'अप्रिल',
-'may-gen' => 'मई',
-'june-gen' => 'जून',
-'july-gen' => 'जुलाई',
-'august-gen' => 'अगस्त',
-'september-gen' => 'सितम्बर',
-'october-gen' => 'अक्टूबर',
-'november-gen' => 'नवम्बर',
-'december-gen' => 'दिसम्बर',
-'jan' => 'जन',
-'feb' => 'फर',
-'mar' => 'मार्च',
-'apr' => 'अप्रिल',
-'may' => 'मई',
-'jun' => 'जून',
-'jul' => 'जुल',
-'aug' => 'अग',
-'sep' => 'सित',
-'oct' => 'अक्टू',
-'nov' => 'नव',
-'dec' => 'दिस',
-
-# Categories related messages
-'pagecategories' => '{{PLURAL:$1|श्रेणी|श्रेणी}}',
-
-'about' => 'बारे में',
-'article' => 'सामग्री पन्ना',
-'newwindow' => '(नया विंडो में खोलीं)',
-'cancel' => 'निरस्त',
-'mytalk' => 'हमार बात',
-'navigation' => 'परिभ्रमण',
-
-# Cologne Blue skin
-'qbfind' => 'खोज',
-'qbbrowse' => 'ब्राउज',
-'qbedit' => 'सम्पादन',
-'qbpageoptions' => 'ई पन्ना',
-'qbmyoptions' => 'हमार पन्ना',
-'qbspecialpages' => 'विशेष पन्ना',
-'faq' => 'साधारण सवाल',
-'faqpage' => 'Project:साधारण सवाल',
-
-# Vector skin
-'vector-action-delete' => 'मिटाईं',
-'vector-action-move' => 'स्थांतरण',
-'vector-action-protect' => 'संरक्षित करीं',
-'vector-action-undelete' => 'मत मिटाईं',
-'vector-action-unprotect' => 'असुरक्षित करीं',
-'vector-view-create' => 'बनाईं',
-'vector-view-edit' => 'सम्पादन',
-'vector-view-history' => 'इतिहास देखीं',
-'vector-view-view' => 'पढ़ीं',
-'vector-view-viewsource' => 'स्त्रोत देखीं',
-
-'errorpagetitle' => 'त्रुटी',
-'returnto' => 'जाईं $1 पर।',
-'tagline' => 'भोजपुरी {{SITENAME}} से',
-'help' => 'मदद',
-'search' => 'खोज',
-'searchbutton' => 'खोजीं',
-'go' => 'जाईं',
-'searcharticle' => 'जाईं',
-'history' => 'पन्ना के इतिहास',
-'history_short' => 'इतिहास',
-'updatedmarker' => 'हमार अन्तिम आगमन से बदलाव',
-'printableversion' => 'छापे लायक संस्करण',
-'permalink' => 'स्थायी लिंक',
-'print' => 'छापीं',
-'edit' => 'सम्पादन',
-'create' => 'बनाईं',
-'editthispage' => 'ई पन्ना के सम्पादन करीं',
-'create-this-page' => 'ई पन्ना के निर्माण करीं',
-'delete' => 'मिटाईं',
-'deletethispage' => 'ई पन्ना के मिटाईं',
-'protect' => 'संरक्षण करीं',
-'protect_change' => 'बदलीं',
-'protectthispage' => 'इ पन्ना के सुरक्षित करीं।',
-'unprotect' => 'असुरक्षित करीं',
-'unprotectthispage' => 'इ पन्ना के असुरक्षित करीं',
-'newpage' => 'नया पन्ना',
-'talkpage' => 'इ पन्ना पर चर्चा करीं',
-'talkpagelinktext' => 'बात-चीत',
-'specialpage' => 'ख़ाश पन्ना',
-'personaltools' => 'ब्यक्तिगत औजार',
-'postcomment' => 'नया खण्ड',
-'articlepage' => 'सामग्री पन्ना देखीं',
-'talk' => 'बात-चीत',
-'views' => 'विचारसूची',
-'toolbox' => 'औजार-पेटी',
-'userpage' => 'प्रयोगकर्ता पन्ना देखीं',
-'projectpage' => 'परियोजना पन्ना देखीं',
-'imagepage' => 'फाईल पन्ना देखीँ',
-'mediawikipage' => 'सन्देश पन्ना देखीं',
-'templatepage' => 'टेम्पलेट पन्ना देखीं',
-'viewhelppage' => 'मदद पन्ना देखीं',
-'categorypage' => 'श्रेणी पन्ना देखीं',
-'viewtalkpage' => 'बात-चीत देखीं',
-'otherlanguages' => 'अन्य भाषा में',
-'redirectedfrom' => '($1 द्वारा पुन: निर्देशित)',
-'redirectpagesub' => 'पुन: निर्देशित पन्ना',
-'lastmodifiedat' => '$1 के $2 पर ई पन्ना पर अन्तिम बार परिवर्तन भईल।',
-'protectedpage' => 'सुरक्षित पन्ना',
-'jumpto' => 'अहिजा जाईं:',
-'jumptonavigation' => 'परिभ्रमण',
-'jumptosearch' => 'खोजीं',
-'view-pool-error' => 'क्षमा करीं, ई समय सर्वर पर बहुत ज्यादा लोड बढ़ गईल बा।
-ई पन्ना के बहुते प्रयोगकर्ता लोग देखे के कोशिश कर रहल बानी।
-ई पन्ना के फिर से देखे से पहिले कृपया कुछ देर तक इन्तजार करीं।
-
-$1',
-
-# All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
-'aboutsite' => '{{SITENAME}} के बारे में',
-'aboutpage' => 'Project:बारे में',
-'copyright' => 'सामग्री $1 के तहत उपलब्ध बा।',
-'copyrightpage' => '{{ns:project}}:लेखाधिकार',
-'currentevents' => 'हाल के घटना',
-'currentevents-url' => 'Project:हाल के घटना',
-'disclaimers' => 'अस्विकरण',
-'disclaimerpage' => 'Project:सामान्य अस्विकरण',
-'edithelp' => 'मदद सम्पादन',
-'edithelppage' => 'Help:सम्पादन',
-'mainpage' => 'मुख्य पन्ना',
-'mainpage-description' => 'पहिलका पन्ना',
-'portal' => 'सामुदायिक पन्ना',
-'portal-url' => 'Project:सामुदायिक पोर्टल',
-'privacy' => 'गोपनीयता नीति',
-'privacypage' => 'Project:गोपनीयता नीति',
-
-'badaccess' => 'अनुमति त्रुटी',
-'badaccess-group0' => 'रउआ जवन कार्रवाई खातिर अनुरोध कईले बानी उ के निष्पादन करे के अनुमति नईखे।',
-
-'ok' => 'ठिक',
-'retrievedfrom' => '"$1" से लियल गईल',
-'youhavenewmessages' => 'रउआ लगे बा $1 ($2).',
-'newmessageslink' => 'नया सन्देश',
-'newmessagesdifflink' => 'अन्तिम परिवर्तन',
-'youhavenewmessagesmulti' => 'रउआ लगे $1 पर नया सन्देश बा',
-'editsection' => 'सम्पादन',
-'editold' => 'सम्पादन',
-'viewsourceold' => 'स्त्रोत देखीं',
-'editlink' => 'सम्पादन',
-'viewsourcelink' => 'स्त्रोत देखीं',
-'editsectionhint' => 'सम्पादन खण्ड: $1',
-'toc' => 'सामग्री',
-'showtoc' => 'देखाईं',
-'hidetoc' => 'छुपाईं',
-'thisisdeleted' => 'देखीं या भंडार करीं $1?',
-'viewdeleted' => '$1 देखब?',
-'site-rss-feed' => '$1 आर एस एस फिड',
-'site-atom-feed' => '$1 एटम फिड',
-'page-rss-feed' => '"$1" आर एस एस फिड',
-'page-atom-feed' => '"$1" एटम फिड',
-'red-link-title' => '$1 (पन्ना मौजूद नईखे)।',
-
-# Short words for each namespace, by default used in the namespace tab in monobook
-'nstab-main' => 'पन्ना',
-'nstab-user' => 'प्रयोगकर्ता पन्ना',
-'nstab-media' => 'मिडीया पन्ना',
-'nstab-special' => 'विशेष पन्ना',
-'nstab-project' => 'परियोजना पन्ना',
-'nstab-image' => 'फाईल',
-'nstab-mediawiki' => 'सन्देश',
-'nstab-template' => 'टेम्पलेट',
-'nstab-help' => 'मदद पन्ना',
-'nstab-category' => 'श्रेणी',
-
-# Main script and global functions
-'nosuchaction' => 'अईसन कौनो कार्रवाई नाहि',
-'nosuchspecialpage' => 'अईसन कौनो ख़ाश पन्ना नाहि',
-'nospecialpagetext' => '<strong>रउआ एगो अवैद्य विशेष पन्ना के अनुरोध कईले बानी।</strong>
-
-वैद्य विशेष पन्ना के सूची मिल सकत बा [[Special:SpecialPages|{{int:specialpages}}]] पर।',
-
-# General errors
-'error' => 'त्रुटी',
-'databaseerror' => 'डेटाबेस त्रुटी',
-'readonly' => 'डेटाबेस लॉक बा',
-'missing-article' => 'डेटाबास ऊ पन्ना के पाठ्य के ना खोज पाईल जौन ई के खोजे के रहल, नामित "$1" $2.
-ई सब साधारणत: निम्नलिखीत अप्रचलित अन्तर अथवा एगो पन्ना पर इतिहास के लिंक जौन मिटा दिहल गईल बा के कारण भईल।
-
-यदि ई बात नईखे, त हो सकत बा सॉफ्टवेयर में बग पावत होखब।
-कृपया ई एगो  [[Special:ListUsers/sysop|प्रबन्धक]] के यू आर एल के बारे में एगो नोट बनाके खबर करीं।',
-'viewsource' => 'स्त्रोत देखीं',
-
-# Login and logout pages
-'yourname' => 'प्रयोगकर्ता नाम',
-'yourpassword' => 'गुप्त शब्द',
-'yourpasswordagain' => 'गुप्त-शब्द पुन:डालीं:',
-'login' => 'खाता में प्रवेश',
-'nav-login-createaccount' => 'खाता प्रवेश / खाता बनाईं',
-'loginprompt' => '{{SITENAME}} में प्रवेश खातिर राउर कुकिज चालू होवे के चाहीं',
-'userlogin' => 'खाता प्रवेश / खाता बनाईं',
-'userloginnocreate' => 'खाता में प्रवेश',
-'logout' => 'खाता से बाहर',
-'userlogout' => 'खाता से बाहर',
-'notloggedin' => 'खाता में प्रवेश नईखीं भईल',
-'nologin' => 'का एगो खाता नईखे? $1.',
-'nologinlink' => 'एगो खाता बनाईं',
-'createaccount' => 'खाता बनाईं',
-'gotaccount' => 'का पहिले से एगो खाता बा? $1.',
-'gotaccountlink' => 'खाता में प्रवेश',
-'createaccountmail' => 'ई-मेल द्वारा',
-'badretype' => 'रउआ जौन गुप्त शब्द डालत बानी उ नईखे मेल खात।',
-'userexists' => 'ई प्रयोगकर्ता नाम पहिले से इस्तेमाल में बा। कृपया कौनो दोसर नाम चुनीं।',
-'loginerror' => 'खाता प्रवेश में त्रुटि',
-'createaccounterror' => 'ई खाता ना बन पाईल: $1',
-'nocookiesnew' => 'प्रयोगकर्ता खाता त बन गईल, बाँकी रउआ प्रवेश नईखीं भईल।
-{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकिज के प्रयोग करेला।
-राउर कुकिज असक्षम बा।
-कृपया उ के सक्षम करीं, उ के बाद राउर नया प्रयोगकर्ता नाम आ गुप्त शब्द के साथ प्रवेश करीं।',
-'nocookieslogin' => '{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकिज के प्रयोग करेला।
-राउर कुकिज असक्षम बा।
-कृपया उ के सक्षम करीं आ फिर से कोशिश करीं',
-'noname' => 'रउआ उपयुक्त प्रयोगकर्ता नाम नईखीं निर्दिष्ट कईले।',
-'loginsuccesstitle' => 'खाता प्रवेश में सफल',
-'loginsuccess' => "''' \"\$1\" के रुप में रउआ {{SITENAME}} में अब प्रवेश कर चुकल बानी।'''",
-'nosuchuser' => '"$1" नाम से कौनो प्रयोगकर्ता नईखन।
-प्रयोगकर्ता नाम संवेदनशील मामला बा।
-शब्द-वर्तनी के जाँच करीं, आ चाहे [[Special:UserLogin/signup|एगो नया खाता बनाईं]]।',
-'nouserspecified' => 'रउआ एगो प्रयोगकर्ता नाम निर्दिष्ट करे के बा।',
-'login-userblocked' => 'ई प्रयोगकर्ता के खाता निष्क्रिय हो चुकल बा। प्रवेश के आज्ञा नईखे।',
-'wrongpassword' => 'गलत गुप्त-शब्द डलले बानी।
-कृपया फिर से कोशिश करीं।',
-'wrongpasswordempty' => 'गुप्त-शब्द खाली बा। कृपया फिर से कोशिश करीं।',
-'passwordtooshort' => 'गुप्त-शब्द कम से कम {{PLURAL:$1|1 अक्षर|$1 अक्षर}} के होवे के चाहीं।',
-'password-name-match' => 'राउर गुप्त-शब्द राउर प्रयोगकर्ता नाम से अलग होवे के चाहीं।',
-'mailmypassword' => 'नया गुप्त-शब्द ई-मेल पर भेजीं',
-'passwordremindertitle' => '{{SITENAME}} खातिर नया अस्थायी गुप्त-शब्द',
-
-# Change password dialog
-'resetpass' => 'गुप्त-शब्द बदलीं',
-'oldpassword' => 'पुराना गुप्त-शब्द:',
-'newpassword' => 'नया गुप्त-शब्द:',
-'retypenew' => 'नया गुप्त-शब्द पुन: डालीं:',
-
-# Edit page toolbar
-'bold_tip' => 'मोट पाठ्य',
-'italic_sample' => 'इटालिक पाठ्य',
-'italic_tip' => 'इटालिक पाठ्य',
-'headline_sample' => 'शिर्षक पाठ्य',
-'image_sample' => 'उदाहरण.jpg',
-'media_sample' => 'उदाहरण.ogg',
-'media_tip' => 'फाईल लिंक',
-'sig_tip' => 'timestamp के साथ राउर हस्ताक्षर',
-
-# Edit pages
-'summary' => 'सारांश:',
-'subject' => 'विषय/शिर्षक:',
-'minoredit' => 'छोट परिवर्तन',
-'watchthis' => 'ई पन्ना ध्यानसूची में डालीं',
-'savearticle' => 'पन्ना सुरक्षित करीं',
-'preview' => 'पूर्वावलोकन',
-'showpreview' => 'पूर्वावलोकन देखाईं',
-'showlivepreview' => 'सीधा पूर्वावलोकन',
-'showdiff' => 'परिवर्तन देखाईं',
-'anoneditwarning' => "'''चेतावनी:''' रउआ आपन खाता में प्रवेश नईखीं कईले। ई पन्ना के सम्पादन इतिहास पर राउर आई पी पता दर्ज कईल जाई।",
-'anonpreviewwarning' => "''रउआ खाता में प्रवेश नईखीं भईल। सुरक्षित करेब त ई पन्ना के सम्पादन इतिहास पर राउर आई पी पता दर्ज हो जाई।\"",
-'missingsummary' => "'''स्मरणपत्र:'''रउआ एगो सारांश के सम्पादन नईखीं प्रदान कईले। अगर रउआ \"फिर से सुरक्षित करीं\" पर क्लिक करेब, त राउर सम्पादन बिना एगो सारांश के सुरक्षित हो जाई।",
-'missingcommenttext' => 'कृपया निचे एगो टिप्पणी करीं।',
-'missingcommentheader' => "'''स्मरणपत्र:''' रउआ ई टिप्पणी खातिर कौनो विषय/शिर्षक प्रदान नईखीं कईले। \"{{int:savearticle}}\" यदि रउआ फिर से सुरक्षित करब त राउर सम्पादन बिना कौनो शिर्षक के सुरक्षित हो जाई।",
-'summary-preview' => 'सारांश पूर्वावलोकन:',
-'subject-preview' => 'विषय/शिर्षक पूर्वावलोकन:',
-'blockedtitle' => 'निष्क्रिय प्रयोगकर्ता',
-'blockednoreason' => 'कउनो कारण उल्लेखित नईखे',
-'nosuchsectiontitle' => 'खण्ड ना मिल सकल।',
-'loginreqtitle' => 'खाता में प्रवेश जरुरी बा',
-'loginreqlink' => 'खाता में प्रवेश',
-'accmailtitle' => 'गुप्त-शब्द भेजा गईल',
-'newarticle' => '(नया)',
-'newarticletext' => "रउआ एगो अइसन लिंक के पन्ना के अनुसरण कइले बानी जउन अभी तक उपलब्ध नइखे।
-पन्ना बनावे खातिर, नीचे के बाकस में टाईप करे के शुरु करीं (ज्यादा जानकारी खातिर देखीं [[{{MediaWiki:Helppage}}|मदद पन्ना]])।
-यदि रउआ अहिजा गलती से आ गईल बानी त, आपन ब्राउजर के '''back''' (बैक) बटन दबाईं",
-'yourdiff' => 'अंतर',
-'template-protected' => '(संरक्षित)',
-
-# History pages
-'revisionasof' => '$1 के रुप में संशोधन',
-'revision-info' => '$2 में से $1 के रुप में संशोधन',
-'previousrevision' => '← पुरान संशोधन',
-'nextrevision' => 'नया संशोधन →',
-'currentrevisionlink' => 'हाल के संशोधन',
-'cur' => 'हाल',
-'next' => 'अगिला',
-'last' => 'पछिला',
-'page_first' => 'पहिलका',
-'page_last' => 'आखिरी',
-'histlegend' => "चुनाव अन्तर: तुलना करे खातिर संशोधन के रेडियो बटन पर निशान लगाईं आ enter बटन दबाईं आ चाहे निचला बटन दबाईं।<br />
-Legend: '''({{int:cur}})''' = हाल के संशोधन के साथ अंतर, '''({{int:last}})''' = पुर्ववर्ती संशोधन के साथ अंतर, '''{{int:minoreditletter}}''' = छोट सम्पादन।",
-'history-fieldset-title' => 'इतिहास निहारीं',
-'history-show-deleted' => 'खाली मेटावल',
-'histfirst' => 'बहुत पहिले के',
-'histlast' => 'हाल के',
-'historysize' => '({{PLURAL:$1|1 बाइट|$1 बाइट}})',
-'historyempty' => '(खाली)',
-
-# Revision feed
-'history-feed-title' => 'संशोधन इतिहास',
-'history-feed-description' => 'विकि पर इ पन्ना के संशोधन के इतिहास',
-'history-feed-item-nocomment' => '$1 $2 पर',
-'history-feed-empty' => 'अनुरोध करल गईल पन्ना उपलब्ध नईखे। हो सकत बा उ के विकि पर से मिटा दिहल गईल होखे, आ चाहे उ के नाम बदल देवल गईल होखे।
-प्रासंगिक पन्ना के [[Special:Search|विकि पर खोजे के]] कोशिश करत रहीं।',
-
-# Revision deletion
-'rev-deleted-comment' => '(टिप्पणी मिटा दिहल गईल बा)',
-'rev-deleted-user' => '(प्रयोगकर्ता के नाम मिटा दिहल गईल बा)',
-'rev-deleted-event' => '(लॉग कार्रवाई मिटा दिहल गईल बा)',
-'rev-deleted-user-contribs' => '[प्रयोगकर्ता नाम आ चाहे आइ पी पता हटा दिहल गईल बा - योगदान से सम्पादन छुप गईल बा]',
-'rev-deleted-text-permission' => "ई पन्ना के संशोधन '''मिटा'''' दिहल गईल बा।
-मेटावल जानकारी [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} डिलेशन लॉग] में मिली।",
-'rev-delundel' => 'दिखाईं/छुपाईं',
-'revdel-restore' => 'दूश्यता बदलीं',
-'revdel-restore-deleted' => 'मिटल संसोधन',
-'revdel-restore-visible' => 'दृश्यमान संसोधन',
-'pagehist' => 'पन्ना के इतिहास',
-'deletedhist' => 'मिटावल इतिहास',
-
-# Merge log
-'revertmerge' => 'अलग करीं',
-'mergelogpagetext' => 'एक पन्ना इतिहास के दुसर पन्ना इतिहास में तुरंत विलय भईल एगो सूची नीचे दिहल बा।',
-
-# Diffs
-'history-title' => "''$1'' के संशोधन इतिहास",
-'lineno' => 'पंक्ति $1:',
-'compareselectedversions' => 'चुनल गईल संशोधन में अन्तर देखीं',
-'showhideselectedversions' => 'चुनल गईल संशोधन दिखाईं/छुपाईं',
-'editundo' => 'पूर्ववत',
-'diff-multi' => '({{PLURAL:$1|एगो मध्यम संशोधन|$1 गो मध्यम संशोधन}} नईखे दिखावल)',
-
-# Search results
-'searchresults' => 'खोज परिणाम',
-'searchresults-title' => '$1 खातिर खोज परिणाम',
-'searchresulttext' => '{{SITENAME}} के खोज करे के बारे में अधिक जानकारी खातिर, देखीं [[{{MediaWiki:Helppage}}| {{int:help}}]]।',
-'searchsubtitle' => '\'\'\'[[:$1]]\'\'\' खातिर राउर करल गईल खोज ([[Special:Prefixindex/$1| "$1" से शुरु होवे वाला सब पन्ना]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|all pages that link to "$1"]])',
-'searchsubtitleinvalid' => "रउआ '''$1''' खातिर खोज कईनी ह",
-'titlematches' => 'पन्ना के शिर्षक मिलत बा।',
-'notitlematches' => 'पन्ना के शिर्षक नईखे मिलत',
-'textmatches' => 'पन्ना के पाठ्य मिलत बा',
-'notextmatches' => 'पन्ना के पाठ्य नईखे मिलत',
-'prevn' => 'पिछला {{PLURAL:$1|$1}}',
-'nextn' => 'अगला {{PLURAL:$1|$1}}',
-'prevn-title' => 'पिछला $1 {{PLURAL:$1|परिणाम}}',
-'nextn-title' => 'अगला $1 {{PLURAL:$1|परिणाम}}',
-'shown-title' => 'दिखाईं $1 {{PLURAL:$1|परिणाम}}',
-'viewprevnext' => 'देखीं ($1 {{int:pipe-separator}} $2) ($3)',
-'searchmenu-legend' => 'खोज विकल्प',
-'searchmenu-exists' => "'''इ विकि पर ''[[:$1]]'' नाम से एगो पन्ना उपलब्ध बा'''",
-'searchmenu-new' => "'''इ विकि पर ''[[:$1]]'' नाम से पन्ना बनाईं'''",
-'searchhelp-url' => 'Help:सामग्री',
-'searchmenu-prefix' => '[[विशेष:उपसर्ग सूची/$1|इ उपसर्ग साथे पन्ना ब्राउज करीं]]',
-'searchprofile-articles' => 'सामग्री पन्ना',
-'searchprofile-project' => 'मदद आ परियोजना पन्ना',
-'searchprofile-images' => 'मल्टिमीडिया',
-'searchprofile-everything' => 'सब कुछ',
-'searchprofile-advanced' => 'अग्रिम',
-'searchprofile-articles-tooltip' => '$1 में खोजीं',
-'searchprofile-project-tooltip' => '$1 में खोजीं',
-'searchprofile-images-tooltip' => 'फाईल खातिर खोज',
-'searchprofile-everything-tooltip' => 'सभन सामग्री में खोजीं (वार्ता पन्ना सहित)',
-'search-result-size' => '$1 ({{PLURAL:$2|1 शब्द|$2 शब्द}})',
-'search-result-score' => 'प्रासंगिकता: $1%',
-'search-redirect' => '(पुन: निर्देशण $1)',
-'search-section' => '(खंड $1)',
-'search-suggest' => 'का राउर मतलब बा: $1',
-'search-interwiki-caption' => 'बहिन परियोजना',
-'search-interwiki-default' => '$1 के परिणाम:',
-'search-interwiki-more' => '(अउर)',
-'search-relatedarticle' => 'संबंधित',
-'mwsuggest-disable' => 'AJAX सुझाव असक्षम',
-'searcheverything-enable' => 'सभन सन्दर्भ में खोजीं',
-'searchrelated' => 'संबंधित',
-'searchall' => 'सब',
-'showingresults' => "नीचे देखावल जा रहल बा {{PLURAL:$1|'''1''' परिणाम|'''$1''' परिणाम}} #'''$2''' से शुरु होवे वाला।",
-'showingresultsnum' => "नीचे देखावल जा रहल बा {{PLURAL:$3|'''1''' परिणाम|'''$3''' परिणाम}} #'''$2''' से शुरु होवे वाला।",
-'powersearch' => 'उन्नत खोज',
-'powersearch-legend' => 'उन्नत खोज',
-'powersearch-ns' => 'सन्दर्भ में खोजीं',
-'powersearch-redir' => 'पुन:निर्देश सूची',
-'powersearch-field' => 'खातिर खोज',
-'powersearch-togglelabel' => 'जाँच:',
-'powersearch-toggleall' => 'सब',
-'powersearch-togglenone' => 'कउनो ना',
-'search-external' => 'बाहरी खोज',
-
-# Quickbar
-'qbsettings-none' => 'कउनो ना',
-
-# Preferences page
-'preferences' => 'वरीयता',
-'mypreferences' => 'हमार पसन्द',
-'prefs-edits' => 'सम्पादन संख्या',
-'prefsnologin' => 'खाता में प्रवेश नईखीं कईले',
-'changepassword' => 'गुप्त शब्द बदलीं',
-'skin-preview' => 'पूर्वावलोकन',
-'prefs-rc' => 'तुरंत भईल परिवर्तन',
-
-# Recent changes
-'recentchanges' => 'तुरंत भईल परिवर्तन',
-'rcshowhideminor' => '$1 छोट सम्पादन',
-'diff' => 'अन्तर',
-'hist' => 'इति',
-'hide' => 'छुपाँई',
-'show' => 'दिखाईं',
-'minoreditletter' => 'छो',
-'newpageletter' => 'न',
-'boteditletter' => 'बो',
-'number_of_watching_users_pageview' => '[$1 देखल जा रहल बा {{PLURAL:$1|प्रयोगकर्ता|प्रयोगकर्ता}}]',
-
-# Recent changes linked
-'recentchangeslinked' => 'सम्बन्धित बदलाव',
-'recentchangeslinked-feed' => 'सम्बन्धित बदलाव',
-'recentchangeslinked-toolbox' => 'सम्बन्धित बदलाव',
-
-# Upload
-'upload' => 'फाईल लादीं',
-
-# File description page
-'filehist' => 'पन्ना के इतिहास',
-'filehist-deleteall' => 'सब मिटाईं',
-'filehist-deleteone' => 'मिटाईं',
-'filehist-current' => 'मौजूदा',
-'filehist-datetime' => 'तारिख/समय',
-'filehist-thumb' => 'थम्बनेल',
-'filehist-nothumb' => 'बिन थम्बनेल',
-'filehist-user' => 'प्रयोगकर्ता',
-'filehist-dimensions' => 'आयाम',
-'filehist-filesize' => 'फाईल के आकार',
-'filehist-comment' => 'टिप्पणी',
-'filehist-missing' => 'गायब फाईल',
-'imagelinks' => 'फाईल लिंक',
-'nolinkstoimage' => 'इ फाईल जोड़े कौनो फाइल लिंक नईखे।',
-'morelinkstoimage' => 'इ फाइल संगे जुड़ल [[Special:WhatLinksHere/$1|सब लिंक]] देखीं।',
-'sharedupload' => 'इ फाईल $1 से बा आ दुसर परियोजना में प्रयोग करल जा सकत बा।',
-'sharedupload-desc-there' => 'इ फाईल $1 से बा आ दुसर परियोजना में प्रयोग करल जा सकत बा। अधिक जानकारी खातिर कृपया [$2 फाईल विवरण पन्ना] देखीं।',
-'filepage-nofile' => 'इ नाम से कौनो फाईल उपलब्ध नईखे।',
-'filepage-nofile-link' => 'इ नाम से कौनो फाईल उपलब्ध नईखे, लेकिन रउआ [$1 के लाद] सकत बानी।',
-'uploadnewversion-linktext' => 'इ फाईल के नया संस्करण लादीं।',
-'shared-repo-from' => '$1 से',
-'shared-repo' => 'एगो आवटिंत भंडार गृह',
-'shared-repo-name-wikimediacommons' => 'विकिमीडिया कॉमन्स',
-
-# File reversion
-'filerevert' => 'पुन: निर्देशित $1',
-'filerevert-legend' => 'पुन: निर्देशित फाईल',
-'filerevert-comment' => 'कारण:',
-
-# File deletion
-'filedelete' => '$1 के मिटाईं',
-'filedelete-legend' => 'फाईल के मिटाईं',
-'filedelete-comment' => 'कारण:',
-'filedelete-submit' => 'मिटाईं',
-'filedelete-success' => "'''$1''' के मिटा दिहल गईल बा।",
-'filedelete-nofile' => "'''$1''' उपलब्ध नईखे।",
-
-# Random page
-'randompage' => 'अविशिष्ट पन्ना',
-
-# Miscellaneous special pages
-'nbytes' => '$1 {{PLURAL:$1|बाईट|बाईट्स}}',
-'move' => 'स्थान्तरण',
-'movethispage' => 'ई पन्ना के स्थांतरण करीं',
-
-# Book sources
-'booksources' => 'किताबी स्त्रोत',
-
-# Special:AllPages
-'allpagessubmit' => 'जाईं',
-'allpagesprefix' => 'उपसर्ग के साथे पन्ना प्रदर्शन:',
-
-# E-mail user
-'emailuser' => 'ई प्रयोगकर्ता के ईमेल करीं',
-
-# Watchlist
-'watchlist' => 'हमार ध्यानसूची',
-'mywatchlist' => 'हमार ध्यानसूची',
-'watch' => 'ध्यानसूची में डालीं',
-'watchthispage' => 'ई पन्ना ध्यानसूची में डालीं',
-'unwatch' => 'ध्यानसूची से हटाईं',
-
-# Displayed when you click the "watch" button and it is in the process of watching
-'watching' => 'ध्यानसूची में जाते हुए',
-'unwatching' => 'ध्यानसूची से हटते हुए',
-
-# Undelete
-'undeletelink' => 'देखीं/बहाल करीं',
-
-# Namespace form on various pages
-'namespace' => 'सन्दर्भ',
-'invert' => 'चयनित पलटीं',
-'blanknamespace' => '(मुख्य)',
-
-# Contributions
-'contributions' => 'प्रयोगकर्ता योगदान',
-'contributions-title' => ' $1 खातिर प्रयोगकर्ता योगदान',
-'mycontris' => 'हमार योगदान',
-'nocontribs' => 'ई मानदंड से मिलत जुलत कौनो बदलाव ना मिलल।',
-'uctop' => '(शीर्ष)',
-'month' => 'महिना से (आ उ से पहिले):',
-'year' => 'साल से (आ उ से पहिले):',
-
-'sp-contributions-newbies' => 'खाली नया खाता के योगदान देखीं।',
-'sp-contributions-newbies-sub' => 'नया खाता खातिर',
-'sp-contributions-newbies-title' => 'नया खाता खातिर प्रयोगकर्ता के योगदान।',
-'sp-contributions-blocklog' => 'निष्क्रीय खाता',
-'sp-contributions-deleted' => 'नष्ट प्रयोगकर्ता के योगदान।',
-'sp-contributions-logs' => 'लौग',
-'sp-contributions-talk' => 'बात-चीत',
-'sp-contributions-userrights' => 'प्रयोगकर्ता अधिकार प्रबन्धन',
-'sp-contributions-blocked-notice' => 'ई प्रयोगकर्ता के ई समय निष्क्रीय करल गईल बा।
-नविनतम नष्ट लौग प्रविष्टी उद्धरण खातिर निचे दिहल बा:',
-
-# What links here
-'whatlinkshere' => 'अहिजा का जुड़ी',
-'whatlinkshere-title' => 'पन्ना जौन "$1" से जुड़ेला',
-'whatlinkshere-page' => 'पन्ना:',
-'linkshere' => "नीचे के सब पन्ना '''[[:$1]]''' से जुड़ेला:",
-'nolinkshere' => "'''[[:$1]]''' से कौनो पन्ना नईखे जुड़ल।",
-'nolinkshere-ns' => "चुनल गईल सन्दर्भ में '''[[:$1]]''' से कौनो पन्ना ना जुड़ेला।",
-'isredirect' => 'पुन: निर्दिष्ट पन्ना',
-'isimage' => 'तस्वीर लिंक',
-'whatlinkshere-prev' => '{{PLURAL:$1|पिछला|पिछला $1}}',
-'whatlinkshere-next' => '{{PLURAL:$1|अगला|अगला $1}}',
-'whatlinkshere-links' => '← लिंक',
-'whatlinkshere-hideredirs' => '$1 पुन: निर्देशित',
-'whatlinkshere-hidelinks' => '$1 लिंक',
-'whatlinkshere-hideimages' => '$1 तस्वीर लिंक',
-'whatlinkshere-filters' => 'फिल्टर',
-
-# Block/unblock
-'blockip' => 'प्रतिबंधित प्रयोगकर्ता',
-'blocklink' => 'निष्क्रिय',
-'unblocklink' => 'ताला खोलीं',
-'change-blocklink' => 'ब्लॉक बदलीं',
-'contribslink' => 'योगदान',
-'blocklogpage' => 'निष्क्रिय खाता',
-
-# Move page
-'movepagebtn' => 'पन्ना स्थांतरण करीं',
-'revertmove' => 'पिछलका स्थिति',
-
-# Thumbnails
-'thumbnail-more' => 'बढ़ाईं',
-'filemissing' => 'फाईल गायब',
-
-# Tooltip help for the actions
-'tooltip-pt-userpage' => 'राउर प्रयोगकर्ता पन्ना',
-'tooltip-pt-mytalk' => 'राउर वार्ता पन्ना',
-'tooltip-pt-preferences' => 'राउर पसन्द',
-'tooltip-pt-mycontris' => 'राउर योगदान के सूची',
-'tooltip-pt-login' => 'रउआ के खाता प्रवेश खातिर प्रोत्साहित करल जा रहल बा, बाँकि ई अनिवार्य नईखे',
-'tooltip-pt-anonlogin' => 'रउआ के खाता प्रवेश खातिर प्रोत्साहित करल जा रहल बा, बाँकि ई अनिवार्य नईखे',
-'tooltip-pt-logout' => 'खाता से बाहर',
-'tooltip-ca-talk' => 'सामग्री पन्ना के बारे में बात-चीत',
-'tooltip-ca-edit' => 'रउआ ई पन्ना के सम्पादन कर सकत बानी। कृपया पन्ना सुरक्षित करे से पहिले पूर्वावलोकन बटन के इस्तेमाल करीं।',
-'tooltip-ca-addsection' => 'एगो नया खण्ड शुरु करीं',
-'tooltip-ca-viewsource' => 'इ पन्ना के संरक्षित कर दिहल गईल बा। रऊआ एकर मूल देख सकत बानी।',
-'tooltip-ca-history' => 'ई पन्ना के पिछला संशोधन',
-'tooltip-ca-protect' => 'इ पन्ना के संरक्षित करीं।',
-'tooltip-ca-unprotect' => 'इ पन्ना के संरक्षण हटाईं।',
-'tooltip-ca-delete' => 'ई पन्ना मिटाईं',
-'tooltip-ca-move' => 'ई पन्ना के स्थांतरण करीं',
-'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' => 'बेतरतिब पन्ना लादीं (Load करीं)',
-'tooltip-n-help' => 'जगह पता लगावे खातिर',
-'tooltip-t-whatlinkshere' => 'अहिजा लिंक होखे वाला सब विकि पन्ना के सूची',
-'tooltip-t-recentchangeslinked' => 'ई पन्ना से जुड़ल पन्नवन पर तुरंत भईल परिवर्तन',
-'tooltip-t-upload' => 'फाईल लादीं (अपलोड )',
-'tooltip-t-specialpages' => 'ख़ाश पन्नवन के सूची',
-'tooltip-t-print' => 'ई पन्ना के छापे लायक संस्करण।',
-'tooltip-t-permalink' => 'ई पन्ना के संसोधन खातिर स्थायी लिंक।',
-'tooltip-ca-nstab-main' => 'सामग्री पन्ना देखीं',
-'tooltip-ca-nstab-special' => 'ई एगो ख़ाश पन्ना ह, रउआ ई पन्ना के सम्पादन नईखीं कर सकत',
-'tooltip-save' => 'आपन बदलाव के सुरक्षित करीं',
-
-# Media information
-'svg-long-desc' => 'एस वी जी फाईल, नॉमिनल्ली $1 x $2 पिक्सल्स, फाईल के आकार $3',
-'show-big-image' => 'पुरा गुणवत्ता',
-'file-info-gif-looped' => 'लूप्ड',
-'file-info-gif-frames' => '$1 {{PLURAL:$1|फ्रेम}}',
-'file-info-png-looped' => 'लूप्ड',
-
-# Bad image list
-'bad_image_list' => 'फोर्मेट निम्न अनुसार बा:
-खाली सूची सामग्री (* से शुरु होवे वाला पंक्ति ) मानल गईल बा।
-पंक्ति पर पहिला लिंक एगो खराब फाईल के साथ जुड़ल होवे के चाहीं।
-कोई भी बाद वाला लिंक ओही पंक्ति पर अईला पर उ के अपवाद मानल जाई, अर्थात जौन पन्ना पर फाईल इनलाईन हो सकत बा।',
-
-# Metadata
-'metadata' => 'मेटाडाटा',
-'metadata-help' => 'इ फाईल में अतिरिक्त जानकारी उपलब्ध बा, हो सकत बा कि इ डिजीटल कैमरा या स्कैनर से लेवल गईल होखे। यदि इ फाईल एकर मूल फाईल में से संशोधित करल गईल बा त कुछ जानकारी उजागर ना हो सकी।',
-'metadata-expand' => 'विस्तृत विवरण देखाईं',
-'metadata-collapse' => 'विस्तृत विवरण छुपाँईं',
-
-# EXIF tags
-'exif-imagewidth' => 'चौड़ाई',
-'exif-imagelength' => 'ऊँचाई',
-'exif-bitspersample' => 'अवयव प्रति बीट',
-'exif-compression' => 'सम्पीड़न प्रणाली',
-'exif-photometricinterpretation' => 'पिक्सल रचना',
-'exif-orientation' => 'अभिसंस्करण',
-'exif-samplesperpixel' => 'अवयवन के संख्या',
-'exif-planarconfiguration' => 'डेटा प्रबन्धन',
-'exif-xresolution' => 'क्षैतिज समाधान',
-'exif-yresolution' => 'लम्बवत समाधान',
-'exif-stripoffsets' => 'चित्र डेटा के स्थिती',
-'exif-jpeginterchangeformatlength' => 'JPEG डेटा के बाइट',
-
-# 'all' in various places, this might be different for inflected languages
-'namespacesall' => 'सब',
-'monthsall' => 'सब',
-'limitall' => 'सब',
-
-# E-mail address confirmation
-'confirmemail' => 'इ-मेल पता कन्फर्म करीं',
-
-# Special:SpecialPages
-'specialpages' => 'ख़ाश पन्ना',
-
-# New logging system
-'revdelete-restricted' => 'प्रबंधक पर प्रतिबंध लागू',
-'revdelete-unrestricted' => 'प्रबंधक पर से प्रतिबंध समाप्त',
-
-);
index 014a8ec..2b2a528 100644 (file)
@@ -113,6 +113,7 @@ $messages = array(
 
 # Categories related messages
 'pagecategories' => '{{PLURAL:$1|श्रेणी|श्रेणी}}',
+'hidden-categories' => '{{PLURAL:$1|छुपावल गईल श्रेणी|छुपावल गईल श्रेणी}}',
 
 'about' => 'बारे में',
 'article' => 'सामग्री पन्ना',
@@ -142,6 +143,9 @@ $messages = array(
 'vector-view-history' => 'इतिहास देखीं',
 'vector-view-view' => 'पढ़ीं',
 'vector-view-viewsource' => 'स्त्रोत देखीं',
+'actions' => 'क्रिया',
+'namespaces' => 'नामस्थान',
+'variants' => 'संस्करण',
 
 'errorpagetitle' => 'त्रुटी',
 'returnto' => 'जाईं $1 पर।',
@@ -211,6 +215,7 @@ $1',
 'disclaimerpage' => 'Project:सामान्य अस्विकरण',
 'edithelp' => 'मदद सम्पादन',
 'edithelppage' => 'Help:सम्पादन',
+'helppage' => 'मदद:सामग्री',
 'mainpage' => 'मुख्य पन्ना',
 'mainpage-description' => 'पहिलका पन्ना',
 'portal' => 'सामुदायिक पन्ना',
@@ -278,6 +283,7 @@ $1',
 'yourname' => 'प्रयोगकर्ता नाम',
 'yourpassword' => 'गुप्त शब्द',
 'yourpasswordagain' => 'गुप्त-शब्द पुन:डालीं:',
+'remembermypassword' => 'इ ब्राउजर पर हमार प्रवेश जारी रहे (अधिकतम $1 {{PLURAL:$1|दिन|दिन}})',
 'login' => 'खाता में प्रवेश',
 'nav-login-createaccount' => 'खाता प्रवेश / खाता बनाईं',
 'loginprompt' => '{{SITENAME}} में प्रवेश खातिर राउर कुकिज चालू होवे के चाहीं',
@@ -332,6 +338,7 @@ $1',
 'italic_sample' => 'इटालिक पाठ्य',
 'italic_tip' => 'इटालिक पाठ्य',
 'headline_sample' => 'शिर्षक पाठ्य',
+'headline_tip' => 'द्वितीय-श्रेणी के शीर्षक',
 'image_sample' => 'उदाहरण.jpg',
 'media_sample' => 'उदाहरण.ogg',
 'media_tip' => 'फाईल लिंक',
@@ -364,9 +371,14 @@ $1',
 'newarticletext' => "रउआ एगो अइसन लिंक के पन्ना के अनुसरण कइले बानी जउन अभी तक उपलब्ध नइखे।
 पन्ना बनावे खातिर, नीचे के बाकस में टाईप करे के शुरु करीं (ज्यादा जानकारी खातिर देखीं [[{{MediaWiki:Helppage}}|मदद पन्ना]])।
 यदि रउआ अहिजा गलती से आ गईल बानी त, आपन ब्राउजर के '''back''' (बैक) बटन दबाईं",
+'noarticletext' => 'ई पन्ना मे अभी कउनो सामग्री नईखे बा ।
+रउआ अन्य पन्ना में [[Special:Search/{{PAGENAME}}|ई शीर्षक के खोज]] कर सकत बानीं',
 'yourdiff' => 'अंतर',
 'template-protected' => '(संरक्षित)',
 
+# Parser/template warnings
+'post-expand-template-inclusion-category' => 'अइसन पृष्ठ जे पर साँचा जोडे के सीमा पार हो गइल बा',
+
 # History pages
 'revisionasof' => '$1 के रुप में संशोधन',
 'revision-info' => '$2 में से $1 के रुप में संशोधन',
@@ -450,6 +462,7 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'searchprofile-project-tooltip' => '$1 में खोजीं',
 'searchprofile-images-tooltip' => 'फाईल खातिर खोज',
 'searchprofile-everything-tooltip' => 'सभन सामग्री में खोजीं (वार्ता पन्ना सहित)',
+'searchprofile-advanced-tooltip' => 'विशेष नामस्थान में खोजीं',
 'search-result-size' => '$1 ({{PLURAL:$2|1 शब्द|$2 शब्द}})',
 'search-result-score' => 'प्रासंगिकता: $1%',
 'search-redirect' => '(पुन: निर्देशण $1)',
@@ -465,6 +478,7 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'searchall' => 'सब',
 'showingresults' => "नीचे देखावल जा रहल बा {{PLURAL:$1|'''1''' परिणाम|'''$1''' परिणाम}} #'''$2''' से शुरु होवे वाला।",
 'showingresultsnum' => "नीचे देखावल जा रहल बा {{PLURAL:$3|'''1''' परिणाम|'''$3''' परिणाम}} #'''$2''' से शुरु होवे वाला।",
+'search-nonefound' => 'राउर खोज मे से मेल खात कउनो परिणाम नईखे बा',
 'powersearch' => 'उन्नत खोज',
 'powersearch-legend' => 'उन्नत खोज',
 'powersearch-ns' => 'सन्दर्भ में खोजीं',
@@ -489,6 +503,9 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 
 # Recent changes
 'recentchanges' => 'तुरंत भईल परिवर्तन',
+'recentchanges-legend' => 'हाल के परिवर्तन संबंधी विकल्प',
+'recentchanges-label-newpage' => 'ई सम्पादन से एगो नवका पृष्ठ तैयार हो गइल बा',
+'recentchanges-label-minor' => 'ई एगो छोटा सम्पाद बा',
 'rcshowhideminor' => '$1 छोट सम्पादन',
 'diff' => 'अन्तर',
 'hist' => 'इति',
@@ -508,6 +525,7 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'upload' => 'फाईल लादीं',
 
 # File description page
+'file-anchor-link' => 'फ़ाइल',
 'filehist' => 'पन्ना के इतिहास',
 'filehist-deleteall' => 'सब मिटाईं',
 'filehist-deleteone' => 'मिटाईं',
@@ -550,6 +568,7 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 
 # Miscellaneous special pages
 'nbytes' => '$1 {{PLURAL:$1|बाईट|बाईट्स}}',
+'newpages' => 'नवका पन्ना',
 'move' => 'स्थान्तरण',
 'movethispage' => 'ई पन्ना के स्थांतरण करीं',
 
@@ -557,6 +576,8 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'booksources' => 'किताबी स्त्रोत',
 
 # Special:AllPages
+'alphaindexline' => '$1 से $2',
+'allarticles' => 'सभी पन्ना',
 'allpagessubmit' => 'जाईं',
 'allpagesprefix' => 'उपसर्ग के साथे पन्ना प्रदर्शन:',
 
@@ -574,6 +595,11 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'watching' => 'ध्यानसूची में जाते हुए',
 'unwatching' => 'ध्यानसूची से हटते हुए',
 
+'created' => 'बनावल गईल',
+
+# Rollback
+'rollbacklink' => 'वापिस लीं',
+
 # Undelete
 'undeletelink' => 'देखीं/बहाल करीं',
 
@@ -631,6 +657,9 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'movepagebtn' => 'पन्ना स्थांतरण करीं',
 'revertmove' => 'पिछलका स्थिति',
 
+# Export
+'export' => 'पन्ना निर्यात करीं',
+
 # Thumbnails
 'thumbnail-more' => 'बढ़ाईं',
 'filemissing' => 'फाईल गायब',
@@ -639,8 +668,9 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'tooltip-pt-userpage' => 'राउर प्रयोगकर्ता पन्ना',
 'tooltip-pt-mytalk' => 'राउर वार्ता पन्ना',
 'tooltip-pt-preferences' => 'राउर पसन्द',
+'tooltip-pt-watchlist' => 'राउर ध्यान दियल पन्ना के सूची',
 'tooltip-pt-mycontris' => 'राउर योगदान के सूची',
-'tooltip-pt-login' => 'रà¤\89à¤\86 à¤\95à¥\87 à¤\96ाता à¤ªà¥\8dरवà¥\87श à¤\96ातिर à¤ªà¥\8dरà¥\8bतà¥\8dसाहित à¤\95रल à¤\9cा à¤°à¤¹à¤² à¤¬à¤¾, à¤¬à¤¾à¤\81à¤\95ि à¤\88 à¤\85निवारà¥\8dय à¤¨à¤\88à¤\96à¥\87',
+'tooltip-pt-login' => 'रउआ के खाता प्रवेश खातिर प्रोत्साहित करल जा रहल बा, बाकि ई अनिवार्य नईखे',
 'tooltip-pt-anonlogin' => 'रउआ के खाता प्रवेश खातिर प्रोत्साहित करल जा रहल बा, बाँकि ई अनिवार्य नईखे',
 'tooltip-pt-logout' => 'खाता से बाहर',
 'tooltip-ca-talk' => 'सामग्री पन्ना के बारे में बात-चीत',
@@ -672,7 +702,13 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'tooltip-t-permalink' => 'ई पन्ना के संसोधन खातिर स्थायी लिंक।',
 'tooltip-ca-nstab-main' => 'सामग्री पन्ना देखीं',
 'tooltip-ca-nstab-special' => 'ई एगो ख़ाश पन्ना ह, रउआ ई पन्ना के सम्पादन नईखीं कर सकत',
+'tooltip-ca-nstab-image' => 'संचिका के पन्ना देखीं',
+'tooltip-ca-nstab-template' => 'टेम्प्लेट देखीं',
+'tooltip-ca-nstab-category' => 'श्रेणी के पन्ना देखीं',
 'tooltip-save' => 'आपन बदलाव के सुरक्षित करीं',
+'tooltip-preview' => 'आपन द्वारा कियल गइल बदलाव के देखीं, संजोये से पहले ईका इस्तेमाल करीं!',
+'tooltip-rollback' => '"वापिस लीं" ई पन्ना के पिछ्ला योगदाता के बदलाव एकही चटके मे गायब कर देवेला',
+'tooltip-summary' => 'एगो संक्षिप्त सारांश दर्ज करीं',
 
 # Media information
 'file-nohires' => ' उच्च गुणवत्ता उपलब्ध नईखे।',
index eb7ceb1..ea21777 100644 (file)
@@ -3659,7 +3659,6 @@ Situs ngini mangalami kangalihan teknik.',
 'logentry-newusers-create' => '$1 ma-ulah sabuting akun pamakai',
 'logentry-newusers-create2' => '$1 ma-ulah sabuting akun pamakai $3',
 'logentry-newusers-autocreate' => 'Akun $1 utumatis diulah',
-'newuserlog-byemail' => 'Katasunduk dikirimakan lung suril.',
 'rightsnone' => '(kadada)',
 
 # Feedback
index 6d36624..c425d6a 100644 (file)
@@ -17,6 +17,7 @@
  * @author Prometheus.pyrphoros
  * @author RIPENDIL
  * @author Reedy
+ * @author Runab
  * @author Samritmaity
  * @author Sayak Sarkar
  * @author Sm faysal
@@ -2044,7 +2045,7 @@ Maybe you want to edit the description on its [$2 file description page] there.'
 'usermessage-editor' => 'সিস্টেম ম্যাসেঞ্জার',
 
 # Watchlist
-'watchlist' => 'à¦\86মার à¦¨à¦\9cর à¦¤à¦¾à¦²à¦¿à¦\95া',
+'watchlist' => 'নজর তালিকা',
 'mywatchlist' => 'নজর তালিকা',
 'watchlistfor2' => '$1 ($2)-এর জন্য',
 'nowatchlist' => 'আপনার নজরতালিকা খালি।',
@@ -3609,7 +3610,6 @@ $4-এ নিশ্চিতকরণ কোডটি মেয়াদোত
 'logentry-newusers-create' => '$1 অ্যাকাউন্টটি তৈরী করা হয়েছে',
 'logentry-newusers-create2' => '$1 ব্যবহারকারী $3 নামের অ্যাকাউন্টটি তৈরী করেছেন',
 'logentry-newusers-autocreate' => '$1 অ্যাকাউন্টটি স্বয়ংক্রিয়ভাবে তৈরি হয়েছে',
-'newuserlog-byemail' => 'শব্দচাবি ইমেইলের মাধ্যমে পাঠানো হয়েছে',
 'logentry-rights-rights' => '$1 ব্যবহারকারী, $3 এর দলগত সদস্যপদ $4 থেকে $5 এ পরিবর্তন করেছেন',
 'logentry-rights-autopromote' => '$1 সয়ংক্রিয়ভাবে $4 থেকে $5 এ উন্নীত হয়েছে',
 'rightsnone' => '(কিছু নাই)',
index d2e61c2..d345834 100644 (file)
@@ -1728,7 +1728,6 @@ Also see [[Special:WantedCategories|wanted categories]].',
 # New logging system
 'revdelete-restricted' => 'ডান্ডিকরেকুরাগরাঙ সীমাবদ্ধতাহানি ফলা',
 'revdelete-unrestricted' => 'ডান্ডিকরেকুরাগরাঙ সীমাবদ্ধতাহানি নেইকর',
-'newuserlog-byemail' => 'ই-মেইলর মা পেঠাদিয়াসি পাসৱার্ডগ',
 'rightsnone' => '(নেই)',
 
 # Search suggestions
index 44f89a5..0098433 100644 (file)
@@ -312,6 +312,7 @@ $messages = array(
 'newwindow' => '(digeriñ en ur prenestr nevez)',
 'cancel' => 'Nullañ',
 'moredotdotdot' => "Ha muioc'h c'hoazh...",
+'morenotlisted' => "Ha muioc'h c'hoazh n'int ket rollet...",
 'mypage' => 'Ma zammig pajenn',
 'mytalk' => "Ma c'haozeadennoù",
 'anontalk' => "Kaozeal gant ar chomlec'h IP-mañ",
@@ -553,7 +554,7 @@ Goulenn : $2",
 'viewsource-title' => 'Gwelet an tarzh evit $1',
 'actionthrottled' => 'Ober daleet',
 'actionthrottledtext' => "A-benn dizarbenn ar strob, n'haller ket implijout an ober-mañ re alies en ur frapad amzer lakaet, hag aet oc'h dreist ar muzul. Klaskit en-dro a-benn un nebeut munutennoù.",
-'protectedpagetext' => "Prennet eo bet ar bajenn-mañ. N'haller ket kemmañ anezhi ken.",
+'protectedpagetext' => 'Prennet eo bet ar bajenn-mañ kuit na vefe skrivet pe cheñchet un dra bennak enni',
 'viewsourcetext' => 'Gallout a rit gwelet hag eilañ danvez ar bajenn-mañ',
 'viewyourtext' => "Gallout a rit gwelet hag eilañ mammenn ho '''kemmoù''' d'ar bajenn-mañ :",
 'protectedinterface' => 'Testenn ar bajenn-mañ a dalvez evit etrefas ar meziant er wiki-mañ. Setu perak eo bet gwarezet ar bajenn.',
@@ -586,6 +587,8 @@ Setu amañ perak ''$2''.",
 Gallout a rit kenderc'hel da implijout {{SITENAME}} en un doare dizanv, pe <span class='plainlinks'>[$1 kevreañ en-dro]</span> gant an hevelep anv pe un anv all mar fell deoc'h.
 Notit mat e c'hallo pajennoù zo kenderc'hel da vezañ diskwelet evel pa vefec'h kevreet c'hoazh, betek ma vo riñset krubuilh ho merdeer ganeoc'h.",
 'welcomeuser' => 'Degemer mat $1 !',
+'welcomecreation-msg' => 'Krouet eo bet ho kont implijer.
+Na zisoñjit ket resisaat ho [[Special:Preferences|penndibaboù evit {{SITENAME}}]].',
 'yourname' => 'Anv implijer :',
 'yourpassword' => 'Ger-tremen :',
 'yourpasswordagain' => 'Skrivit ho ker-tremen en-dro',
@@ -608,7 +611,7 @@ Notit mat e c'hallo pajennoù zo kenderc'hel da vezañ diskwelet evel pa vefec'h
 'gotaccount' => "Ur gont zo ganeoc'h dija ? '''$1'''.",
 'gotaccountlink' => 'Kevreañ',
 'userlogin-resetlink' => "Ha disoñjet eo bet ho titouroù kevreañ ganeoc'h ?",
-'createaccountmail' => 'dre bostel',
+'createaccountmail' => 'Dre bostel',
 'createaccountreason' => 'Abeg :',
 'badretype' => 'Ne glot ket ar gerioù-tremen an eil gant egile.',
 'userexists' => "Implijet eo an anv implijer lakaet ganeoc'h dija.
@@ -734,6 +737,7 @@ Ger-tremen da c'hortoz : $2",
 'changeemail-oldemail' => "Chomlec'h postel a-vremañ :",
 'changeemail-newemail' => "Chomlec'h postel nevez :",
 'changeemail-none' => '(hini ebet)',
+'changeemail-password' => 'Ho ker-tremen war {{SITENAME}}:',
 'changeemail-submit' => "Cheñch chomlec'h postel",
 'changeemail-cancel' => 'Nullañ',
 
@@ -896,10 +900,11 @@ Heñveldra, prometiñ a rit kemer perzh dre zegas skridoù savet ganeoc'h hepken
 '''NA IMPLIJIT KET LABOURIOÙ GANT GWIRIOÙ AOZER (COPYRIGHT) HEP AOTRE D'OBER KEMENT-SE!'''",
 'copyrightwarning2' => "Notit mat e c'hall kement degasadenn graet ganeoc'h war {{SITENAME}} bezañ kemmet, adaozet pe lamet kuit gant an implijerien all. Mar ne fell ket deoc'h e vije kemmet-digemmet ar pezh hoc'h eus skrivet na gemerit ket perzh er raktres-mañ.<br /> Gouestlañ a rit ivez eo bet savet ar boued spered ganeoc'h pe eilet diwar ur vammenn frank a wirioù pe en domani foran (gwelet $1 evit gouzout hiroc'h). '''NA IMPLIJIT KET LABOURIOÙ GANT GWIRIOÙ AOZER HEP AOTRE D'OBER KEMENT-SE!'''",
 'longpageerror' => "'''FAZI : {{PLURAL:$1|Ur c'hilookted|$1 kilookted}} hir eo an destenn lakaet ganeoc'h, ar pezh zo hiroc'h eget {{PLURAL:$2|ur c'hilookted|$2 kilookted}}, ar vent vrasañ aotreet. N'haller ket enrollañ.'''",
-'readonlywarning' => "'''KEMENN DIWALL : stanket eo an diaz titouroù a-benn bezañ trezalc'het; setu ne viot ket evit enrollañ ho kemmoù diouzhtu-diouzhtu eta.
-Gallout a rit eilañ-pegañ an destenn en ur restr skrid all hag enrollañ anezhi a-benn diwezhatoc'hik.'''
+'readonlywarning' => "'''KEMENN DIWALL : prennet eo bet an diaz titouroù evit bezañ trezalc'het; setu ne viot ket evit enrollañ ho kemmoù diouzhtu-diouzhtu eta.'''
 
-Setu an displegadenn lakaet gant ar merour en deus stanket an traoù : $1",
+Gallout a rit eilañ ha pegañ ho testenn en ur restr skrid all hag enrollañ anezhi a-benn diwezhatoc'hik.'''
+
+Setu an displegadenn lakaet gant ar merour eo bet prennet an traoù gantañ : $1",
 'protectedpagewarning' => "'''KEMENN DIWALL: Gwarezet eo bet ar bajenn-mañ. N'eus nemet an implijerien ganto ar statud merour a c'hall kemmañ anezhi.'''
 Enmont diwezhañ ar marilh a ziskouezer amañ a-is evel dave :",
 'semiprotectedpagewarning' => "''Notenn :''' Gwarezet eo ar bajenn-mañ; n'eus nemet an implijerien bet krouet ur gont ganto a kemmañ anezhi. Kasadenn ziwezhañ ar marilh zo diskouezet amañ a-is evel dave :",
@@ -969,10 +974,10 @@ A-gostez eo bet lezet an arventenn-se.',
 'converter-manual-rule-error' => 'Fazi dinodet  er reolenn cheñch yezh dre zorn',
 
 # "Undo" feature
-'undo-success' => "Gallout a reer disteurel ar c'hemmoù-mañ. Gwiriit, mar plij, gant ar geñveriadenn a-is evit bezañ sur eo an dra-se a fell deoc'h ober; goude-se enrollit ar c'hemmoù a-is a-benn echuiñ disteurel ar c'hemmoù.",
+'undo-success' => "Gallout a reer dizober ar c'hemmoù-mañ. Gwiriit, mar plij, gant ar geñveriadenn a-is evit bezañ sur eo an dra-se a fell deoc'h ober; goude-se enrollit ar c'hemmoù a-is a-benn echuiñ disteurel ar c'hemmoù.",
 'undo-failure' => "N'eus ket bet tu da zisteuler ar c'hemm-mañ abalamour d'un tabut gant kemmoù degaset e-keit-se.",
 'undo-norev' => "N'eus ket bet gallet degas ar c'hemmoù-mañ rak pe n'eus ket anezho pe int bet diverket.",
-'undo-summary' => 'Disteurel kemmoù $1 a-berzh [[Special:Contributions/$2|$2]] ([[User talk:$2|kaozeal]])',
+'undo-summary' => 'Dizober kemmoù $1 a-berzh [[Special:Contributions/$2|$2]] ([[User talk:$2|kaozeal]])',
 
 # Account creation failure
 'cantcreateaccounttitle' => 'Dibosupl krouiñ ar gont',
@@ -1199,7 +1204,7 @@ Gallout a reot kavout munudoù e [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'search-interwiki-default' => "$1 disoc'h :",
 'search-interwiki-more' => "(muioc'h)",
 'search-relatedarticle' => "Disoc'hoù kar",
-'mwsuggest-disable' => 'Diweredekaat kinnigoù AJAX',
+'mwsuggest-disable' => "Diweredekaat ar c'hinnigoù klask",
 'searcheverything-enable' => 'Klask en holl esaouennoù anv',
 'searchrelated' => "disoc'hoù kar",
 'searchall' => 'An holl',
@@ -1305,8 +1310,8 @@ Setu aze un dalvoudenn ganet dre zegouezh hag a c'hallfec'h implijout : $1",
 'prefs-emailconfirm-label' => 'Kadarnaat ar postel :',
 'prefs-textboxsize' => 'Ment ar prenestr skridaozañ',
 'youremail' => 'Postel :',
-'username' => 'Anv implijer :',
-'uid' => 'Niv. identelezh an implijer :',
+'username' => '{{GENDER:$1|Anv implijer|Anv implijerez}}:',
+'uid' => '{{GENDER:$1|Niv. identelezh an implijer|Niv. identelezh an implijerez}}:',
 'prefs-memberingroups' => 'Ezel eus {{PLURAL:$1|ar strollad|ar strolladoù}}:',
 'prefs-registration' => 'Deiziad enskrivañ :',
 'yourrealname' => 'Anv gwir*',
@@ -1703,6 +1708,7 @@ Ma talc'h ar gudenn, kit e darempred gant [[Special:ListUsers/sysop|merourien ar
 'backend-fail-notsame' => "Ur restr disheñvel zo e $1 c'hoazh.",
 'backend-fail-invalidpath' => "$1 n'eo ket un hent stokañ reizh.",
 'backend-fail-delete' => 'Dibosupl eo diverkañ ar restr $1.',
+'backend-fail-describe' => 'N\'eus ket bet gallet cheñch ar metaroadennoù evit ar restr "$1".',
 'backend-fail-alreadyexists' => 'Ar restr "$1" zo anezhi c\'hoazh.',
 'backend-fail-store' => 'Dibosupl stokañ ar restr $1 e $2.',
 'backend-fail-copy' => 'Dibosupl eilañ ar restr "$1" war-du "$2".',
@@ -2089,7 +2095,7 @@ Gwelet ivez ar [[Special:WantedCategories|rummadoù goulennet a vank]].',
 'linksearch-ok' => 'Klask',
 'linksearch-text' => 'Gallout a reer implijout arouezennoù "joker" evel, da skouer, "*.wikipedia.org".
 Rekis eo dezho un domani a-us da nebeutañ evel, da skouer, "*.org".<br />
-Protokoloù skoret : <code>$1</code> (defaults to http:// na lakait hini ebet eus ar re-se en ho klask)',
+{{PLURAL:$2|Protokol|Protokoloù}} skoret : <code>$1</code> (defaults to http:// na lakait hini ebet eus ar re-se en ho klask).',
 'linksearch-line' => '$1 gant ul liamm adal $2',
 'linksearch-error' => "N'hall an arouezennoù joker bezañ implijet nemet e deroù anv domani an ostiz.",
 
@@ -2102,7 +2108,7 @@ Protokoloù skoret : <code>$1</code> (defaults to http:// na lakait hini ebet eu
 # Special:ActiveUsers
 'activeusers' => 'Roll an implijerien oberiant',
 '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|degasadenn}} abaoe an {{PLURAL:$3|deiz|$3 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 robotoù',
 'activeusers-hidesysops' => 'Kuzhat ar verourien',
@@ -2177,9 +2183,7 @@ E maezienn \"Kaser\" ho postel e vo merket ar chomlec'h postel resisaet ganeoc'h
 a-benn gellout kemmañ ho roll evezhiañ.",
 'addwatch' => "Ouzhpennañ d'ar roll evezhiañ",
 'addedwatchtext' => 'Ouzh ho [[Special:Watchlist|rollad evezhiañ]] eo bet ouzhpennet ar bajenn "[[:$1]]".
-Kemmoù da zont ar bajenn-mañ ha re ar bajenn gaozeal stag outi a vo rollet amañ hag e teuio ar bajenn <b>e tev</b> er [[Special:RecentChanges|roll kemmoù diwezhañ]] evit bezañ gwelet aesoc\'h ganeoc\'h.
-
-Evit tennañ ar bajenn-mañ a-ziwar ho rollad evezhiañ, klikit war "Paouez da evezhiañ" er framm merdeiñ.',
+Amañ e vo rollet ar c\'hemmoù da zont evit ar bajenn-mañ hag ar bajenn gaozeal stag outi.',
 'removewatch' => 'Lemel a-ziwar ar roll evezhiañ',
 'removedwatchtext' => 'Lamet eo bet ar bajenn "[[:$1]]" a-ziwar ho [[Special:Watchlist|roll evezhiañ]].',
 'watch' => 'Evezhiañ',
@@ -2280,8 +2284,8 @@ taolit evezh bras.",
 'rollback' => "disteuler ar c'hemmoù",
 'rollback_short' => 'Disteuler',
 'rollbacklink' => 'disteuler',
-'rollbacklinkcount' => 'terriñ $1 {{PLURAL:$1|kemm|kemmañ}}',
-'rollbacklinkcount-morethan' => 'terriñ ouzhpenn $1 {{PLURAL:$1|kemm|kemmoù}}',
+'rollbacklinkcount' => 'disteurel $1 {{PLURAL:$1|kemm}}',
+'rollbacklinkcount-morethan' => 'disteurel ouzhpenn $1 {{PLURAL:$1|kemm}}',
 'rollbackfailed' => "C'hwitet eo bet an distaoladenn",
 'cantrollback' => 'Dibosupl da zisteuler: an aozer diwezhañ eo an hini nemetañ da vezañ kemmet ar pennad-mañ',
 'alreadyrolled' => "Dibosupl eo disteuler ar c'hemm diwezhañ graet d'ar bajenn [[:$1]] gant [[User:$2|$2]] ([[User talk:$2|Kaozeal]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);
@@ -2326,9 +2330,9 @@ Setu doare a-vremañ ar bajenn '''$1''' :",
 Setu an doare a-vremañ evit ar bajenn-mañ '''$1''':",
 'protect-cascadeon' => "Gwarezet eo ar bajenn-mañ peogwir he c'haver er {{PLURAL:$1|bajenn|pajennoù}} da-heul zo gweredekaet enno ar gwareziñ dre skalierad. Gallout a rit kemmañ al live gwareziñ met ne cheñcho ket ar gwareziñ dre skalierad.",
 'protect-default' => 'Aotren an holl implijerien',
-'protect-fallback' => 'Ezhomm zo aotre "$1"',
-'protect-level-autoconfirmed' => "Stankañ an implijerien nevez hag ar re n'int ket enrollet",
-'protect-level-sysop' => 'Merourien hepken',
+'protect-fallback' => 'Degemer hepken an implijerien gant an aotre "$1"',
+'protect-level-autoconfirmed' => 'Degemer hepken an implijerien emgadarnaet',
+'protect-level-sysop' => 'Aotren ar verourien hepken',
 'protect-summary-cascade' => 'Gwareziñ dre skalierad',
 'protect-expiring' => "a zeu d'e dermen d'an $1",
 'protect-expiring-local' => "a ya d'e dermen d'an $1",
@@ -2617,10 +2621,17 @@ Kadarnait, mar plij, eo se hoc'h eus c'hoant da ober.",
 # Move page
 'move-page' => "Dilec'hiañ $1",
 'move-page-legend' => 'Adenvel ur pennad',
-'movepagetext' => "Grit gant ar furmskrid a-is evit adenvel ur pennad hag adkas an holl stummoù kent anezhañ war-du an anv nevez.
-Dont a raio an titl kentañ da vezañ ur bajenn adkas war-du an titl nevez.
+'movepagetext' => "Grit gant ar furmskrid a-is evit adenvel ur pennad hag adkas an holl stummoù kent anezhañ war-zu an anv nevez.
+Dont a raio an titl kozh da vezañ ur bajenn adkas war-zu an titl nevez.
+Gallout a rit nevesaat ent emgefre an adkasoù a-vremañ a gas d'an titl orin.
 Ne vo ket kemmet liammoù an titl kozh ha ne vo ket dilec'hiet ar bajenn gaozeal, ma'z eus anezhi.
 
+Ma rit ho soñj chom hep en ober, gwiriit mat an holl [[Special:DoubleRedirects|adkasoù doubl]] pe [[Special:BrokenRedirects|adkasoù torret]].
+C'hwi eo zo karget da wiriañ e kas mat al liammoù d'al lec'h int sañset kas.
+
+Notit mat '''ne vo ket''' dilec'hiet ma'z eus dija ur bajenn ganti an anv nevez, nemet e vefe un adkas ha ne vefe tamm istor ebet stag outi.
+Dre se e c'haller adkas ur bajenn war-zu he lec'h orin ma oa kamm an adkas.
+
 '''DIWALLIT!'''
 Gallout a ra kement-se bezañ ur c'hemm bras ha dic'hortoz evit ur pennad a vez sellet outi alies;
 bezit sur e komprenit mat an heuliadoù a-raok kenderc'hel ganti.",
@@ -2980,6 +2991,10 @@ Sur a-walc'h abalamour d'ul liamm enni a gas d'ul lec'hienn ziavaez berzet.",
 'pageinfo-redirectsto-info' => 'Titouroù',
 'pageinfo-contentpage-yes' => 'Ya',
 'pageinfo-protect-cascading-yes' => 'Ya',
+'pageinfo-category-info' => 'Titouroù ar rummad',
+'pageinfo-category-pages' => 'Niver a bajennoù',
+'pageinfo-category-subcats' => 'Niver a isrummadoù',
+'pageinfo-category-files' => 'Niver a restroù',
 
 # Skin names
 'skinname-standard' => 'Standard',
@@ -3065,7 +3080,10 @@ Ma vez erounezet ganeoc'h e c'hallje tagañ ho reizhiad.",
 'minutes' => '{{PLURAL:$1|$1 vunutenn|$1 munutenn}}',
 'hours' => '{{PLURAL:$1|$1 eurvezh|$1 eurvezh}}',
 'days' => '{{PLURAL:$1|$1 deiz|$1 deiz}}',
+'months' => '{{PLURAL: $1|$1 miz|$1 miz}}',
+'years' => '{{PLURAL: $1|$1 bloaz|$1 bloaz}}',
 'ago' => '$1 zo',
+'just-now' => 'bremañ diouzhtu',
 
 # Bad image list
 'bad_image_list' => "Setu doare ar furmad :
@@ -3561,6 +3579,7 @@ Mont a raio ar c'hod-mañ d'e dermen d'ar \$4.",
 # Scary transclusion
 'scarytranscludedisabled' => '[Diweredekaet eo an treuzkludañ etrewiki]',
 'scarytranscludefailed' => "[N'eus ket bet gallet tapout ar patrom evit $1]",
+'scarytranscludefailed-httpstatus' => "[c'hwitet adtapout ar patrom evit $1: HTTP $2]",
 'scarytranscludetoolong' => '[URL re hir]',
 
 # Delete conflict
@@ -3833,7 +3852,6 @@ Diskouezet eo ar skeudennoù gant ur pizhder uhel, erounit a ra ar restroù all
 'logentry-newusers-create' => 'Krouet eo bet ar gont implijer $1',
 'logentry-newusers-create2' => 'Gant $1 eo bet krouet ar gont implijer $3',
 'logentry-newusers-autocreate' => 'Krouet eo bet kont $1 ent emgefre',
-'newuserlog-byemail' => 'ger-tremen kaset dre bostel',
 'rightsnone' => '(netra)',
 
 # Feedback
index eff8e5f..b41c354 100644 (file)
@@ -396,7 +396,7 @@ $messages = array(
 'category-empty' => "''Ova kategorija trenutno ne sadrži članke ni medije.''",
 'hidden-categories' => '{{PLURAL:$1|Sakrivena kategorija|Sakrivene kategorije}}',
 'hidden-category-category' => 'Sakrivene kategorije',
-'category-subcat-count' => '{{PLURAL:$2|Ova kategorija ima sljedeću $1 podkategoriju.|Ova kategorija ima {{PLURAL:$1|sljedeće podkategorije|sljedećih $1 podkategorija}}, od $2 ukupno.}}',
+'category-subcat-count' => '{{PLURAL:$2|Ova kategorija ima sljedeću podkategoriju.|Ova kategorija ima {{PLURAL:$1|sljedeće podkategorije|sljedećih $1 podkategorija}}, od $2 ukupno.}}',
 'category-subcat-count-limited' => 'Ova kategorija sadrži {{PLURAL:$1|slijedeću $1 podkategoriju|slijedeće $1 podkategorije|slijedećih $1 podkategorija}}.',
 'category-article-count' => '{{PLURAL:$2|U ovoj kategoriji se nalazi $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-limited' => '{{PLURAL:$1|Slijedeća $1 stranica je|Slijedeće $1 stranice su|Slijedećih $1 stranica je}} u ovoj kategoriji.',
@@ -671,6 +671,7 @@ $2',
 'ns-specialprotected' => 'Specijalne stranice se ne mogu uređivati.',
 'titleprotected' => 'Naslov stranice je zaštićen od postavljanja od strane korisnika [[User:$1|$1]].
 Iz razloga "\'\'$2\'\'".',
+'invalidtitle-knownnamespace' => 'Neispravan naslov s imenskim prostorom "$2" i tekstom "$3"',
 'exception-nologin' => 'Niste prijavljeni',
 'exception-nologin-text' => 'Ova stranica ili aktivnost zahtijeva da budete prijavljeni na ovom wikiju.',
 
@@ -846,6 +847,7 @@ Privremena šifra: $2',
 'changeemail-oldemail' => 'Trenutna e-mail adresa:',
 'changeemail-newemail' => 'Nova e-mail adresa:',
 'changeemail-none' => '(ništa)',
+'changeemail-password' => 'Tvoja šifra/lozinka za {{SITENAME}}:',
 'changeemail-submit' => 'Promijeni e-mail',
 'changeemail-cancel' => 'Otkaži',
 
@@ -1013,8 +1015,8 @@ Također nam garantujete da ste ovo Vi napisali, ili da ste ga kopirali iz javne
 '''NE ŠALJITE AUTORSKIM PRAVOM ZAŠTIĆENE TEKSTOVE BEZ DOZVOLE!'''",
 'longpageerror' => "'''Greška: Tekst, koji ste poslali, je dug {{PLURAL:$1|jedan kilobajt|$1 kilobajta}}, što je veće od maksimuma, koji iznosi {{PLURAL:$2|jedan kilobajt|$2 kilobajta}}.'''
 Stranica ne može biti sačuvana.",
-'readonlywarning' => "'''PAŽNJA: Baza je zaključana zbog održavanja, tako da nećete moći da sačuvate svoje izmjene za sada.
-Možda želite da kopirate i nalijepite tekst u tekst editor i sačuvate ga za kasnije.'''
+'readonlywarning' => "'''PAŽNJA: Baza je zaključana zbog održavanja, tako da nećete moći da sačuvate svoje izmjene za sada.'''
+Možda želite da kopirate i nalijepite tekst u tekst editor i sačuvate ga za kasnije.
 
 Administrator koji je zaključao bazu je naveo slijedeće objašnjenje: $1",
 'protectedpagewarning' => "'''PAŽNJA: Ova stranica je zaključana tako da samo korisnici sa administratorskim privilegijama mogu da je mijenjaju.'''
@@ -1216,7 +1218,9 @@ Molimo provjerite zapise.',
 'revdelete-only-restricted' => 'Greška pri sakrivanju stavke od dana $2, $1: ne možete ukloniti stavke od pregledavanja administratora bez da odaberete neku od drugih opcija za uklanjanje.',
 'revdelete-reason-dropdown' => '*Uobičajeni razlozi brisanja
 ** Kršenje autorskih prava
-** Neadekvatni lični podaci',
+** Neprikladan komentar ili lični podac
+** Neprikladno korisničko ime
+** Uvredljivi podaci',
 'revdelete-otherreason' => 'Ostali/dodatni razlog:',
 'revdelete-reasonotherlist' => 'Ostali razlozi',
 'revdelete-edit-reasonlist' => 'Uredi razloge brisanja',
@@ -1421,7 +1425,7 @@ Ovo se ne može vratiti unazad.',
 'youremail' => 'E-mail:',
 'username' => '{{GENDER:$1|Korisničko}} ime:',
 'uid' => '{{GENDER:$1|Korisnički}} ID:',
-'prefs-memberingroups' => 'Član {{PLURAL:$1|grupe|grupa}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Korisnik|Korisnica}} je član {{PLURAL:$1|grupe|grupâ}}:',
 'prefs-registration' => 'Vrijeme registracije:',
 'yourrealname' => 'Vaše pravo ime:',
 'yourlanguage' => 'Jezik:',
@@ -1820,10 +1824,24 @@ Ako se problem ne riješi, kontaktirajte [[Special:ListUsers/sysop|administrator
 'backend-fail-delete' => 'Ne može se izbrisati datoteka $1.',
 'backend-fail-alreadyexists' => 'Datoteka $1 već postoji.',
 'backend-fail-store' => 'Ne može se spremiti datoteka $1 na $2.',
+'backend-fail-copy' => 'Nije uspjelo kopiranje datoteke "$1" u "$2".',
+'backend-fail-move' => 'Nije uspjelo premještanje datoteke "$1" u "$2".',
+'backend-fail-opentemp' => 'Ne mogu otvoriti privremenu datoteku.',
+'backend-fail-writetemp' => 'Ne mogu pisati u privremenu datoteku.',
+'backend-fail-closetemp' => 'Ne mogu zatvoriti privremenu datoteku.',
 'backend-fail-read' => 'Ne mogu čitati datoteku $1.',
 'backend-fail-create' => 'Ne mogu napraviti datoteku $1.',
+'backend-fail-contenttype' => 'Ne mogu da utvrdim kakav sadržaj ima datoteka koju treba da smjestim u "$1".',
 
 # Lock manager
+'lockmanager-notlocked' => 'Ne mogu otključati "$1"; nije zaključan.',
+'lockmanager-fail-closelock' => 'Ne mogu zatvoriti "lock"-datoteku za "$1".',
+'lockmanager-fail-deletelock' => 'Ne mogu obrisati "lock"-datoteku za "$1".',
+'lockmanager-fail-acquirelock' => 'Ne mogu dobiti "lock"-datoteku za "$1".',
+'lockmanager-fail-openlock' => 'Ne mogu otvoriti "lock"-datoteku za "$1".',
+'lockmanager-fail-releaselock' => 'Ne mogu osloboditi katanac za „$1“.',
+'lockmanager-fail-db-bucket' => 'Ne mogu da kontaktiram s dovoljno "lock"-baza u kanti $1.',
+'lockmanager-fail-db-release' => 'Ne mogu osloboditi katance u bazi $1.',
 'lockmanager-fail-svr-release' => 'Ne mogu se otključati katanci na serveru file $1.',
 
 # ZipDirectoryReader
@@ -1842,6 +1860,7 @@ Ne može se dobro provjeriti u vezi sigurnosti.',
 '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-refresh' => 'Osvježi spisak datoteka',
+'invalid-chunk-offset' => 'Neispravna polazna tačka',
 
 # img_auth script messages
 'img-auth-accessdenied' => 'Pristup onemogućen',
@@ -2019,9 +2038,9 @@ Prije brisanja provjerite da li druge stranice vode na te šablone.',
 
 'disambiguations' => 'Stranice koje vode na čvor članke',
 'disambiguationspage' => '{{ns:template}}:Čvor',
-'disambiguations-text' => "Slijedeće stranice su povezane sa '''čvor stranicom'''.
-Po pravilu, one se trebaju povezati sa konkretnim člankom.<br />
-Stranica se smatra čvorom, ukoliko koristi šablon koji je povezan sa spiskom [[MediaWiki:Disambiguationspage|čvor stranica]]",
+'disambiguations-text' => "Slijedeće stranice sadrže najmanje jedan link na '''čvor stranicom'''.
+Umjesto toga, one se trebaju povezati sa konkretnim konkretnim stranicom.<br />
+Stranica se smatra čvorom, ukoliko koristi šablon koji je povezan sa spiskom [[MediaWiki:Disambiguationspage]]",
 
 'doubleredirects' => 'Dvostruka preusmjerenja',
 'doubleredirectstext' => 'Ova stranica prikazuje stranice koje preusmjeravaju na druga preusmjerenja.
@@ -2066,6 +2085,8 @@ Svaki red sadrži veze na prvo i drugo preusmjerenje, kao i na prvu liniju tekst
 'wantedpages' => 'Tražene stranice',
 'wantedpages-badtitle' => 'Nevaljan naslov u setu rezultata: $1',
 'wantedfiles' => 'Tražene datoteke',
+'wantedfiletext-cat' => 'Sljedeće datoteke se koriste, ali ne postoje. Datoteke iz drugih baza mogu biti navedene iako ne postoje. Takve datoteke će biti <del>izbrisane</del> sa spiska. Pored toga, stranice koje sadrže nepostojeće datoteke se nalaze u [[:$1]].',
+'wantedfiletext-nocat' => 'Sljedeće datoteke se koriste, ali ne postoje. Datoteke iz drugih baza mogu biti navedene iako ne postoje. Takve datoteke će biti <del>izbrisane</del> sa spiska.',
 'wantedtemplates' => 'Potrebni šabloni',
 'mostlinked' => 'Članci sa najviše linkova',
 'mostlinkedcategories' => 'Kategorije sa najviše linkova',
@@ -2217,7 +2238,7 @@ da biste slali e-poštu drugim korisnicima.',
 'emailuser-title-target' => 'Pošalji e-poruku {{GENDER:$1|korisniku|korisnici|korisniku}}',
 'emailuser-title-notarget' => 'Pošalji e-mail korisniku',
 'emailpage' => 'Pošalji e-mail korisniku',
-'emailpagetext' => 'Možete korisiti formu ispod za slanje e-mail poruka ovom korisniku.
+'emailpagetext' => 'Možete korisiti formu ispod za slanje e-mail poruka {{GENDER:$1|ovom korisniku|ovoj korisnici|ovom korisniku}}.
 E-mail adresa koju ste unijeli u [[Special:Preferences|Vašim korisničkim postavkama]] će biti prikazana kao adresa pošiljaoca, tako da će primaoc poruke moći da Vam odgovori.',
 'usermailererror' => 'Objekat pošte je vratio grešku:',
 'defemailsubject' => '{{SITENAME}} e-pošta od {{GENDER:$1|korisnika|korisnice|korisnika}} $1',
@@ -2248,7 +2269,7 @@ E-mail adresa koju ste unijeli u [[Special:Preferences|Vašim korisničkim posta
 'usermessage-editor' => 'Sistem za poruke',
 
 # Watchlist
-'watchlist' => 'Moji praćeni članci',
+'watchlist' => 'Praćeni članci',
 'mywatchlist' => 'Praćeni članci',
 'watchlistfor2' => 'Za $1 $2',
 'nowatchlist' => 'Nemate ništa na svom spisku praćenih članaka.',
@@ -2256,9 +2277,8 @@ E-mail adresa koju ste unijeli u [[Special:Preferences|Vašim korisničkim posta
 'watchnologin' => 'Niste prijavljeni',
 'watchnologintext' => 'Morate biti [[Special:UserLogin|prijavljeni]] da bi ste mijenjali spisak praćenih članaka.',
 'addwatch' => 'Dodaj na spisak praćenja',
-'addedwatchtext' => 'Stranica "[[:$1]]" je dodata vašem [[Special:Watchlist|spisku praćenih članaka]]. Buduće promjene ove stranice i njoj pridružene stranice za razgovor će biti navedene ovde, i stranica će biti <b>podebljana</b> u [[Special:RecentChanges|spisku]] nedavnih izmjena da bi se lakše uočila.
-
-Ako kasnije želite da uklonite stranicu sa vašeg spiska praćenih članaka, kliknite na "prekini praćenje" na paleti.',
+'addedwatchtext' => 'Stranica "[[:$1]]" je dodata vašem [[Special:Watchlist|spisku praćenih članaka]]. 
+Buduće promjene ove stranice i njoj pridružene stranice za razgovor će biti navedene ovde.',
 'removewatch' => 'Ukloni sa spiska praćenja',
 'removedwatchtext' => 'Stranica "[[:$1]]" je uklonjena iz [[Special:Watchlist|vašeg spiska praćenih članaka]].',
 'watch' => 'Prati članak',
@@ -2287,26 +2307,32 @@ Ako kasnije želite da uklonite stranicu sa vašeg spiska praćenih članaka, kl
 'enotif_mailer' => '{{SITENAME}} obaviještenje o pošti',
 'enotif_reset' => 'Označi sve strane kao posjećene',
 'enotif_impersonal_salutation' => '{{SITENAME}} korisnik',
+'enotif_subject_deleted' => '{{gender:$2|Korisnik|Korisnica}} $2 je {{gender:$2|obrisao|obrisala}} stranicu $1 projekta {{SITENAME}}',
+'enotif_subject_created' => '{{gender:$2|Korisnik|Korisnica}} $2 je {{gender:$2|napravio|napravila}} stranicu $1 projekta {{SITENAME}}',
+'enotif_subject_moved' => '{{gender:$2|Korisnik|Korisnica}} $2 je {{gender:$2|premjestio|premjestila}} stranicu $1 projekta {{SITENAME}}',
+'enotif_subject_restored' => '{{gender:$2|Korisnik|Korisnica}} $2 je {{gender:$2|vratio|vratila}} stranicu $1 projekta {{SITENAME}}',
+'enotif_subject_changed' => '{{gender:$2|Korisnik|Korisnica}} $2 je {{gender:$2|promijenio|promijenila}} stranicu $1 projekta {{SITENAME}}',
+'enotif_body_intro_deleted' => 'Stranicu $1 projekta {{SITENAME}} {{GENDER:$2|obrisao|obrisala}} je dana $PAGEEDITDATE {{GENDER:$2|korisnik|korisnica}} $2, pogledajte $3.',
+'enotif_body_intro_created' => 'Stranicu $1 projekta {{SITENAME}} {{GENDER:$2|napravio|napravila}} je dana $PAGEEDITDATE {{GENDER:$2|korisnik|korisnica}} $2, pogledajte $3 za trenutnu verziju.',
+'enotif_body_intro_moved' => 'Stranicu $1 projekta {{SITENAME}} {{GENDER:$2|premjestio|premjestila}} je dana $PAGEEDITDATE {{GENDER:$2|korisnik|korisnica}} $2, pogledajte $3 za trenutnu verziju.',
+'enotif_body_intro_restored' => 'Stranicu $1 projekta {{SITENAME}} {{GENDER:$2|vratio|vratila}} je dana $PAGEEDITDATE {{GENDER:$2|korisnik|korisnica}} $2, pogledajte $3 za trenutnu verziju.',
+'enotif_body_intro_changed' => 'Stranicu $1 projekta {{SITENAME}} {{GENDER:$2|promijenio|promijenila}} je dana $PAGEEDITDATE {{GENDER:$2|korisnik|korisnica}} $2, pogledajte $3 za trenutnu verziju.',
 'enotif_lastvisited' => 'Pogledajte $1 za sve izmjene od vaše posljednje posjete.',
 'enotif_lastdiff' => 'Vidi $1 da pregledate ovu promjenu.',
 'enotif_anon_editor' => 'anonimni korisnik $1',
 'enotif_body' => 'Poštovani $WATCHINGUSERNAME,
 
-
-Stranica {{SITENAME}} sa naslovom $PAGETITLE je bila $CHANGEDORCREATED dana $PAGEEDITDATE od strane $PAGEEDITOR, pogledajte $PAGETITLE_URL za trenutnu reviziju.
-
-$NEWPAGE
+$PAGEINTRO $NEWPAGE
 
 Sažetak urednika: $PAGESUMMARY $PAGEMINOREDIT
 
 Kontaktirajte urednika:
-mail: $PAGEEDITOR_EMAIL
+e-pošta: $PAGEEDITOR_EMAIL
 wiki: $PAGEEDITOR_WIKI
 
-Neće biti drugih obavještenja u slučaju daljnjih izmjena osima ako posjetite stranicu.
-Također možete poništiti oznake obavijesti za sve praćene stranice koje imate na vašem spisku praćenja.
+Neće biti drugih obavještenja u slučaju daljnjih izmjena osima ako posjetite stranicu. Također možete poništiti oznake obavijesti za sve praćene stranice koje imate na vašem spisku praćenja.
 
-             Vaš prijateljski {{SITENAME}} sistem obavještavanja
+Vaš prijateljski {{SITENAME}} sistem obavještavanja
 
 --
 Za promjenu vaših postavki e-mail obavijesti, posjetite
@@ -2389,6 +2415,8 @@ Pogledajte [[Special:ProtectedPages|spisak zaštićenih stranica]] za pregled tr
 'protect-title' => 'Zaštićuje se "$1"',
 'protect-title-notallowed' => 'Pregled stepena zaštite za "$1"',
 'prot_1movedto2' => 'članak [[$1]] premješten na [[$2]]',
+'protect-badnamespace-title' => 'Nezaštitljiv imenski prostor',
+'protect-badnamespace-text' => 'Stranice u ovom imenskom prostoru se ne mogu zaštititi.',
 'protect-legend' => 'Potvrdite zaštitu',
 'protectcomment' => 'Razlog:',
 'protectexpiry' => 'Ističe:',
@@ -2407,7 +2435,7 @@ Možete promijeniti stepen zaštite ove stranice, ali to neće uticati na prenos
 'protect-default' => 'Dopusti svim korisnicima',
 'protect-fallback' => 'Potrebno je imati "$1" ovlasti',
 'protect-level-autoconfirmed' => 'Blokiraj nove i neregistrovane korisnike',
-'protect-level-sysop' => 'Samo administratori',
+'protect-level-sysop' => 'Dozvoli samo administratorima',
 'protect-summary-cascade' => 'prenosna zaštita',
 'protect-expiring' => 'ističe $1 (UTC)',
 'protect-expiring-local' => 'ističe $1',
@@ -2609,6 +2637,7 @@ ili korisničkom imenu.',
 'blocklist-userblocks' => 'Sakrij blokade računa',
 'blocklist-tempblocks' => 'Sakrij privremene blokade',
 'blocklist-addressblocks' => 'Sakrij pojedinačne IP blokade',
+'blocklist-rangeblocks' => 'Sakrij blokiranja opsega',
 'blocklist-timestamp' => 'Vremenska oznaka',
 'blocklist-target' => 'Cilj',
 'blocklist-expiry' => 'Ističe',
@@ -2706,23 +2735,18 @@ Ako želite otključati ili zaključati bazu, ova datoteka mora biti omogućena
 # Move page
 'move-page' => 'Pomjeranje $1',
 'move-page-legend' => 'Premjestite stranicu',
-'movepagetext' => "Korištenjem ovog formulara možete preusmjeriti članak
-zajedno sa stranicom za diskusiju tog članka.
+'movepagetext' => "Korištenjem ovog formulara možete preimenovati stranicu, premještajući cijelu historiju na novo ime.
+Članak pod starim imenom će postati stranica koja preusmjerava na članak pod novim imenom. 
+Možete automatski izmjeniti preusmjerenje do izvornog naslova.
+Ako se ne odlučite na to, provjerite [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|neispravna preusmjeravanja]].
+Dužni ste provjeriti da svi linkovi i dalje nastave voditi na prave stranice.
 
-Članak pod starim imenom će postati stranica koja preusmjerava
-na članak pod novim imenom. Linkovi koji vode na članak sa
-starim imenom neće biti preusmjereni. Vaša je dužnost da se
-pobrinete da svi linkovi koji vode na članak sa starim imenom
-budu adekvatno preusmjereni (stranica posebne namjene za
-održavanje je korisna za obavještenje o [[Special:BrokenRedirects|mrtvim]] i [[Special:DoubleRedirects|duplim]] preusmjerenjima).
-
-Imajte na umu da članak '''neće''' biti preusmjeren ukoliko
-već postoji članak pod imenom na koje namjeravate da
-preusmjerite.
+Imajte na umu da članak '''neće''' biti preusmjeren ukoliko već postoji članak pod imenom na koje namjeravate da preusmjerite osim u slučaju stranice za preusmjeravanje koja nema nikakvih starih izmjena.
+To znači da možete vratiti stranicu na prethodno mjesto ako pogriješite, ali ne možete zamijeniti postojeću stranicu.
 
 '''Pažnja!'''
-Imajte na umu da preusmjeravanje popularnog članka može biti
-drastična i neočekivana promjena za korisnike.",
+Ovo može biti drastična i neočekivana promjena kad su u pitanju popularne stranice;
+Molimo dobro razmislite prije nego što preimenujete stranicu.",
 'movepagetext-noredirectfixer' => "Koristeći obrazac ispod ćete preimenovati stranicu i premjestiti cijelu njenu historiju na novi naziv.
 Stari naziv će postati preusmjerenje na novi naziv.
 Molimo provjerite da li postoje [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|nedovršena preusmjerenja]].
@@ -2847,6 +2871,7 @@ Molimo posjetite [//www.mediawiki.org/wiki/Localisation MediaWiki lokalizaciju]
 'djvu_page_error' => 'DjVu stranica je van opsega',
 'djvu_no_xml' => 'Za XML-datoteku se ne može pozvati DjVu datoteka',
 'thumbnail-temp-create' => 'Ne mogu da napravim privremenu smanjenu sliku',
+'thumbnail-dest-create' => 'Ne mogu da sačuvam smanjenu sliku ("thumbnail") na destinaciju',
 'thumbnail_invalid_params' => 'Pogrešne postavke smanjenog prikaza',
 'thumbnail_dest_directory' => 'Ne može se napraviti odredišni folder',
 'thumbnail_image-type' => 'Tip slike nije podržan',
@@ -2894,6 +2919,11 @@ Nedostaje privremeni folder.',
 'import-upload' => 'Postavljanje XML podataka',
 'import-token-mismatch' => 'Izgubljeni podaci sesije. Molimo pokušajte ponovno.',
 'import-invalid-interwiki' => 'Ne može se uvesti iz navedenog wikija.',
+'import-error-edit' => 'Stranica "$1" nije uvezena jer vam nije dopušteno da je uređujete.',
+'import-error-create' => 'Stranica "$1" nije uvezena jer vam nije dozvoljeno da je napravite.',
+'import-error-interwiki' => 'Stranica "$1" nije uvezena jer je njen naziv rezerviran za vanjsko povezivanje (interwiki).',
+'import-error-special' => 'Stranica "$1" nije uvezena jer pripada posebnom imenskom prostoru koje ne prihvata stranice.',
+'import-error-invalid' => 'Stranica "$1" nije uvezena jer je njen naziv neispravan.',
 'import-options-wrong' => '{{PLURAL:$2|Pogrešna opcija|Pogrešne opcije}}: <nowiki>$1</nowiki>',
 
 # Import log
@@ -3044,7 +3074,7 @@ Ovo je vjerovatno izazvao vezom ka vanjskoj nepoželjnoj stranici.',
 'pageinfo-article-id' => 'ID stranice',
 'pageinfo-language' => 'Jezik sadržaja stranice',
 'pageinfo-views' => 'Broj pogleda',
-'pageinfo-watchers' => 'Broj onih koji pregledaju',
+'pageinfo-watchers' => 'Broj pratitelja stranice',
 'pageinfo-redirects-name' => 'Preusmjeravanja na ovu stranicu',
 'pageinfo-subpages-name' => 'Podstranice ove stranice',
 'pageinfo-firstuser' => 'Korisnik koji je napravio stranicu',
@@ -3858,7 +3888,7 @@ Slike su prikazane u punoj veličini, ostale vrste datoteka su prikazane direktn
 'specialpages-group-highuse' => 'Najčešće korištene stranice',
 'specialpages-group-pages' => 'Spiskovi stranica',
 'specialpages-group-pagetools' => 'Alati stranice',
-'specialpages-group-wiki' => 'Wiki podaci i alati',
+'specialpages-group-wiki' => 'Podaci i alati',
 'specialpages-group-redirects' => 'Preusmjeravanje posebnih stranica',
 'specialpages-group-spam' => 'Alati za spam',
 
@@ -3899,6 +3929,7 @@ Slike su prikazane u punoj veličini, ostale vrste datoteka su prikazane direktn
 'compare-submit' => 'Usporedi',
 'compare-invalid-title' => 'Naslov koji ste unijeli je nevaljan.',
 'compare-title-not-exists' => 'Naslov koji ste naveli ne postoji.',
+'compare-revision-not-exists' => 'Izmjena koji ste naveli ne postoji.',
 
 # Database error messages
 'dberr-header' => 'Ovaj wiki ima problem',
@@ -3928,6 +3959,15 @@ Slike su prikazane u punoj veličini, ostale vrste datoteka su prikazane direktn
 # New logging system
 'logentry-delete-delete' => '$1 je obrisao stranicu $3',
 'logentry-delete-restore' => '$1 je vratio stranicu $3',
+'logentry-delete-event' => '$1 je {{GENDER:|promijenio|promijenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u evidenciji na $3: $4',
+'logentry-delete-revision' => '$1 je {{GENDER:|promijenio|promijenila}} vidljivost {{PLURAL:$5|izmjene|$5 izmjene|$5 izmjena}} na stranici  $3: $4',
+'logentry-delete-event-legacy' => '$1 je {{GENDER:|promijenio|promijenila}} vidljivost događaja u evidenciji na $3',
+'logentry-delete-revision-legacy' => '$1 je {{GENDER:|promijenio|promijenila}} vidljivost izmjena na stranici $3',
+'logentry-suppress-delete' => '$1 {{GENDER:|je potisnuo|je potisnula}} stranicu $3',
+'logentry-suppress-event' => '$1 je tajno {{GENDER:|promijenio|promijenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u evidenciji na $3: $4',
+'logentry-suppress-revision' => '$1 je tajno {{GENDER:|promijenio|promijenila}} vidljivost {{PLURAL:$5|izmjene|$5 izmjene|$5 izmjena}} na stranici  $3: $4',
+'logentry-suppress-event-legacy' => '$1 je tajno {{GENDER:|promijenio|promijenila}} vidljivost događaja u evidenciji na $3',
+'logentry-suppress-revision-legacy' => '$1 je tajno {{GENDER:|promijenio|promijenila}} vidljivost izmjena na stranici $3',
 'revdelete-content-hid' => 'skriveni sadržaj',
 'revdelete-summary-hid' => 'sažetak izmjene je sakriven',
 'revdelete-uname-hid' => 'sažetak izmjene je sakriven',
@@ -3945,8 +3985,8 @@ Slike su prikazane u punoj veličini, ostale vrste datoteka su prikazane direktn
 'logentry-newusers-newusers' => 'Korisnički račun $1 je napravljen',
 'logentry-newusers-create' => 'Korisnički račun $1 je napravljen',
 'logentry-newusers-create2' => '$3 je {{GENDER:$2|napravio|napravila}} korisnički račun $1',
+'logentry-newusers-byemail' => 'Korisnički račun $3 je napravio $1 i lozinka/šifra je poslana putem e-maila',
 'logentry-newusers-autocreate' => 'Korisnički račun $1 je automatski napravljen',
-'newuserlog-byemail' => 'šifra je poslana putem e-maila',
 'logentry-rights-rights' => '$1 {{GENDER:$1|je promijenio|je promijenila|je promijenio}} članstvo grupe za $3 iz $4 u $5',
 'logentry-rights-rights-legacy' => '$1 je {{GENDER:$2|promijenio|promijenila|promijenio}} članstvo grupe za $3',
 'logentry-rights-autopromote' => 'Korisničkom računu $1 {{GENDER:$1|je automatski promijenjeno članstvo|su automatski promijenjena članstva}} iz $4 u $5',
@@ -3984,10 +4024,11 @@ Inače, možete ispuniti jednostavan obrazac ispod. Vaš komentar biti će dodan
 'api-error-emptypage' => 'Stvaranje novih praznih stranica nije dozvoljeno.',
 'api-error-fetchfileerror' => 'Unutrašnja greška: pojavio se neki problem pri dobijanju podataka o datoteci.',
 'api-error-fileexists-forbidden' => 'Datoteka s imenom "$1" već postoji, i ne može biti zamijenjena.',
+'api-error-fileexists-shared-forbidden' => 'Datoteka s imenom "$1" već postoji u zajedničkom spremištu i ne može biti prepisana.',
 'api-error-file-too-large' => 'Datoteka koju ste poslali je bila prevelika.',
 'api-error-filename-tooshort' => 'Ime datoteke je prekratko.',
 'api-error-filetype-banned' => 'Ova vrsta datoteke je zabranjena.',
-'api-error-filetype-banned-type' => '$1 nije dopuštena vrsta datoteke. {{PLURAL:$3|Dopuštena vrsta datoteke je|Dopuštene vrste datoteka su}} $2.',
+'api-error-filetype-banned-type' => '$1 {{PLURAL:$4|nije dopušteni vrsta datoteke|su nedopušteni vrste datoteke|su nedopušteni vrste datoteka}}. {{PLURAL:$3|Dopuštena vrsta datoteke je|Dopuštene vrste datoteka su}} $2.',
 'api-error-filetype-missing' => 'Datoteci nedostaje nastavak.',
 'api-error-hookaborted' => 'Izmjena koji ste pokušali načiniti je obustavljena preko kuke proširenja.',
 'api-error-http' => 'Unutrašnja greška: ne može se spojiti na server.',
@@ -4003,6 +4044,7 @@ Inače, možete ispuniti jednostavan obrazac ispod. Vaš komentar biti će dodan
 'api-error-ok-but-empty' => 'Unutrašnja greška: nema odgovora od servera.',
 'api-error-overwrite' => 'Pisanje preko postojeće datoteke nije dopušteno.',
 'api-error-stashfailed' => 'Unutrašnja greška: server nije mogao da spremi privremenu datoteku.',
+'api-error-publishfailed' => 'Unutrašnja greška: Server nije uspio objaviti privremenu datoteku.',
 'api-error-timeout' => 'Server nije odgovorio unutar očekivanog vremena.',
 'api-error-unclassified' => 'Desila se nepoznata greška',
 'api-error-unknown-code' => 'Nepoznata greška: "$1"',
@@ -4014,7 +4056,7 @@ Inače, možete ispuniti jednostavan obrazac ispod. Vaš komentar biti će dodan
 
 # Durations
 'duration-seconds' => '$1 {{PLURAL:$1|sekunda|sekunde}}',
-'duration-minutes' => '$1 {{PLURAL:$1|minut|minuta|minuta}}',
+'duration-minutes' => '$1 {{PLURAL:$1|minut|minute|minuta}}',
 'duration-hours' => '$1 {{PLURAL:$1|sat|sata|sati}}',
 'duration-days' => '$1 {{PLURAL:$1|dan|dana}}',
 'duration-weeks' => '$1 {{PLURAL:$1|sedmica|sedmice|sedmica}}',
index cdd3c93..44f7c31 100644 (file)
@@ -229,7 +229,7 @@ $messages = array(
 'tog-externaldiff' => "Utilitza per defecte un altre visualitzador de diferències (opció per a experts, requereix la configuració adient de l'ordinador, [//www.mediawiki.org/wiki/Manual:External_editors consulteu-ho al manual])",
 'tog-showjumplinks' => "Habilita els enllaços de dreceres d'accessibilitat",
 'tog-uselivepreview' => 'Utilitza la previsualització automàtica (cal JavaScript) (experimental)',
-'tog-forceeditsummary' => "Avisa'm en introduir un camp de resum en blanc",
+'tog-forceeditsummary' => "Avisa'm en deixar el resum de la modificació en blanc",
 'tog-watchlisthideown' => 'Amaga les meues edicions de la llista de seguiment',
 'tog-watchlisthidebots' => 'Amaga de la llista de seguiment les edicions fetes per usuaris bots',
 'tog-watchlisthideminor' => 'Amaga les edicions menors de la llista de seguiment',
@@ -1373,15 +1373,15 @@ Ha de tenir com a molt {{PLURAL:$1|un caràcter|$1 caràcters}}.',
 'userrights-lookup-user' => "Gestiona els grups d'usuari",
 'userrights-user-editname' => "Introduïu un nom d'usuari:",
 'editusergroup' => "Edita els grups d'usuaris",
-'editinguser' => "S'està canviant els permisos de l'usuari '''[[User:$1|$1]]''' $2",
+'editinguser' => "Modificació dels permisos de {{GENDER:$1|l’usuari|la usuària}} '''[[User:$1|$1]]''' $2",
 'userrights-editusergroup' => "Edita els grups d'usuaris",
 'saveusergroups' => "Desa els grups d'usuari",
 'userrights-groupsmember' => 'Membre de:',
 'userrights-groupsmember-auto' => 'Membre implícit de:',
-'userrights-groups-help' => "Podeu modificar els grups als quals pertany aquest usuari.
-* Els requadres marcats indiquen que l'usuari és dins del grup.
-* Els requadres sense marcar indiquen que l'usuari no hi pertany.
-* Un asterisc (*) indica que no el podreu treure del grup una vegada l'hàgiu afegit o viceversa.",
+'userrights-groups-help' => "Podeu modificar els grups als quals pertany {{GENDER:$1|aquest usuari|aquesta usuària}}.
+* Una casella marcada significa que {{GENDER:$1|l’usuari|la usuària}} pertany a aquest grup.
+* Una casella no marcada significa que {{GENDER:$1|l’usuari|la usuària}} no pertany a aquest grup.
+* Un asterisc (*) indica que no {{GENDER:$1|el|la}} podreu treure del grup una vegada l'hàgiu afegit o viceversa.",
 'userrights-reason' => 'Motiu:',
 'userrights-no-interwiki' => "No teniu permisos per a editar els permisos d'usuari d'altres wikis.",
 'userrights-nodatabase' => 'La base de dades $1 no existeix o no és local.',
@@ -2132,7 +2132,7 @@ i tenir una direcció electrònica vàlida en les vostres [[Special:Preferences|
 per enviar un correu electrònic a altres usuaris.",
 'emailuser' => 'Envia un missatge de correu electrònic a aquest usuari',
 'emailuser-title-target' => 'Enviar un correu electrònic a {{GENDER:$1|aquest usuari|aquesta usuària}}',
-'emailuser-title-notarget' => "Enviar un correu electrònic a l'usuari",
+'emailuser-title-notarget' => 'Enviar un correu electrònic a un usuari',
 'emailpage' => 'Correu electrònic a usuari',
 'emailpagetext' => "Podeu usar el següent formulari per a enviar un missatge de correu electrònic a {{GENDER:$1|aquest usuari|aquesta usuària}}.
 L'adreça electrònica que vau indicar a [[Special:Preferences|les vostres preferències d'usuari]] apareixerà com a remitent del correu electrònic, de manera que el destinatari us podrà respondre directament.",
@@ -2500,8 +2500,8 @@ quines pàgines en concret estan sent vandalitzades).",
 ** Abús de comptes d'usuari múltiples
 ** Nom d'usuari no acceptable",
 'ipb-hardblock' => "Impedeix que els usuaris registrats puguin editar des d'aquesta adreça IP",
-'ipbcreateaccount' => 'Evita la creació de comptes',
-'ipbemailban' => "Evita que l'usuari enviï correu electrònic",
+'ipbcreateaccount' => 'Impedeix la creació de comptes',
+'ipbemailban' => "Impedeix que l'usuari enviï correus electrònics",
 'ipbenableautoblock' => "Bloca l'adreça IP d'aquest usuari, i totes les subseqüents adreces des de les quals intenti registrar-se",
 'ipbsubmit' => 'Bloqueja aquesta adreça',
 'ipbother' => 'Un altre termini',
@@ -2772,7 +2772,7 @@ En el darrer cas, podeu fer servir un enllaç com ara [[{{#Special:Export}}/{{Me
 'thumbnail_image-missing' => 'Sembla que falta el fitxer: $1',
 
 # Special:Import
-'import' => 'Importa les pàgines',
+'import' => 'Importació de pàgines',
 'importinterwiki' => 'Importa interwiki',
 'import-interwiki-text' => "Trieu un web basat en wiki i un títol de pàgina per a importar.
 Es conservaran les dates de les versions i els noms dels editors.
@@ -2796,7 +2796,7 @@ Deseu-lo al vostre ordinador i carregueu-ne una còpia ací.",
 'importcantopen' => "No ha estat possible d'obrir el fitxer a importar",
 'importbadinterwiki' => "Enllaç d'interwiki incorrecte",
 'importnotext' => 'Buit o sense text',
-'importsuccess' => "S'ha acabat d'importar.",
+'importsuccess' => 'Importació completada!',
 'importhistoryconflict' => "Hi ha un conflicte de versions en l'historial (la pàgina podria haver sigut importada abans)",
 'importnosources' => "No s'ha definit cap font d'origen interwiki i s'ha inhabilitat la càrrega directa d'una còpia de l'historial",
 'importnofile' => "No s'ha pujat cap fitxer d'importació.",
@@ -2883,7 +2883,7 @@ Deseu-lo al vostre ordinador i carregueu-ne una còpia ací.",
 'tooltip-t-print' => "Versió per a impressió d'aquesta pàgina",
 'tooltip-t-permalink' => 'Enllaç permanent a aquesta versió de la pàgina',
 'tooltip-ca-nstab-main' => 'Vegeu el contingut de la pàgina.',
-'tooltip-ca-nstab-user' => "Vegeu la pàgina de l'usuari.",
+'tooltip-ca-nstab-user' => "Vegeu la pàgina d'usuari",
 'tooltip-ca-nstab-media' => "Vegeu la pàgina de l'element multimèdia",
 'tooltip-ca-nstab-special' => 'Aquesta és una pàgina especial, no podeu modificar-la',
 'tooltip-ca-nstab-project' => 'Vegeu la pàgina del projecte',
@@ -3819,7 +3819,6 @@ Les imatges es mostren en plena resolució; altres tipus de fitxer s'inicien dir
 'logentry-newusers-create' => "S'ha creat el compte d'usuari $1",
 'logentry-newusers-create2' => "$1 ha creat el compte d'usuari $3",
 'logentry-newusers-autocreate' => "El compte d'usuari $1 ha estat creat de manera automàtica",
-'newuserlog-byemail' => 'contrasenya enviada per correu electrònic',
 'logentry-rights-rights' => '$1 ha canviat la pertinença de grups per $3 de $4 a $5',
 'logentry-rights-rights-legacy' => '$1 ha canviat la pertinença de grups per $3',
 'logentry-rights-autopromote' => '$1 ha estat promogut automàticament de $4 a $5',
index 96ead71..b01dfc1 100644 (file)
@@ -1248,7 +1248,6 @@ Ang uban default nga nakatago.
 # New logging system
 'revdelete-restricted' => 'mga na-aplay nga restriksyon sa mga tagdumala',
 'revdelete-unrestricted' => 'gitangtang ang mga restriksyon alang sa mga tagdumala',
-'newuserlog-byemail' => "ang pasword gipadala na pinaagi sa ''e-mail''",
 'rightsnone' => '(wala)',
 
 );
index 256e83c..afcd744 100644 (file)
@@ -844,7 +844,7 @@ $2
 'creating' => 'دروستکردنی $1',
 'editingsection' => 'دەستکاریکردنی: $1 (بەش)',
 'editingcomment' => 'دەستکاریکردنی $1 (بەشی  نوێ)',
-'editconflict' => 'دەستکاری کێشە : $1',
+'editconflict' => 'کێشەی دەستکاری: $1',
 'explainconflict' => "کەسێکی تر ئەم پەڕەیە گۆڕیوە لەو کاتەوە تۆ دەستکاریکردنیت دەستپێکردووە.
 بەشی سەرەوەی دەق، شێوازی ئێستای پەڕەکە لە خۆ ئەگرێت.
 گۆڕانکاریەکانی تۆش لە بەشی خوارەوەی دەق نیشان‌دراوە.
@@ -1117,8 +1117,8 @@ $1",
 'diff-multi' => '({{PLURAL:$1|پیاچوونەوەیەکی نێوانی|$1 پیاچوونەوەی نێوانی}}ی {{PLURAL:$2|بەکارھێنەرێک|$2 بەکارھێنەر}} نیشان نەدراوە)',
 
 # Search results
-'searchresults' => 'ئەنجامەکانی گەڕان',
-'searchresults-title' => 'ئەنجامەکانی گەڕان بۆ "$1"',
+'searchresults' => 'ئاکامەکانی گەڕان',
+'searchresults-title' => 'ئاکامەکانی گەڕان بۆ «$1»',
 'searchresulttext' => 'بۆ زانیاری زیاتر دەربارەی گەڕان {{SITENAME}} ، بڕوانە لە  [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => "گەڕایت بۆ '''[[:$1]]''' ([[Special:Prefixindex/$1|ھەموو ئەو پەڕانەی بە «$1»ەوە دەستپێدەکەن]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|ھەموو ئەو پەڕانەی بەستەریان ھەیە بۆ «$1»]])",
 'searchsubtitleinvalid' => "گەڕایت بۆ '''$1'''",
@@ -1358,7 +1358,7 @@ $1",
 # Rights
 'right-read' => 'خوێندنەوەی پەڕەکان',
 'right-edit' => 'دەستکاری کردنی پەڕەکان',
-'right-createpage' => 'دروست کردنی پەڕەکان (کە پەڕەی لێدوان نین)',
+'right-createpage' => 'دروستکردنی پەڕەکان (کە پەڕەی وتووێژ نین)',
 'right-createtalk' => 'دروست کردنی پەڕەکانی لێدوان',
 'right-createaccount' => 'دروست کردنی ھەژماری بەکارھێنەریی نوێ',
 'right-minoredit' => 'بچووک دیاری کردنی گۆڕانکارییەکان',
@@ -1964,7 +1964,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'پێرستی بەکارھێنەرە چالاکەکان',
 'activeusers-intro' => 'ئەمە لیستێکی ئەو بەکارھێنەرانەیە کە لە  $1 {{PLURAL:$1|ڕۆژ|ڕۆژ}}ی ڕابردوودا بە جۆرێک چالاکییەکیان ھەبووە.',
-'activeusers-count' => '$1 گۆڕانکاری لە دوایین {{PLURAL:$3|ڕۆژدا|$3 ڕۆژدا}}',
+'activeusers-count' => '$1 {{PLURAL:$1|کردەوە}} لە دوایین {{PLURAL:$3|ڕۆژ|$3 ڕۆژ}}دا',
 'activeusers-from' => 'نیشاندانی بەکارھێنەران بە دەستپێکردن لە:',
 'activeusers-hidebots' => 'بۆتەکان بشارەوە',
 'activeusers-hidesysops' => 'بەڕێوبەران بشارەوە',
@@ -2024,7 +2024,7 @@ $1',
 'usermessage-editor' => 'پەیامنێری سیستەم',
 
 # Watchlist
-'watchlist' => 'پێرستی چاودێرییەکانم',
+'watchlist' => 'پێرستی چاودێری',
 'mywatchlist' => 'پێرستی چاودێری',
 'watchlistfor2' => 'بۆ $1 $2',
 'nowatchlist' => 'لە لیستی چاودێڕییەکانتدا ھیچ نیە.',
@@ -2115,7 +2115,7 @@ $UNWATCHURL
 'historywarning' => "'''وشیار بە:''' پەڕەیەک کە دەتەوێ بیسڕیتەوە مێژوویەکی ھەیە بە نزیکەی $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}وە:",
 'confirmdeletetext' => 'تۆ خەریکی پەڕەیەک بە ھەموو مێژووەکەیەوە دەسڕیتەو.
 تکایە پشتڕاستی بکەوە کە دەتەوێت ئەم کارە بکەی، لە ئاکامەکەی تێدەگەی، و ئەم کارە بە پێی [[{{MediaWiki:Policy-url}}|سیاسەتنامە]] ئەنجام دەدەی.',
-'actioncomplete' => 'کردەوە بە ئاکام گەیشت',
+'actioncomplete' => 'کردەوە بە ئاکام گەییشت',
 'actionfailed' => 'کردارەکە سەرنەکەوت',
 'deletedtext' => '«$1»  سڕایەوە.
 سەیری $2 بکە بۆ تۆمارێکی دوایین سڕینەوەکان.',
@@ -2188,7 +2188,7 @@ $UNWATCHURL
 'protect-default' => 'بە ھەموو بەکارھێنەران ڕێگە بدە',
 'protect-fallback' => 'پێویستی بە ئیزنی «$1» ھەیە',
 'protect-level-autoconfirmed' => 'بەکارھێنەرانی نوێ و تۆمارنەکراو ئاستەنگ بکە',
-'protect-level-sysop' => 'تەنھا بەڕێوەبەران',
+'protect-level-sysop' => 'تەنیا بەڕێوەبەران',
 'protect-summary-cascade' => 'تاڤگەیی',
 'protect-expiring' => 'بەسەردەچێ لە ڕێکەوتی $1 (UTC)',
 'protect-expiring-local' => 'بە سەر دەچێ لە $1',
@@ -3299,8 +3299,8 @@ $5
 # Hijri month names
 'hijri-calendar-m1' => 'موحەڕەم',
 'hijri-calendar-m2' => 'سەفەر',
-'hijri-calendar-m3' => 'ڕەبيع ئەلئەووەڵ',
-'hijri-calendar-m4' => 'ڕەبيع ئەسسانی',
+'hijri-calendar-m3' => 'ڕەبیعەلئەووەڵ',
+'hijri-calendar-m4' => 'ڕەبیعەلئاخیر',
 'hijri-calendar-m5' => 'جومادەلئەووەل',
 'hijri-calendar-m6' => 'جومادەسسانی',
 'hijri-calendar-m7' => 'ڕەجەب',
@@ -3376,7 +3376,7 @@ $5
 'specialpages-group-highuse' => 'پەڕە زۆر بەکار ھێنراوەکان',
 'specialpages-group-pages' => 'پێرستەکانی پەڕەکان',
 'specialpages-group-pagetools' => 'ئامرازەکانی پەڕە',
-'specialpages-group-wiki' => 'دراوەکان و ئامرازەکانی ویکی',
+'specialpages-group-wiki' => 'دراوەکان و ئامرازەکان',
 'specialpages-group-redirects' => 'پەڕە تایبەتەکانی رەوانکردنەوە',
 'specialpages-group-spam' => 'ئامرازەکانی سپەم',
 
@@ -3458,7 +3458,6 @@ $5
 'logentry-newusers-create' => 'ھەژماری بەکارھێنەریی $1 دروست کرا',
 'logentry-newusers-create2' => 'ھەژماری بەکارھێنەریی $3 لە لایەن $1 دروست کرا',
 'logentry-newusers-autocreate' => 'ھەژماری $1 بە شێوەی خۆگەڕ دروستکرا',
-'newuserlog-byemail' => 'تێپەڕوشە بە ئیمەیل نێردرا.',
 'rightsnone' => '(ھیچ)',
 
 # Feedback
index d8f0afd..f824e6f 100644 (file)
@@ -2099,9 +2099,6 @@ $5
 # HTML forms
 'htmlform-reset' => 'Денъишикликлерни кери ал',
 
-# New logging system
-'newuserlog-byemail' => 'пароль e-mail вастасынен йиберильген',
-
 # Search suggestions
 'searchsuggest-containing' => 'ичинде бу олгъан...',
 
index 26c99c1..4bc2ac1 100644 (file)
@@ -2093,9 +2093,6 @@ Bitirgen soñ "{{int:Watchlistedit-raw-submit}}" yazısına basıñız.
 # HTML forms
 'htmlform-reset' => 'Deñişikliklerni keri al',
 
-# New logging system
-'newuserlog-byemail' => 'parol e-mail vastasınen yiberilgen',
-
 # Search suggestions
 'searchsuggest-containing' => 'içinde bu olğan...',
 
index 62651d3..ce43c0b 100644 (file)
@@ -56,19 +56,19 @@ $namespaceNames = array(
 );
 
 $namespaceAliases = array(
-    'Uživatel_diskuse'      => NS_USER_TALK,      # old literal translation backward compatibility
-    'Uživatelka_diskuse'    => NS_USER_TALK,      # female complement to old literal translation style
-    '$1_diskuse'            => NS_PROJECT_TALK,   # old literal translation backward compatibility
-    'Soubor_diskuse'        => NS_FILE_TALK,      # old literal translation backward compatibility
-    'MediaWiki_diskuse'     => NS_MEDIAWIKI_TALK, # old literal translation backward compatibility
-    'Šablona_diskuse'       => NS_TEMPLATE_TALK,  # old literal translation backward compatibility
-    'Nápověda_diskuse'      => NS_HELP_TALK,      # old literal translation backward compatibility
-    'Kategorie_diskuse'     => NS_CATEGORY_TALK,  # old literal translation backward compatibility
+       'Uživatel_diskuse'      => NS_USER_TALK,      # old literal translation backward compatibility
+       'Uživatelka_diskuse'    => NS_USER_TALK,      # female complement to old literal translation style
+       '$1_diskuse'            => NS_PROJECT_TALK,   # old literal translation backward compatibility
+       'Soubor_diskuse'        => NS_FILE_TALK,      # old literal translation backward compatibility
+       'MediaWiki_diskuse'     => NS_MEDIAWIKI_TALK, # old literal translation backward compatibility
+       'Šablona_diskuse'       => NS_TEMPLATE_TALK,  # old literal translation backward compatibility
+       'Nápověda_diskuse'      => NS_HELP_TALK,      # old literal translation backward compatibility
+       'Kategorie_diskuse'     => NS_CATEGORY_TALK,  # old literal translation backward compatibility
 );
 
 $namespaceGenderAliases = array(
-    NS_USER      => array( 'male' => 'Uživatel', 'female' => 'Uživatelka' ),
-    NS_USER_TALK => array( 'male' => 'Diskuse_s_uživatelem', 'female' => 'Diskuse_s_uživatelkou' ),
+       NS_USER      => array( 'male' => 'Uživatel', 'female' => 'Uživatelka' ),
+       NS_USER_TALK => array( 'male' => 'Diskuse_s_uživatelem', 'female' => 'Diskuse_s_uživatelkou' ),
 );
 
 $specialPageAliases = array(
@@ -84,6 +84,7 @@ $specialPageAliases = array(
        'Categories'                => array( 'Kategorie' ),
        'ChangeEmail'               => array( 'Změna_emailu', 'Zmena_emailu' ),
        'ChangePassword'            => array( 'Změna_hesla', 'Zmena_hesla', 'Resetovat_heslo' ),
+       'ComparePages'              => array( 'Porovnání_stránek', 'PorovnáníStránek', 'Porovnani_stranek', 'PorovnaniStranek' ),
        'Confirmemail'              => array( 'Potvrdit_e-mail' ),
        'Contributions'             => array( 'Příspěvky', 'Prispevky' ),
        'CreateAccount'             => array( 'Vytvořit_účet', 'Vytvorit_ucet' ),
@@ -679,7 +680,7 @@ Zkuste se podívat na [[Special:SpecialPages|seznam všech existujících speci
 
 # General errors
 'error' => 'Chyba',
-'databaseerror' => 'Databázová chyba',
+'databaseerror' => 'Chyba databáze',
 'dberrortext' => 'Při dotazu do databáze došlo k syntaktické chybě.
 Příčinou může být chyba v programu.
 Poslední dotaz byl:
@@ -789,11 +790,11 @@ Nezapomeňte si upravit své [[Special:Preferences|nastavení {{grammar:2sg|{{SI
 'notloggedin' => 'Nejste přihlášen(a)',
 'nologin' => "Dosud nemáte účet? '''$1'''.",
 'nologinlink' => 'Zaregistrujte se',
-'createaccount' => 'Vytvořit nový účet',
+'createaccount' => 'Vytvořit účet',
 'gotaccount' => "Už jste registrováni? '''$1'''.",
 'gotaccountlink' => 'Přihlaste se',
 'userlogin-resetlink' => 'Zapomněli jste přihlašovací údaje?',
-'createaccountmail' => 'pomocí e-mailu',
+'createaccountmail' => 'Použít dočasné náhodné heslo a odeslat ho na níže uvedenou e-mailovou adresu',
 'createaccountreason' => 'Důvod:',
 'badretype' => 'Vámi napsaná hesla nesouhlasí.',
 'userexists' => 'Zadané uživatelské jméno se již používá.
@@ -1083,7 +1084,8 @@ Uložením příspěvku se zavazujete, že je vaším dílem nebo je zkopírová
 Uložením příspěvku se zavazujete, že je vaším dílem nebo je zkopírován ze zdrojů, které nejsou chráněny autorským právem (tzv. <em>public domain</em>), podrobnosti najdete na $1. '''Nekopírujte díla chráněná autorským právem bez dovolení!'''",
 'longpageerror' => "'''Chyba: Pokoušíte se uložit text o velikosti {{PLURAL:$1|$1 KiB}}, přičemž dovolené maximum je {{PLURAL:$2|$2 KiB}}.'''
 Vaše změna nemůže být uložena.",
-'readonlywarning' => "'''VAROVÁNÍ: Databáze byla uzamčena kvůli údržbě, takže nebudete moci uložit své změny. Můžete si okopírovat text do souboru a uložit ho na později.'''
+'readonlywarning' => "'''Varování: Databáze byla uzamčena kvůli údržbě, takže momentálně nebudete moci uložit své změny.'''
+Můžete si okopírovat text do souboru a uložit ho na později.
 
 Správce serveru, který databázi zamkl, poskytl toto zdůvodnění: $1",
 'protectedpagewarning' => "'''Varování: Tato stránka byla zamčena, takže ji mohou editovat pouze správci.'''
@@ -1387,7 +1389,7 @@ Podrobnosti mohou být uvedeny v [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'search-interwiki-default' => 'Výsledky z $1:',
 'search-interwiki-more' => '(více)',
 'search-relatedarticle' => 'Související',
-'mwsuggest-disable' => 'Vypnout ajaxové napovídání',
+'mwsuggest-disable' => 'Vypnout našeptávač při hledání',
 'searcheverything-enable' => 'Hledat ve všech jmenných prostorech',
 'searchrelated' => 'související',
 'searchall' => 'vše',
@@ -2284,7 +2286,7 @@ Povinná je přinejmenším doména nejvyššího řádu, např. „*.org“.<br
 # Special:ActiveUsers
 'activeusers' => 'Seznam aktivních uživatelů',
 '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|editace|editace|editací}} během {{PLURAL:$3|posledního dne|posledních $3 dnů}}',
+'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',
@@ -3146,6 +3148,7 @@ Uložte jej na svůj disk a nahrajte ho sem.',
 'pageinfo-robot-noindex' => 'Neindexovatelná',
 'pageinfo-views' => 'Počet zobrazení',
 'pageinfo-watchers' => 'Počet sledujících',
+'pageinfo-few-watchers' => 'Méně než $1 {{PLURAL:$1|sledující|sledující|sledujících}}',
 'pageinfo-redirects-name' => 'Přesměrování na tuto stránku',
 'pageinfo-subpages-name' => 'Podstránky této stránky',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|přesměrování}}; $3 {{PLURAL:$3|nepřesměrování}})',
@@ -3262,8 +3265,7 @@ Otevřením souboru můžete ohrozit svůj počítač.",
 'days' => '{{PLURAL:$1|$1 den|$1 dny|$1 dní}}',
 'months' => '{{PLURAL:$1|$1 měsícem|$1 měsíci}}',
 'years' => '{{PLURAL:$1|$1 rokem|$1 roky}}',
-'ago' => 'před 
-$1',
+'ago' => 'před $1',
 'just-now' => 'Právě teď',
 
 # Bad image list
@@ -3975,7 +3977,7 @@ Obrázky se zobrazí v plném rozlišení, jiné typy souborů se otevřenou v p
 'specialpages-group-highuse' => 'Často používané stránky',
 'specialpages-group-pages' => 'Seznamy stránek',
 'specialpages-group-pagetools' => 'Nástroje ke stránkám',
-'specialpages-group-wiki' => 'Informace a nástroje k celé wiki',
+'specialpages-group-wiki' => 'Nástroje a data',
 'specialpages-group-redirects' => 'Přesměrovávací speciální stránky',
 'specialpages-group-spam' => 'Protispamové nástroje',
 
@@ -4072,8 +4074,8 @@ Obrázky se zobrazí v plném rozlišení, jiné typy souborů se otevřenou v p
 'logentry-newusers-newusers' => 'Byl založen uživatelský účet $1',
 'logentry-newusers-create' => 'Byl založen uživatelský účet $1',
 'logentry-newusers-create2' => '$1 založil uživatelský účet $3',
+'logentry-newusers-byemail' => '$1 {{GENDER:$2|založil|založila}} uživatelský účet $3, heslo bylo posláno e-mailem',
 'logentry-newusers-autocreate' => 'Automaticky byl založen účet $1',
-'newuserlog-byemail' => 'heslo zasláno e-mailem',
 'logentry-rights-rights' => '$1 {{GENDER:$2|změnil|změnila}} členství $3 ve skupinách z $4 na $5',
 'logentry-rights-rights-legacy' => '$1 změnil členství $3 ve skupinách',
 'logentry-rights-autopromote' => '$1 byl automaticky povýšen z $4 na $5',
@@ -4130,7 +4132,8 @@ Jinak můžete využít jednoduchý formulář níže. Váš komentář bude př
 'api-error-nomodule' => 'Interní chyba: není nastaven načítací modul.',
 'api-error-ok-but-empty' => 'Interní chyba: ze serveru nepřišla odpověď.',
 'api-error-overwrite' => 'Není dovoleno přepsat existující soubor.',
-'api-error-stashfailed' => 'Vnitřní chyba: serveru se nepodařilo uložit dočasný soubor.',
+'api-error-stashfailed' => 'Vnitřní chyba: Serveru se nepodařilo uložit dočasný soubor.',
+'api-error-publishfailed' => 'Vnitřní chyba: Serveru se nepodařilo zveřejnit dočasný soubor.',
 'api-error-timeout' => 'Server neodpověděl v očekávaném čase.',
 'api-error-unclassified' => 'Došlo k neznámé chybě',
 'api-error-unknown-code' => 'Neznámá chyba: „$1“',
index 12f7f34..3de2da1 100644 (file)
  * @author ОйЛ
  */
 
+$specialPageAliases = array(
+       'Allpages'                  => array( 'Вьсѩ_страницѧ' ),
+       'Categories'                => array( 'Катигорїѩ' ),
+       'Contributions'             => array( 'Добродѣꙗниꙗ' ),
+       'Preferences'               => array( 'Строи' ),
+       'Recentchanges'             => array( 'Послѣдьнѩ_мѣнꙑ' ),
+       'Search'                    => array( 'Исканиѥ' ),
+       'Statistics'                => array( 'Статїстїка' ),
+       'Upload'                    => array( 'Положєниѥ_дѣла' ),
+);
+
 $namespaceNames = array(
        NS_MEDIA            => 'Срѣдьства',
        NS_SPECIAL          => 'Нарочьна',
index eba65c0..c39aa66 100644 (file)
@@ -12,6 +12,7 @@
  * @author Lloffiwr
  * @author Malafaya
  * @author Reedy
+ * @author Robin Owain
  * @author Thaf
  * @author Urhixidur
  * @author Xxglennxx
@@ -144,7 +145,7 @@ $messages = array(
 'tog-enotifminoredits' => 'Gyrru e-bost ataf hefyd ar gyfer golygiadau bychain i dudalennau a ffeiliau',
 'tog-enotifrevealaddr' => 'Datguddio fy nghyfeiriad e-bost mewn e-byst hysbysu',
 'tog-shownumberswatching' => "Dangos y nifer o ddefnyddwyr sy'n gwylio",
-'tog-oldsig' => 'Llofnod cyfredol:',
+'tog-oldsig' => 'Y llofnod cyfredol:',
 'tog-fancysig' => 'Trin y llofnod fel testun wici (heb gyswllt wici awtomatig)',
 'tog-externaleditor' => 'Defnyddio golygydd allanol trwy ragosodiad (ar gyfer arbenigwyr yn unig; mae arno angen gosodiadau arbennig ar eich cyfrifiadur. [//www.mediawiki.org/wiki/Manual:External_editors Rhagor o wybodaeth.])',
 'tog-externaldiff' => 'Defnyddio "external diff" trwy ragosodiad (ar gyfer arbenigwyr yn unig; mae arno angen gosodiadau arbennig ar eich cyfrifiadur. [//www.mediawiki.org/wiki/Manual:External_editors Rhagor o wybodaeth.])',
@@ -525,6 +526,7 @@ Y rheswm a roddwyd gan y gweinyddwr a roddodd y ffeil dan glo yw "\'\'$3\'\'".',
 Gallwch ddefnyddio {{SITENAME}} yn anhysbys, neu fe allwch <span class='plainlinks'>[$1 fewngofnodi eto]</span> wrth yr un un enw neu wrth enw arall.
 Sylwer y bydd rhai tudalennau yn parhau i ymddangos fel ag yr oeddent pan oeddech wedi mewngofnodi hyd nes i chi glirio celc eich porwr.",
 'welcomeuser' => 'Croeso, $1!',
+'welcomecreation-msg' => 'Peidiwch ag anghofio newid eich [[Special:Preferences|{{SITENAME}} preferences]].',
 'yourname' => 'Eich enw defnyddiwr:',
 'yourpassword' => 'Eich cyfrinair:',
 'yourpasswordagain' => 'Ail-deipiwch y cyfrinair:',
@@ -547,7 +549,7 @@ Sylwer y bydd rhai tudalennau yn parhau i ymddangos fel ag yr oeddent pan oeddec
 'gotaccount' => "Oes cyfrif gennych eisoes? '''$1'''.",
 'gotaccountlink' => 'Mewngofnodwch',
 'userlogin-resetlink' => 'Ydych chi wedi anghofio eich manylion mewngofnodi?',
-'createaccountmail' => 'trwy e-bost',
+'createaccountmail' => "Defnyddier cyfrinair ar hap dros dro a'i anfon i'r cyfeiriad e-bost isod",
 'createaccountreason' => 'Rheswm:',
 'badretype' => "Nid yw'r cyfrineiriau'n union yr un fath.",
 'userexists' => 'Mae rhywun arall wedi dewis yr enw defnyddiwr hwn. 
@@ -829,9 +831,10 @@ Rydych chi'n cadarnhau mai chi yw awdur y cyfraniad, neu eich bod chi wedi'i gop
 '''PEIDIWCH Â CHYFRANNU GWAITH O DAN HAWLFRAINT HEB GANIATÂD!'''",
 'longpageerror' => "'''GWALL: Mae'r testun yr ydych wedi ei osod yma yn {{PLURAL:$1|$1 cilobeit}} o hyd, ac yn hwy na'r hyd eithaf o {{PLURAL:$2|$2}} cilobeit.
 Ni ellir ei roi ar gadw.'''",
-'readonlywarning' => "'''RHYBUDD: Mae'r databas wedi'i gloi am gyfnod er mwyn cynnal a chadw, felly fyddwch chi ddim yn gallu cadw'ch golygiadau ar hyn o bryd. Rydyn ni'n argymell eich bod chi'n copïo a gludo'r testun i ffeil a'i gadw ar eich disg tan bod y sustem yn weithredol eto.'''
+'readonlywarning' => "'''RHYBUDD: Mae'r gronfa ddata wedi'i chloi am gyfnod er mwyn cynnal a chadw, felly fyddwch chi ddim yn gallu cadw'ch golygiadau ar hyn o bryd.''' 
+Gallwch gopïo'r testun a'i gludo i ffeil destun er mwyn ei gadw tan yn hwyrach.
 
-Cynigiodd y gweinyddwr a glodd y databas y rheswm hwn dros ei gloi: $1",
+Cynigiodd y gweinyddwr a glodd y gronfa ddata y rheswm hwn dros ei chloi: $1",
 'protectedpagewarning' => "'''RHYBUDD: Mae'r dudalen hon wedi'i diogelu. Dim ond gweinyddwyr sydd yn gallu ei golygu.'''
 Dyma'r cofnod lòg diweddaraf, er gwybodaeth:",
 'semiprotectedpagewarning' => "'''Sylwer:''' Mae'r dudalen hon wedi ei chloi; dim ond defnyddwyr cofrestredig a allant ei golygu.
@@ -868,6 +871,9 @@ Ymddengys iddi gael ei dileu.",
 'edit-already-exists' => 'Ni ellid creu tudalen newydd.
 Mae ar gael yn barod.',
 'defaultmessagetext' => 'Y testun rhagosodedig',
+'content-failed-to-parse' => "Ni lwyddwyd i ddosrannu'r cynnwys sydd ar ffurf $2 yn ôl y model $1: $3",
+'invalid-content-data' => "Data annilys i'r cynnwys",
+'content-not-allowed-here' => 'Nid yw cynnwys ar ffurf "$1" yn cael ei ganiatau ar y dudalen [[$2]]',
 
 # Content models
 'content-model-wikitext' => 'cystrawen wici',
@@ -1085,7 +1091,7 @@ Pan yn gwneud hyn dylid sicrhau nad yw dilyniant hanes tudalennau yn cael ei ddi
 'diff-multi-manyusers' => '(Ni ddangosir {{PLURAL:$1|yr $1 diwygiad|yr $1 diwygiad|y $1 ddiwygiad|y $1 diwygiad|y $1 diwygiad|y $1 diwygiad}} rhyngol gan mwy na $2 {{PLURAL:$2|o ddefnyddwyr}}.)',
 'difference-missing-revision' => "Ni chafwyd hyd i $1 {{PLURAL:$2|diwygiad|diwygiad|ddiwygiad|diwygiad}} o'r gwahaniaeth ($1) {{PLURAL:$2|hwn}}.
 
-Fel arfer, fe ddigwydd hyn pan mae dyn wedi dilyn hen gyswllt gwahaniaeth i dudalen sydd erbyn hyn wedi cael ei dileu.
+Fel arfer, fe ddigwydd hyn pan mae person wedi dilyn hen gyswllt gwahaniaeth i dudalen sydd erbyn hyn wedi cael ei ddileu.
 Mae manylion pellach i'w cael yn [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} lòg y dileuon].",
 
 # Search results
@@ -1130,7 +1136,7 @@ Mae manylion pellach i'w cael yn [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'search-interwiki-default' => 'Y canlyniadau o $1:',
 'search-interwiki-more' => '(rhagor)',
 'search-relatedarticle' => 'Erthyglau eraill tebyg',
-'mwsuggest-disable' => 'Analluogi awgrymiadau AJAX',
+'mwsuggest-disable' => 'Analluogi awgrymiadau chwilio',
 'searcheverything-enable' => 'Chwilio pob parth',
 'searchrelated' => 'erthyglau eraill tebyg',
 'searchall' => 'oll',
@@ -1624,6 +1630,7 @@ Os yw'r broblem yn parhau, cysylltwch â [[Special:ListUsers/sysop|gweinyddwr]].
 'backend-fail-notsame' => "Mae ffeil gwahanol a'r enw $1 arni eisoes ar gael.",
 'backend-fail-invalidpath' => 'Nid yw $1 yn lwybr dilys i roi ffeil ar gadw.',
 'backend-fail-delete' => "Wedi methu dileu'r ffeil $1.",
+'backend-fail-describe' => 'Ni lwyddwyd newid metadata\'r ffeil "$1".',
 'backend-fail-alreadyexists' => "Mae'r ffeil $1 ar gael yn barod.",
 'backend-fail-store' => "Wedi methu rhoi'r ffeil $1 ar gadw yn $2.",
 'backend-fail-copy' => "Wedi methu copïo'r ffeil $1 i $2.",
@@ -2025,7 +2032,7 @@ Mae angen parth lefel-uchaf o leiaf, er enghraifft "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Rhestr defnyddwyr gweithgar',
 '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|golygiad|golygiad}} yn ystod y {{PLURAL:$3|diwrnod|diwrnod|deuddydd|tridiau|$3 diwrnod|$3 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',
@@ -2089,7 +2096,7 @@ Bydd y cyfeiriad e-bost a osodoch yn eich [[Special:Preferences|dewisiadau]] yn
 'usermessage-editor' => 'Golygydd neges y system',
 
 # Watchlist
-'watchlist' => 'Fy rhestr wylio',
+'watchlist' => 'Rhestr wylio',
 'mywatchlist' => 'Rhestr wylio',
 'watchlistfor2' => 'Yn ôl gofyn $1 $2',
 'nowatchlist' => "Mae eich rhestr wylio'n wag.",
@@ -2133,6 +2140,10 @@ Pan fydd y dudalen hon, neu ei thudalen sgwrs, yn newid, fe fyddant yn ymddangos
 'enotif_subject_restored' => 'Adferwyd y dudalen $1 ar {{SITENAME}} gan {{gender:$2|$2}}',
 'enotif_subject_changed' => 'Newidiwyd y dudalen $1 ar {{SITENAME}} gan {{gender:$2|$2}}',
 'enotif_body_intro_deleted' => 'Dilewyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}, gweler $3.',
+'enotif_body_intro_created' => 'Dechrëwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ohoni ar $3.',
+'enotif_body_intro_moved' => 'Symudwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ar $3.',
+'enotif_body_intro_restored' => 'Adferwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ohoni ar $3.',
+'enotif_body_intro_changed' => 'Newidiwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ohoni ar $3.',
 'enotif_lastvisited' => 'Gwelwch $1 am bob newid ers eich ymweliad blaenorol.',
 'enotif_lastdiff' => 'Gallwch weld y newid ar $1.',
 'enotif_anon_editor' => 'defnyddiwr anhysbys $1',
@@ -2233,6 +2244,8 @@ Mae'r tudalennau sydd wedi eu diogelu ar hyn o bryd wedi eu rhestri ar y [[Speci
 'prot_1movedto2' => 'wedi symud [[$1]] i [[$2]]',
 'protect-badnamespace-title' => 'Parth na ellir ei ddiogelu',
 'protect-badnamespace-text' => 'Ni ellir diogelu tudalennau yn y parth hwn.',
+'protect-norestrictiontypes-text' => 'Ni ellir gwarchod y dudalen hon gan nad oes mathau o gyfyngiadau ar gael iddi.',
+'protect-norestrictiontypes-title' => 'Tudalen na ellir ei gwarchod',
 'protect-legend' => "Cadarnháu'r diogelu",
 'protectcomment' => 'Rheswm:',
 'protectexpiry' => 'Yn dod i ben:',
@@ -2248,9 +2261,9 @@ Dyma'r gosodiadau diogelu cyfredol ar gyfer y dudalen '''$1''':",
 Dyma'r gosodiadau diogelu cyfredol ar gyfer y dudalen '''$1''':",
 'protect-cascadeon' => "Mae'r dudalen hon wedi ei diogelu ar hyn o bryd oherwydd ei bod wedi ei chynnwys yn y {{PLURAL:$1|dudalen|dudalen|tudalennau|tudalennau|tudalennau|tudalennau}} canlynol sydd wedi {{PLURAL:$1|ei|ei|eu|eu|eu|eu}} sgydol-diogelu.  Gallwch newid lefel diogelu'r dudalen hon, ond ni fydd hynny'n effeithio ar y sgydol-ddiogelu.",
 'protect-default' => "Caniatáu'r gallu i bob defnyddiwr",
-'protect-fallback' => 'Mynnu\'r gallu "$1"',
-'protect-level-autoconfirmed' => "Blocio defnyddwyr newydd a'r rhai heb gyfrif",
-'protect-level-sysop' => 'Gweinyddwyr yn unig',
+'protect-fallback' => 'Caniatau i\'r defnyddwyr gyda\'r gallu "$1" yn unig wneud hyn',
+'protect-level-autoconfirmed' => "Caniatau'r defnyddwyr sydd wedi eu cadarnhau'n awtomatig yn unig",
+'protect-level-sysop' => 'Gweinyddwyr yn unig caiff wneud',
 'protect-summary-cascade' => 'sgydol',
 'protect-expiring' => 'yn dod i ben am $1 (UTC)',
 'protect-expiring-local' => 'yn dod i ben am $1',
@@ -2545,17 +2558,18 @@ Er mwyn cloi'r gronfa ddata neu ei datgloi, mae'n rhaid i'r gweinydd gwe allu ys
 # Move page
 'move-page' => 'Symud $1',
 'move-page-legend' => 'Symud tudalen',
-'movepagetext' => "Drwy ddefnyddio'r ffurflen isod, byddwch yn ailenwi tudalen, felly yn symud ei holl hanes i'r enw tudalen newydd.
-Caiff yr hen deitl a oedd ar y dudalen ei droi'n dudalen sy'n ailgyfeirio i'r teitl newydd.
+'movepagetext' => "Drwy ddefnyddio'r ffurflen isod, byddwch yn ailenwi tudalen, ac felly yn symud ei holl hanes i'r dudalen a'r enw newydd.
+Caiff y dudalen a'r hen deitl ei throi'n dudalen sy'n ailgyfeirio i'r teitl newydd.
 Gallwch ddiweddaru tudalennau ailgyfeirio sy'n cyfeirio at y teitl gwreiddiol yn awtomatig.
-Os ydych yn dewis peidio â gwneud hyn, gwiriwch [[Special:BrokenRedirects|dudalennau ailgyfeirio nad ydynt yn ailgyfeirio]] neu [[Special:DoubleRedirects|dudalennau ailgyfeirio dwbl]].
-Chi sy'n gyfrifol am wirio bod cysylltiadau yn cyfeirio at y tudalennau cywir.
+Os ydych yn dewis peidio â gwneud hyn, gwiriwch [[Special:DoubleRedirects|dudalennau ailgyfeirio dwbl]] neu 
+[[Special:BrokenRedirects|dudalennau ailgyfeirio nad ydynt yn ailgyfeirio]].
+Chi sy'n gyfrifol am sicrhau bod cysylltiadau yn cyfeirio at y tudalennau cywir.
 
-Sylwer '''na''' chaiff y dudalen ei symud os oes enw ar y dudalen yn bodoli'n barod, oni bai ei bod hi'n wag neu'n dudalen ailgyfeirio ac nad oes hanes golygu ganddi.
-Mae hyn yn golygu y gallwch ailenwi tudalen yn ôl os yr ydych yn gwneud camgymeriad, ond nid ydych yn gallu trosysgrifo tudalen sy'n bodoli'n barod.
+Sylwer '''na''' chaiff y dudalen ei symud os oes tudalen a'r enw newydd ar gael yn barod, oni bai bod y dudalen a'r enw newydd yn dudalen ailgyfeirio ac nad oes hanes golygu ganddi.
+Mae hyn yn golygu y gallwch ailenwi tudalen yn ôl i'w henw gwreiddiol os ydych yn gwneud camgymeriad, ond na allwch drosysgrifo tudalen sy'n bodoli'n barod.
 
 '''Rhybudd!'''
-Gall hwn greu newid annisgwyl a chryf i dudalen boblogaidd;
+Gall hwn fod yn newid mawr ac annisgwyl i dudalen boblogaidd;
 gwnewch yn siŵr eich bod yn deall canlyniadau'r broses hon cyn i chi barhau.",
 'movepagetext-noredirectfixer' => "Wrth ddefnyddio'r ffurflen isod byddwch yn ail-enwi tudalen, gan symud ei hanes gyfan i'r enw newydd.
 Bydd yr hen deitl yn troi'n dudalen ailgyfeirio i'r teitl newydd.
@@ -2621,6 +2635,7 @@ nid yw'n bosib cyflawnu'r symud.",
 'immobile-target-namespace-iw' => 'Nid yw cyswllt rhyngwici yn nod dilys wrth symud tudalen.',
 'immobile-source-page' => 'Ni ellir symud y dudalen hon.',
 'immobile-target-page' => "Ddim yn gallu symud i'r teitl newydd hwn.",
+'bad-target-model' => "Mae'r cyrchfan dewisedig yn defnyddio model gwahanol i'w chynnwys. Ni ellir trawsnewid o $1 i $2.",
 'imagenocrossnamespace' => 'Ni ellir symud ffeil i barth arall',
 'nonfile-cannot-move-to-file' => 'Ni ellir symud unrhywbeth heblaw ffeil i barth y ffeiliau',
 'imagetypemismatch' => "Nid yw'r estyniad ffeil newydd yn cyfateb i'r math o ffeil",
@@ -2864,10 +2879,11 @@ Achos hyn yn fwy na thebyg yw presenoldeb cysylltiad i wefan ar y rhestr wahardd
 'pageinfo-article-id' => 'ID y dudalen',
 'pageinfo-language' => 'Iaith cynnwys y dudalen',
 'pageinfo-robot-policy' => 'Statws i beiriannau chwilio',
-'pageinfo-robot-index' => 'Gellir ei rhestri gan beiriannau chwilio',
-'pageinfo-robot-noindex' => 'Ni ellir ei rhestri gan beiriannau chwilio',
+'pageinfo-robot-index' => 'Gellir ei rhestru gan beiriannau chwilio',
+'pageinfo-robot-noindex' => 'Ni ellir ei rhestru gan beiriannau chwilio',
 'pageinfo-views' => 'Nifer yr ymweliadau',
 'pageinfo-watchers' => 'Nifer gwylwyr y dudalen',
+'pageinfo-few-watchers' => 'Llai na $1 {{PLURAL:$1|gwyliwr|gwyliwr|wyliwr|gwyliwr|o wylwyr}}',
 'pageinfo-redirects-name' => "Nifer yr ailgyfeiriadau i'r dudalen hon",
 'pageinfo-subpages-name' => "Nifer yr is-dudalennau i'r dudalen hon",
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|ailgyfeiriad}}; $3 {{PLURAL:$3|is-dudalen arall}})',
@@ -2882,8 +2898,15 @@ Achos hyn yn fwy na thebyg yw presenoldeb cysylltiad i wefan ar y rhestr wahardd
 'pageinfo-magic-words' => '{{PLURAL:$1|Gair|Gair|Geiriau}} hud ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categori|Categori|Categorïau}} cudd ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Nodyn|Nodyn|Nodiadau}} a drawsgynhwyswyd ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Tudalen|Tudalen|Tudalennau}} y trawsgynhwyswyd y dudalen hon arnynt ($1)',
 'pageinfo-toolboxlink' => 'Gwybodaeth am y dudalen',
 'pageinfo-redirectsto' => 'Yn ailgyfeirio i',
+'pageinfo-redirectsto-info' => 'manylion',
+'pageinfo-contentpage' => 'Ymhlith tudalennau pwnc y wici',
+'pageinfo-contentpage-yes' => 'Ydi',
+'pageinfo-protect-cascading' => "Mae diogelu sgydol yn deillio o'r dudalen hon",
+'pageinfo-protect-cascading-yes' => 'Oes',
+'pageinfo-protect-cascading-from' => "Mae'r diogelu sgydol yn dechrau ar",
 'pageinfo-category-info' => 'Gwybodaeth am y categori',
 'pageinfo-category-pages' => 'Nifer y tudalennau',
 'pageinfo-category-subcats' => 'Nifer yr is-gategorïau',
@@ -2904,6 +2927,8 @@ Achos hyn yn fwy na thebyg yw presenoldeb cysylltiad i wefan ar y rhestr wahardd
 'markedaspatrollederror' => 'Ni ellir gosod marc ymweliad patrôl',
 'markedaspatrollederrortext' => "Rhaid nodi'r union olygiad sydd angen marc ymweliad patrôl.",
 'markedaspatrollederror-noautopatrol' => "Ni chaniateir i chi farcio'ch newidiadau eich hunan fel rhai derbyniol.",
+'markedaspatrollednotify' => 'Nodwyd bod y newid hwn i $1 wedi derbyn ymweliad patrôl.',
+'markedaspatrollederrornotify' => 'Methwyd rhoi marc ymweliad patrôl arni.',
 
 # Patrol log
 'patrol-log-page' => 'Lòg patrolio',
@@ -2937,6 +2962,7 @@ Mae'n bosib y bydd eich cyfrifiadur yn cael ei danseilio wrth ddefnyddio'r ffeil
 'file-nohires' => 'Wedi ei chwyddo hyd yr eithaf.',
 'svg-long-desc' => 'Ffeil SVG, maint mewn enw $1 × $2 picsel, maint y ffeil: $3',
 'svg-long-desc-animated' => 'Ffeil SVG animeiddiedig, maint mewn enw $1 × $2 picsel, maint y ffeil: $3',
+'svg-long-error' => 'Ffeil SVG annilys: $1',
 'show-big-image' => 'Maint llawn',
 'show-big-image-preview' => 'Maint y rhagolwg: $1.',
 'show-big-image-other' => '{{PLURAL:$2|Datrysiad arall|Datrysiad arall|Datrysiadau eraill|Datrysiadau eraill|Datrysiadau eraill|Datrysiadau eraill}}: $1.',
@@ -2972,7 +2998,7 @@ Mae'n bosib y bydd eich cyfrifiadur yn cael ei danseilio wrth ddefnyddio'r ffeil
 'months' => '{{PLURAL:$1|$1 mis|mis|deufis|$1 mis}}',
 'years' => '{{PLURAL:$1|$1 blwyddyn|blwyddyn|$1 flynedd|$1 blynedd|$1 blynedd|$1 mlynedd}}',
 'ago' => '$1 yn ôl',
-'just-now' => 'gynnau',
+'just-now' => 'nawr',
 
 # Bad image list
 'bad_image_list' => "Dyma'r fformat:
@@ -3039,7 +3065,7 @@ Cuddir y meysydd eraill trwy ragosodiad.
 'exif-pixelydimension' => 'Lled y ddelwedd',
 'exif-pixelxdimension' => 'Uchder y ddelwedd',
 'exif-usercomment' => "Sylwadau'r defnyddiwr",
-'exif-relatedsoundfile' => 'Ffeil sain cysylltiedig',
+'exif-relatedsoundfile' => 'Ffeil sain gysylltiedig',
 'exif-datetimeoriginal' => 'Dyddiad ac amser y cynhyrchwyd y data',
 'exif-datetimedigitized' => 'Dyddiad ac amser y digiteiddiwyd',
 'exif-subsectime' => 'Manylyn iseiliad amser newid y ffeil',
@@ -3165,8 +3191,8 @@ Cuddir y meysydd eraill trwy ragosodiad.
 'exif-originaldocumentid' => 'ID unigryw y ddogfen wreiddiol',
 'exif-licenseurl' => 'URL y drwydded hawlfraint',
 'exif-morepermissionsurl' => 'Gwybodaeth trwyddedu amgen',
-'exif-attributionurl' => "Wrth ail-ddefnyddio'r gwaith yma, darparwch ddolen at",
-'exif-preferredattributionname' => "Wrth ail-ddefnyddio'r gwaith yma, cydnabyddwch",
+'exif-attributionurl' => "Wrth ailddefnyddio'r gwaith yma, darparwch ddolen at",
+'exif-preferredattributionname' => "Wrth ailddefnyddio'r gwaith yma, cydnabyddwch",
 'exif-pngfilecomment' => 'Sylwadau ar y ffeil PNG',
 'exif-disclaimer' => 'Ymwadiad',
 'exif-contentwarning' => 'Rhybudd am y cynnwys',
@@ -3458,7 +3484,8 @@ Bydd y côd cadarnhau yn dod i ben am $4.',
 
 # Scary transclusion
 'scarytranscludedisabled' => '[Analluogwyd cynhwysiad rhyng-wici]',
-'scarytranscludefailed' => '[Methwyd â nôl y nodyn ar gyfer $1]',
+'scarytranscludefailed' => '[Methwyd nôl y nodyn ar gyfer $1]',
+'scarytranscludefailed-httpstatus' => '[Methwyd nôl y nodyn ar gyfer $1: HTTP $2]',
 'scarytranscludetoolong' => "[Mae'r URL yn rhy hir]",
 
 # Delete conflict
@@ -3567,6 +3594,7 @@ Gallwch hefyd [[Special:EditWatchlist|ddefnyddio\'r rhestr arferol]].',
 'version-license' => 'Trwydded',
 'version-poweredby-credits' => "Mae'r wici hwn wedi'i nerthu gan '''[//www.mediawiki.org/ MediaWiki]''', hawlfraint © 2001 - $1 $2.",
 'version-poweredby-others' => 'eraill',
+'version-credits-summary' => 'Hoffem gydnabod cyfraniad y bobl canlynol i [[Special:Version|MediaWiki]].',
 'version-license-info' => "Meddalwedd rhydd yw MediaWiki; gallwch ei ddefnyddio a'i addasu yn ôl termau'r GNU General Public License a gyhoeddir gan Free Software Foundation; naill ai fersiwn 2 o'r Drwydded, neu unrhyw fersiwn diweddarach o'ch dewis.
 
 Cyhoeddir MediaWiki yn y gobaith y bydd o ddefnydd, ond HEB UNRHYW WARANT; heb hyd yn oed gwarant ymhlyg o FARCHNADWYEDD nag o FOD YN ADDAS AT RYW BWRPAS ARBENNIG. Gweler y GNU General Public License am fanylion pellach.
@@ -3612,7 +3640,7 @@ Dangosir delweddau ar eu maint llawn, dechreuir ffeiliau o fathau eraill yn unio
 'specialpages-group-highuse' => 'Tudalennau aml eu defnydd',
 'specialpages-group-pages' => 'Rhestrau tudalennau',
 'specialpages-group-pagetools' => 'Offer trin tudalennau',
-'specialpages-group-wiki' => 'Data ac offer y wici',
+'specialpages-group-wiki' => 'Data ac offer',
 'specialpages-group-redirects' => 'Tudalennau arbennig ailgyfeirio',
 'specialpages-group-spam' => 'Offer sbam',
 
@@ -3709,8 +3737,11 @@ Dangosir delweddau ar eu maint llawn, dechreuir ffeiliau o fathau eraill yn unio
 'logentry-newusers-newusers' => 'Dechreuwyd y cyfrif defnyddiwr $1',
 'logentry-newusers-create' => 'Dechreuwyd y cyfrif defnyddiwr $1',
 'logentry-newusers-create2' => 'Dechreuwyd y cyfrif defnyddiwr $3 gan $1',
+'logentry-newusers-byemail' => 'Dechreuodd $1 y cyfrif defnyddiwr $3 ac anfonodd gyfrinair drwy e-bost',
 'logentry-newusers-autocreate' => 'Crëwyd y cyfrif $1 yn awtomatig',
-'newuserlog-byemail' => 'anfonwyd y cyfrinair trwy e-bost',
+'logentry-rights-rights' => 'Newidiodd $1 y grwpiau y mae $3 yn aelod ohonynt o $4 i $5',
+'logentry-rights-rights-legacy' => 'Newidiodd $1 y grwpiau y mae $3 yn aelod ohonynt',
+'logentry-rights-autopromote' => 'Dyrchafwyd $1 yn awtomatig o $4 i $5',
 'rightsnone' => '(dim)',
 
 # Feedback
@@ -3764,6 +3795,7 @@ Dangosir delweddau ar eu maint llawn, dechreuir ffeiliau o fathau eraill yn unio
 'api-error-ok-but-empty' => 'Gwall mewnol: dim ymateb gan y gweinydd.',
 'api-error-overwrite' => 'Ni chaniateir trosysgrifo ffeil sydd eisoes yn bod.',
 'api-error-stashfailed' => "Gwall mewnol: methodd y gweinydd â rhoi'r ffeil dros dro ar gadw.",
+'api-error-publishfailed' => "Gwall mewnol: methodd y gweinydd â chyhoeddi'r ffeil dros dro.",
 'api-error-timeout' => 'Ni chafwyd ymateb gan y gweinydd mewn da bryd.',
 'api-error-unclassified' => 'Cafwyd gwall anhysbys',
 'api-error-unknown-code' => 'Gwall anhysbys: "$1"',
index 745a4d9..c6f969d 100644 (file)
@@ -32,6 +32,7 @@
  * @author Morten LJ
  * @author Najami
  * @author Nghtwlkr
+ * @author Palnatoke
  * @author Peter Alberti
  * @author Peter Andersen
  * @author Purodha
@@ -321,6 +322,7 @@ $messages = array(
 'newwindow' => '(åbner i et nyt vindue)',
 'cancel' => 'Afbryd',
 'moredotdotdot' => 'Mere...',
+'morenotlisted' => 'Mere ikke angivet...',
 'mypage' => 'Side',
 'mytalk' => 'Diskussion',
 'anontalk' => 'Diskussionsside for denne IP-adresse',
@@ -620,7 +622,7 @@ Glem ikke at ændre dine [[Special:Preferences|{{SITENAME}} indstillinger]].',
 'gotaccount' => 'Har du allerede en konto? $1.',
 'gotaccountlink' => 'Log på',
 'userlogin-resetlink' => 'Har du glemt dine login oplysninger?',
-'createaccountmail' => 'via e-mail',
+'createaccountmail' => 'Brug en midlertidig tilfældig adgangskode og send den til e-mailadressen angivet nedenfor',
 'createaccountreason' => 'Begrundelse:',
 'badretype' => 'De indtastede adgangskoder er ikke ens.',
 'userexists' => 'Det brugernavn, du har valgt, er allerede i brug.
@@ -692,6 +694,7 @@ Vent venligst før du prøver igen.',
 # E-mail sending
 'php-mail-error-unknown' => "Ukendt fejl i PHP's mail()-funtion",
 'user-mail-no-addy' => 'Forsøgte at sende email uden en email-adresse',
+'user-mail-no-body' => 'Forsøgte at sende en e-mail med tomt eller urimeligt kort indhold.',
 
 # Change password dialog
 'resetpass' => 'Skift adgangskode',
@@ -915,9 +918,10 @@ Du bekræfter hermed også, at du selv har skrevet denne tekst eller kopieret de
 '''OVERFØR IKKE OPHAVSRETSLIGT BESKYTTET INDHOLD UDEN TILLADELSE!'''",
 'longpageerror' => "'''Fejl: Teksten, som du ville gemme, er {{PLURAL:$1|en kilobyte|$1 kilobytes}} stor, hvilket er mere end det tilladte maksimum på {{PLURAL:$2|en kilobyte|$2 kilobytes}}.'''
 Det er ikke muligt at gemme den.",
-'readonlywarning' => "'''ADVARSEL: Databasen er låst på grund af vedligeholdelse, så du kan ikke gemme dine ændringer lige nu. Det kan godt være en god ide at kopiere din tekst til en tekstfil, så du kan gemme den til senere.'''
+'readonlywarning' => "'''Advarsel: Databasen er låst på grund af vedligeholdelse, så du kan ikke gemme dine ændringer lige nu.'''
+Det kan godt være en god ide at kopiere din tekst til en tekstfil, så du kan gemme den til senere.
 
-Systemadministratoren som låste databasen, gav denne forklaring: $1",
+Administratoren som låste databasen, gav denne forklaring: $1",
 'protectedpagewarning' => "'''ADVARSEL: Denne side er skrivebeskyttet, så kun administratorer kan redigere den.'''<br />
 Den seneste logpost vises nedenfor:",
 'semiprotectedpagewarning' => "'''Bemærk: Siden er låst, så kun registrerede brugere kan ændre den.'''
@@ -1213,7 +1217,7 @@ Detaljer kan findes i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'search-interwiki-default' => '{{PLURAL:$1|et resultat|$1 resultater}}:',
 'search-interwiki-more' => '(mere)',
 'search-relatedarticle' => 'Relateret',
-'mwsuggest-disable' => 'Slå AJAX-forslag fra',
+'mwsuggest-disable' => 'Slå søgningsforslag fra',
 'searcheverything-enable' => 'Søg i alle navnerum',
 'searchrelated' => 'relateret',
 'searchall' => 'alle',
@@ -2114,7 +2118,7 @@ Der skal som minimum angives et topniveau-domæne som f. eks. "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Liste over aktive brugere',
 '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|redigering|redigeringer}} i {{PLURAL:$3|det seneste døgn|de seneste $3 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',
@@ -2338,9 +2342,9 @@ Se [[Special:ProtectedPages|listen over beskyttede sider]] for listen over sideb
 'protect-locked-access' => "Den brugerkonto har ikke de nødvendige rettigheder til at ændre sidebeskyttelsen. Her er de aktuelle beskyttelsesindstillinger for siden '''„$1“:'''",
 'protect-cascadeon' => 'Denne side er del af en nedarvet skrivebeskyttelse. Wen er indeholdt i nedenstående {{PLURAL:$1|side|sider}}, som er skrivebeskyttet med tilvalg af "nedarvende sidebeskyttelse" Sidebeskyttelsen kan ændres for denne side, det påvirker dog ikke kaskadespærringen:',
 'protect-default' => 'Tillad alle brugere',
-'protect-fallback' => 'Kræver "$1"-tilladelse',
-'protect-level-autoconfirmed' => 'Spær for nye og uregistrerede brugere',
-'protect-level-sysop' => 'Kun administratorer',
+'protect-fallback' => 'Tillad kun brugere med "$1" adgang',
+'protect-level-autoconfirmed' => 'Tillad kun autobekræftede brugere',
+'protect-level-sysop' => 'Tillad kun administratorer',
 'protect-summary-cascade' => 'nedarvende',
 'protect-expiring' => 'til $1 (UTC)',
 'protect-expiring-local' => 'udløber $1',
@@ -2632,7 +2636,17 @@ Se [[Special:BlockList|blokeringslisten]] for den nuværende liste med aktuelle
 # Move page
 'move-page' => 'Flyt $1',
 'move-page-legend' => 'Flyt side',
-'movepagetext' => "Når du bruger formularen herunder vil du få omdøbt en side og flyttet hele sidens historie til det nye navn. Den gamle titel vil blive en omdirigeringsside til den nye titel. Henvisninger til den gamle titel vil ikke blive ændret. Sørg for at tjekke for dobbelte eller dårlige omdirigeringer. Du er ansvarlig for, at alle henvisninger stadig peger derhen, hvor det er meningen de skal pege. Bemærk at siden '''ikke''' kan flyttes hvis der allerede er en side med den nye titel, medmindre den side er tom eller er en omdirigering uden nogen historie. Det betyder at du kan flytte en side tilbage hvor den kom fra, hvis du kommer til at lave en fejl. <b>ADVARSEL!</b> Dette kan være en drastisk og uventet ændring for en populær side; vær sikker på, at du forstår konsekvenserne af dette før du fortsætter.",
+'movepagetext' => "Når du bruger formularen herunder, vil du få omdøbt en side og flyttet hele sidens historie til det nye navn.
+Den gamle titel vil blive en omdirigeringsside til den nye titel.
+Du kan opdatere omdirigeringer, der peger på den oprindelige titel, automatisk.
+Hvis du vælger ikke at opdatere dem automatisk, så sørg for at tjekke efter [[Special:DoubleRedirects|dobbelte]] eller [[Special:BrokenRedirects|dårlige omdirigeringer]].
+Du er ansvarlig for, at alle henvisninger stadig peger derhen, hvor det er meningen de skal pege.
+
+Bemærk at siden '''ikke''' kan flyttes, hvis der allerede er en side med den nye titel, medmindre den side er en omdirigering uden nogen redigeringshistorik.
+Det betyder, at du kan flytte en side tilbage hvor den kom fra, hvis du kommer til at lave en fejl, og det betyder, at du ikke kan overskrive en eksisterende side.
+
+'''ADVARSEL!'''
+Dette kan være en drastisk og uventet ændring for en populær side; vær sikker på, at du forstår konsekvenserne af dette før du fortsætter.",
 'movepagetext-noredirectfixer' => "Brug formularen herunder du vil omdøbe en side og flyttet hele sidens historie til det nye navn.
 Den gamle titel vil blive en omdirigeringsside til den nye titel.
 Vær sikker på at tjekke for [[Special:DoubleRedirects|dobbelte]] eller [[Special:BrokenRedirects|ødelagte omdirigeringer]].
@@ -2950,6 +2964,7 @@ Dette skyldes sandsynligvis en henvisning til et sortlistet eksternt websted.',
 'pageinfo-robot-noindex' => 'Ikke indekserbar',
 'pageinfo-views' => 'Antal visninger',
 'pageinfo-watchers' => 'Antal brugere, der overvåger siden',
+'pageinfo-few-watchers' => 'Overvåget af færre end $1 {{PLURAL:$1|bruger|brugere}}',
 'pageinfo-redirects-name' => 'Omdirigeringer til denne side',
 'pageinfo-subpages-name' => 'Undersider til denne side',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|omdirigering|omdirigeringer}}; $3 {{PLURAL:$3|der ikke er en omdirigering|der ikke er omdirigeringer}})',
@@ -2964,6 +2979,7 @@ Dette skyldes sandsynligvis en henvisning til et sortlistet eksternt websted.',
 'pageinfo-magic-words' => '{{PLURAL:$1|Magisk|Magiske}} ord ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Skjult kategori|Skjulte kategorier}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Transkluderet skabelon|Transkluderede skabeloner}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Side|Sider}} transkluderet på ( $1 )',
 'pageinfo-toolboxlink' => 'Oplysninger om siden',
 'pageinfo-redirectsto' => 'Omdirigerer til',
 'pageinfo-redirectsto-info' => 'info',
@@ -3711,7 +3727,7 @@ Billeder vises i fuld opløsning, og andre mediatyper vil blive aktiveret med de
 'specialpages-group-highuse' => 'Højt profilerede sider',
 'specialpages-group-pages' => 'Sidelister',
 'specialpages-group-pagetools' => 'Sideværktøjer',
-'specialpages-group-wiki' => 'Wikidata og værktøjer',
+'specialpages-group-wiki' => 'Data og værktøjer',
 'specialpages-group-redirects' => 'Specialsider der viderestiller',
 'specialpages-group-spam' => 'Spamværktøjer',
 
@@ -3808,8 +3824,8 @@ Billeder vises i fuld opløsning, og andre mediatyper vil blive aktiveret med de
 'logentry-newusers-newusers' => 'Brugerkontoen $1 blev oprettet',
 'logentry-newusers-create' => 'Brugerkontoen $1 blev oprettet',
 'logentry-newusers-create2' => 'Brugerkontoen $3 blev oprettet af $1',
+'logentry-newusers-byemail' => 'Brugerkonto  $3  blev oprettet af  $1  og adgangskode er sendt via e-mail',
 'logentry-newusers-autocreate' => 'Kontoen $1 blev automatisk oprettet',
-'newuserlog-byemail' => 'kodeord tilsendt pr. e-mail',
 'logentry-rights-rights' => '$1 ændrede gruppemedlemskabet for $3 fra $4 til $5',
 'logentry-rights-rights-legacy' => '$1 ændrede gruppemedlemskabet for $3',
 'logentry-rights-autopromote' => '$1 blev automatisk forfremmet fra $4 til $5',
@@ -3867,6 +3883,7 @@ Ellers kan du bruge den enkle formular nedenfor. Din kommentar vil blive tilføj
 'api-error-ok-but-empty' => 'Intern fejl: intet svar fra serveren.',
 'api-error-overwrite' => 'Det er ikke tilladt at overskrive en eksisterende fil.',
 'api-error-stashfailed' => 'Intern fejl: serveren kunne ikke gemme midlertidig fil.',
+'api-error-publishfailed' => 'Intern fejl: serveren kunne ikke udgive midlertidig fil.',
 'api-error-timeout' => 'Serveren svarede ikke tilbage inden for den forventede tid.',
 'api-error-unclassified' => 'En ukendt fejl opstod.',
 'api-error-unknown-code' => 'Ukendt fejl: "$1"',
index dc6d03d..654bd05 100644 (file)
@@ -13,6 +13,7 @@
  * @author Church of emacs
  * @author DaSch
  * @author Das Schäfchen
+ * @author Dschwen
  * @author Duesentrieb
  * @author Filzstift
  * @author Geitost
@@ -193,6 +194,7 @@ $specialPageAliases = array(
        'Userlogin'                 => array( 'Anmelden' ),
        'Userlogout'                => array( 'Abmelden' ),
        'Userrights'                => array( 'Benutzerrechte' ),
+       'Version'                   => array( 'Versionsinformationen' ),
        'Wantedcategories'          => array( 'Gewünschte_Kategorien' ),
        'Wantedfiles'               => array( 'Gewünschte_Dateien', 'Fehlende_Dateien' ),
        'Wantedpages'               => array( 'Gewünschte_Seiten' ),
@@ -780,7 +782,7 @@ Die Daten werden bis auf Weiteres nicht erneuert.',
 Funktion: $1<br />
 Abfrage: $2',
 'viewsource' => 'Quelltext anzeigen',
-'viewsource-title' => 'Quelltext von Seite $1 ansehen',
+'viewsource-title' => 'Quelltext der Seite $1',
 'actionthrottled' => 'Aktionsanzahl limitiert',
 'actionthrottledtext' => 'Im Rahmen einer Anti-Spam-Maßnahme kann diese Aktion in einem kurzen Zeitabstand nur begrenzt oft ausgeführt werden. Diese Grenze hast du überschritten.
 Bitte versuche es in ein paar Minuten erneut.',
@@ -844,7 +846,7 @@ Vergiss nicht, deine [[Special:Preferences|{{SITENAME}}-Einstellungen]] zu ände
 'gotaccount' => "Du hast bereits ein Benutzerkonto? '''$1'''.",
 'gotaccountlink' => 'Anmelden',
 'userlogin-resetlink' => 'Die Anmeldedaten vergessen?',
-'createaccountmail' => 'Benutzerkonto anlegen (mit Passwortzusendung)',
+'createaccountmail' => 'Ein temporäres Zufallspasswort verwenden und an die unten angegebene E-Mail-Adresse versenden',
 'createaccountreason' => 'Grund:',
 'badretype' => 'Die beiden Passwörter stimmen nicht überein.',
 'userexists' => 'Dieser Benutzername ist schon vergeben.
@@ -1433,7 +1435,7 @@ Einzelheiten sind im [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'search-interwiki-default' => '$1 Ergebnisse:',
 'search-interwiki-more' => '(weitere)',
 'search-relatedarticle' => 'Verwandte',
-'mwsuggest-disable' => 'Vorschläge per Ajax deaktivieren',
+'mwsuggest-disable' => 'Suchvorschläge deaktivieren',
 'searcheverything-enable' => 'In allen Namensräumen suchen',
 'searchrelated' => 'verwandt',
 'searchall' => 'alle',
@@ -1499,7 +1501,7 @@ Einzelheiten sind im [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'columns' => 'Spalten:',
 'searchresultshead' => 'Suche',
 'resultsperpage' => 'Treffer pro Seite:',
-'stub-threshold' => 'Linkformatierung <a href="#" class="stub">kleiner Seiten</a> (in Byte):',
+'stub-threshold' => 'Linkformatierung <a href="#" class="stub">kleiner Seiten</a> (in Bytes):',
 'stub-threshold-disabled' => 'Deaktiviert',
 'recentchangesdays' => 'Anzahl der standardmäßig einbezogenen Tage:',
 'recentchangesdays-max' => 'Maximal $1 {{PLURAL:$1|Tag|Tage}}',
@@ -1769,7 +1771,7 @@ Stand: $4, $5 Uhr.",
 'rc_categories' => 'Nur Seiten aus den Kategorien (getrennt mit „|“):',
 'rc_categories_any' => 'Alle',
 'rc-change-size' => '$1 {{PLURAL:$1|Byte|Bytes}}',
-'rc-change-size-new' => '$1 {{PLURAL:$1|Byte|Byte}} nach der Änderung',
+'rc-change-size-new' => '$1 {{PLURAL:$1|Byte|Bytes}} nach der Änderung',
 'newsectionsummary' => 'Neuer Abschnitt /* $1 */',
 'rc-enhanced-expand' => 'Details anzeigen (benötigt JavaScript)',
 'rc-enhanced-hide' => 'Details verstecken',
@@ -1823,7 +1825,7 @@ Um ein '''Bild''' in einer Seite zu verwenden, nutze einen Link in der folgenden
 'ignorewarnings' => 'Warnungen ignorieren',
 'minlength1' => 'Dateinamen müssen mindestens einen Buchstaben lang sein.',
 'illegalfilename' => 'Der Dateiname „$1“ enthält mindestens ein nicht erlaubtes Zeichen. Bitte benenne die Datei um und versuche, sie erneut hochzuladen.',
-'filename-toolong' => 'Dateinamen dürfen nicht größer als 240 Byte sein.',
+'filename-toolong' => 'Dateinamen dürfen nicht größer als 240 Bytes sein.',
 'badfilename' => 'Der Dateiname wurde in „$1“ geändert.',
 'filetype-mime-mismatch' => 'Dateierweiterung „.$1“ stimmt nicht mit dem MIME-Typ ($2) überein.',
 'filetype-badmime' => 'Dateien mit dem MIME-Typ „$1“ dürfen nicht hochgeladen werden.',
@@ -1949,7 +1951,7 @@ Wenn das Problem weiter besteht, informiere einen [[Special:ListUsers/sysop|Syst
 'backend-fail-closetemp' => 'Die temporäre Datei konnte nicht geschlossen werden.',
 'backend-fail-read' => 'Die Datei $1 konnte nicht gelesen werden.',
 'backend-fail-create' => 'Die Datei $1 konnte nicht gespeichert werden.',
-'backend-fail-maxsize' => 'Die Datei $1 konnte nicht gespeichert werden, da sie größer als {{PLURAL:$2|ein Byte|$2 Byte}} ist.',
+'backend-fail-maxsize' => 'Die Datei $1 konnte nicht gespeichert werden, da sie größer als {{PLURAL:$2|ein Byte|$2 Bytes}} ist.',
 'backend-fail-readonly' => 'Das Speicher-Backend „$1“ befindet sich derzeit im Lesemodus. Der angegebene Grund lautet: „$2“',
 'backend-fail-synced' => 'Die Datei „$1“ befindet sich, innerhalb des internen Speicher-Backends, in einem inkonsistenten Zustand.',
 'backend-fail-connect' => 'Es konnte keine Verbindung zum Speicher-Backend „$1“ hergestellt werden.',
@@ -2193,7 +2195,7 @@ Jede Zeile enthält Links zur ersten und zweiten Weiterleitung sowie dem Ziel de
 'fewestrevisions' => 'Seiten mit den wenigsten Versionen',
 
 # Miscellaneous special pages
-'nbytes' => '$1 {{PLURAL:$1|Byte|Byte}}',
+'nbytes' => '$1 {{PLURAL:$1|Byte|Bytes}}',
 'ncategories' => '$1 {{PLURAL:$1|Kategorie|Kategorien}}',
 'ninterwikis' => '{{PLURAL:$1|Ein Interwikilink|$1 Interwikilinks}}',
 'nlinks' => '{{PLURAL:$1|1 Link|$1 Links}}',
@@ -2335,7 +2337,7 @@ Siehe auch die Liste der [[Special:WantedCategories|gewünschten Kategorien]].',
 # Special:ActiveUsers
 'activeusers' => 'Aktive Benutzer',
 '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|Bearbeitung|Bearbeitungen}} in den {{PLURAL:$3|letzten 24 Stunden|vergangenen $3 Tagen}}',
+'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',
@@ -2847,22 +2849,22 @@ Siehe die [[Special:BlockList|Liste der gesperrten IP-Adressen und Benutzernamen
 'movepagetext' => "Mit untenstehendem Formular kannst du eine Seite umbenennen, indem du sie mitsamt allen Versionen auf einen neuen Titel verschiebst.
 Der alte Titel wird danach zum neuen weiterleiten.
 Du kannst Weiterleitungen, die auf den Originaltitel verlinken, automatisch korrigieren lassen.
-Stelle sicher, dass du im Anschluss alle [[Special:DoubleRedirects|doppelten]] oder [[Special:BrokenRedirects|kaputten Weiterleitungen]] überprüfst.
+Stelle sicher, dass du im Anschluss alle [[Special:DoubleRedirects|doppelten]] oder [[Special:BrokenRedirects|defekten Weiterleitungen]] überprüfst.
 Du bist dafür verantwortlich, dass Links weiterhin auf das korrekte Ziel verweisen.
 
 Die Seite wird '''nicht''' verschoben, sofern es bereits eine Seite mit dem vorgesehenen Titel gibt, es sei denn, diese eine Weiterleitung ohne Versionsgeschichte.
-Dies bedeutet, dass du die Umbenennung rückgängig machen kannst, sofern du einen Fehler gemacht hast. Du kannst hingegen keine Seite überschreiben.
+Dies bedeutet, dass du die Umbenennung rückgängig machen kannst, sofern du einen Fehler gemacht hast. Du kannst hingegen keine existierende Seite überschreiben.
 
 '''Warnung!'''
 Die Verschiebung kann weitreichende und unerwartete Folgen für häufig besuchte Seiten haben.
 Du solltest daher die Konsequenzen verstanden haben, bevor du jetzt fortfährst.",
 'movepagetext-noredirectfixer' => "Mit untenstehendem Formular kannst du eine Seite umbenennen, indem du sie mitsamt allen Versionen auf einen neuen Titel verschiebst.
 Der alte Titel wird danach zum neuen weiterleiten.
-Stelle sicher, dass du im Anschluss alle [[Special:DoubleRedirects|doppelten]] oder [[Special:BrokenRedirects|kaputten Weiterleitungen]] überprüfst.
+Stelle sicher, dass du im Anschluss alle [[Special:DoubleRedirects|doppelten]] oder [[Special:BrokenRedirects|defekten Weiterleitungen]] überprüfst.
 Du bist dafür verantwortlich, dass Links weiterhin auf das korrekte Ziel verweisen.
 
 Die Seite wird '''nicht''' verschoben, sofern es bereits eine Seite mit dem vorgesehenen Titel gibt, es sei denn, diese ist eine Weiterleitung ohne Versionsgeschichte.
-Dies bedeutet, dass du die Umbenennung rückgängig machen kannst, sofern du einen Fehler gemacht hast. Du kannst hingegen keine Seite überschreiben.
+Dies bedeutet, dass du die Umbenennung rückgängig machen kannst, sofern du einen Fehler gemacht hast. Du kannst hingegen keine existierende Seite überschreiben.
 
 '''Warnung!'''
 Die Verschiebung kann weitreichende und unerwartete Folgen für häufig besuchte Seiten haben.
@@ -3193,15 +3195,16 @@ Das liegt wahrscheinlich an einem Link auf eine externe Seite.',
 'pageinfo-header-restrictions' => 'Seitenschutz',
 'pageinfo-header-properties' => 'Seiteneigenschaften',
 'pageinfo-display-title' => 'Anzeigetitel',
-'pageinfo-default-sort' => 'Standardsortierkriterium',
-'pageinfo-length' => 'Seitenlänge (in Byte)',
+'pageinfo-default-sort' => 'Standard-Sortierschlüssel',
+'pageinfo-length' => 'Seitenlänge (in Bytes)',
 'pageinfo-article-id' => 'Seitenkennnummer',
 'pageinfo-language' => 'Seiteninhaltssprache',
 'pageinfo-robot-policy' => 'Suchmaschinenstatus',
-'pageinfo-robot-index' => 'Indizierbar',
-'pageinfo-robot-noindex' => 'Nicht indizierbar',
+'pageinfo-robot-index' => 'Indexierbar',
+'pageinfo-robot-noindex' => 'Nicht indexierbar',
 'pageinfo-views' => 'Anzahl der Seitenaufrufe',
 'pageinfo-watchers' => 'Anzahl der Beobachter der Seite',
+'pageinfo-few-watchers' => 'Weniger als {{PLURAL:$1|ein|$1}} Beobachter',
 'pageinfo-redirects-name' => 'Weiterleitungen zu dieser Seite',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Unterseiten dieser Seite',
@@ -3534,7 +3537,7 @@ Weitere werden standardmäßig nicht angezeigt.
 'exif-compression-4' => 'CCITT Gruppe 4 Faxcodierung',
 
 'exif-copyrighted-true' => 'Geschützt',
-'exif-copyrighted-false' => 'Gemeinfrei',
+'exif-copyrighted-false' => 'Copyright Flag nicht gesetzt',
 
 'exif-unknowndate' => 'Unbekanntes Datum',
 
@@ -3934,7 +3937,8 @@ Du kannst auch die [[Special:EditWatchlist|Standardseite]] zum Bearbeiten benutz
 'version-variables' => 'Erweiterungen mit Variablen',
 'version-antispam' => 'Spamschutzerweiterungen',
 'version-skins' => 'Benutzeroberflächen',
-'version-other' => 'Andere Erweiterungen',
+'version-api' => 'API-Erweiterungen',
+'version-other' => 'Sonstige Erweiterungen',
 'version-mediahandlers' => 'Mediennutzungserweiterungen',
 'version-hooks' => "Schnittstellen ''(Hooks)''",
 'version-extension-functions' => 'Funktionsaufrufe',
@@ -3994,7 +3998,7 @@ Eine [{{SERVER}}{{SCRIPTPATH}}/COPYING Kopie der ''GNU General Public License'']
 'specialpages-group-highuse' => 'Häufig benutzte Seiten',
 'specialpages-group-pages' => 'Seitenlisten',
 'specialpages-group-pagetools' => 'Seitenwerkzeuge',
-'specialpages-group-wiki' => 'Systemdaten und Werkzeuge',
+'specialpages-group-wiki' => 'Daten und Werkzeuge',
 'specialpages-group-redirects' => 'Weiterleitende Spezialseiten',
 'specialpages-group-spam' => 'Spam-Werkzeuge',
 
@@ -4091,8 +4095,8 @@ Eine [{{SERVER}}{{SCRIPTPATH}}/COPYING Kopie der ''GNU General Public License'']
 'logentry-newusers-newusers' => 'Benutzerkonto $1 wurde erstellt',
 'logentry-newusers-create' => 'Benutzerkonto $1 wurde erstellt',
 'logentry-newusers-create2' => 'Benutzerkonto $3 wurde von $1 erstellt',
+'logentry-newusers-byemail' => 'Das Benutzerkonto $3 wurde von $1 erstellt und das Passwort wurde per E-Mail zugesandt',
 'logentry-newusers-autocreate' => 'Benutzerkonto $1 wurde automatisch erstellt',
-'newuserlog-byemail' => 'das Passwort wurde per E-Mail versandt',
 'logentry-rights-rights' => '$1 änderte die Gruppenzugehörigkeit für $3 von $4 zu $5',
 'logentry-rights-rights-legacy' => '$1 änderte die Gruppenzugehörigkeit für $3',
 'logentry-rights-autopromote' => '$1 wurde automatisch von $4 zu $5 zugeordnet',
@@ -4150,6 +4154,7 @@ Anderenfalls kannst du auch das untenstehende einfache Formular nutzen. Dein Kom
 'api-error-ok-but-empty' => 'Interner Fehler: Der Server reagiert nicht.',
 'api-error-overwrite' => 'Das Überschreiben einer vorhandenen Datei ist nicht erlaubt.',
 'api-error-stashfailed' => 'Interner Fehler: Der Server konnte keine temporäre Datei speichern.',
+'api-error-publishfailed' => 'Interner Fehler: Der Server konnte die temporäre Datei nicht veröffentlichen.',
 'api-error-timeout' => 'Der Server hat nicht innerhalb der erwarteten Zeit reagiert.',
 'api-error-unclassified' => 'Ein unbekannter Fehler ist aufgetreten.',
 'api-error-unknown-code' => 'Unbekannter Fehler: „$1“',
index ef4e093..95c7b88 100644 (file)
@@ -14,6 +14,7 @@
  * @author George Animal
  * @author Kaganer
  * @author Mirzali
+ * @author Nemo bis
  * @author Olvörg
  * @author Reedy
  * @author Sahim
@@ -51,15 +52,15 @@ $specialPageAliases = array(
        'Activeusers'               => array( 'KarberêAktivi', 'AktivKarberi' ),
        'Allmessages'               => array( 'MesaciPêro' ),
        'Allpages'                  => array( 'PeleyPêro' ),
-       'Ancientpages'              => array( 'PeleyVerêni' ),
+       'Ancientpages'              => array( 'PeleyKehani' ),
        'Badtitle'                  => array( 'SernameyoXırab' ),
-       'Blankpage'                 => array( 'PelaVeng', 'VengPela' ),
-       'Block'                     => array( 'Bloke', 'BlokeIP', 'BlokeKarber' ),
-       'Blockme'                   => array( 'BlokêMe' ),
+       'Blankpage'                 => array( 'PelêVengi' ),
+       'Block'                     => array( 'Bloqe', 'BloqeIP', 'BloqeyêKarber' ),
+       'Blockme'                   => array( 'BloqeyêMe' ),
        'Booksources'               => array( 'KıtabeÇıme' ),
        'BrokenRedirects'           => array( 'HetênayışoXırab' ),
-       'Categories'                => array( 'Kategoriye' ),
-       'ChangeEmail'               => array( 'EpostaBıvurnê' ),
+       'Categories'                => array( 'Kategoriy' ),
+       'ChangeEmail'               => array( 'EpostaVurnayış' ),
        'ChangePassword'            => array( 'ParolaBıvurnê', 'ParolaResetke' ),
        'ComparePages'              => array( 'PelaPêverke' ),
        'Confirmemail'              => array( 'EpostayAraştke' ),
@@ -67,9 +68,9 @@ $specialPageAliases = array(
        'CreateAccount'             => array( 'HesabVırazê' ),
        'Deadendpages'              => array( 'PelaBıgirê' ),
        'DeletedContributions'      => array( 'İştıraqêkeBesterneyayê' ),
-       'Disambiguations'           => array( 'ManeoBin' ),
-       'DoubleRedirects'           => array( 'DıletHeteneayış' ),
-       'EditWatchlist'             => array( 'ListeyaTemaşiVurnayış' ),
+       'Disambiguations'           => array( 'Arêzekerdış' ),
+       'DoubleRedirects'           => array( 'HetanayışoDılet' ),
+       'EditWatchlist'             => array( 'ListeyaSeyrkerdışiVurnayış' ),
        'Emailuser'                 => array( 'EpostayaKarberi' ),
        'Export'                    => array( 'Ateberde' ),
        'Fewestrevisions'           => array( 'TewrtaynRevizyon' ),
@@ -77,33 +78,34 @@ $specialPageAliases = array(
        'Filepath'                  => array( 'RayaDosya', 'HerunaDosya', 'CayêDosya' ),
        'Import'                    => array( 'Azeredê', 'Atewrke' ),
        'Invalidateemail'           => array( 'EpostaAraştkerdışiBıterknê' ),
-       'BlockList'                 => array( 'ListeyêBloki', 'IPBloki', 'Blokeyê_IP' ),
+       'BlockList'                 => array( 'ListeyêBloqi', 'IPBloqi', 'Blokqeyê_IP' ),
        'LinkSearch'                => array( 'GreCıgeyrayış' ),
-       'Listadmins'                => array( 'ListeyêXizmetkaran' ),
-       'Listbots'                  => array( 'ListeyêBotan' ),
-       'Listfiles'                 => array( 'ListeyêDosyayan', 'DosyayaListeke', 'ListeyêResiman' ),
-       'Listgrouprights'           => array( 'ListeyêHeqêGruban', 'HeqêGrubdeKarberan' ),
-       'Listredirects'             => array( 'ListeyêHetanayışi' ),
-       'Listusers'                 => array( 'ListeyêKarberan', 'KarberaListeke' ),
+       'Listadmins'                => array( 'ListeyaSerkaran' ),
+       'Listbots'                  => array( 'ListeyaBotan' ),
+       'Listfiles'                 => array( 'ListeyaDosyayan', 'DosyayaListeke', 'ListeyêResiman' ),
+       'Listgrouprights'           => array( 'ListeyaHeqandêGruban', 'HeqêGrubdeKarberan' ),
+       'Listredirects'             => array( 'ListeyaArêzekerdışan' ),
+       'Listusers'                 => array( 'ListeyaKarberan', 'KarberaListeke' ),
        'Lockdb'                    => array( 'DBKilitke' ),
        'Log'                       => array( 'Qeyd', 'Qeydi' ),
-       'Lonelypages'               => array( 'PeleyêBêkesi' ),
-       'Longpages'                 => array( 'PeleyeDergi' ),
-       'MergeHistory'              => array( 'RavêrdaPêtewrke' ),
+       'Lonelypages'               => array( 'PeleyêBêwayıri' ),
+       'Longpages'                 => array( 'PeleyêDergi' ),
+       'MergeHistory'              => array( 'VerênanPêtewrke' ),
        'MIMEsearch'                => array( 'NIMECıgeyrayış' ),
        'Mostcategories'            => array( 'TewrvêşiKategoriyıni' ),
        'Mostimages'                => array( 'DosyeyêkeCırêvêşiGreDeyayo' ),
+       'Mostinterwikis'            => array( 'TewrvêşiTeberwiki' ),
        'Mostlinked'                => array( 'PeleyêkeCırêvêşiGreDeyayo' ),
        'Mostlinkedcategories'      => array( 'KategoriyêkeCırêvêşiGreDeyayo' ),
        'Mostlinkedtemplates'       => array( 'ŞablonêkeCırêvêşiGreDeyayo' ),
        'Mostrevisions'             => array( 'TewrvêşiRevizyon' ),
-       'Movepage'                  => array( 'PelaAhulne' ),
-       'Mycontributions'           => array( 'İştıraqeMe' ),
-       'Mypage'                    => array( 'PelaMe' ),
-       'Mytalk'                    => array( 'PersiyeMe' ),
+       'Movepage'                  => array( 'PelerBerê' ),
+       'Mycontributions'           => array( 'İştıraqêMe' ),
+       'Mypage'                    => array( 'PeleyêMe' ),
+       'Mytalk'                    => array( 'WerênayışêMe' ),
        'Myuploads'                 => array( 'BarkerdışeMe' ),
        'Newimages'                 => array( 'DosyeyêNewey', 'ResimêNewey' ),
-       'Newpages'                  => array( 'PeleyeNewey' ),
+       'Newpages'                  => array( 'PeleyêNewey' ),
        'PasswordReset'             => array( 'ParolaResetkerdış' ),
        'PermanentLink'             => array( 'GreyoDaimi' ),
        'Popularpages'              => array( 'PeleyêPopuleri' ),
@@ -118,7 +120,7 @@ $specialPageAliases = array(
        'Revisiondelete'            => array( 'RevizyoniBesterne' ),
        'Search'                    => array( 'Cıgeyre' ),
        'Shortpages'                => array( 'PeleyêKılmi' ),
-       'Specialpages'              => array( 'PeleyXısusi' ),
+       'Specialpages'              => array( 'PeleyêXısusi' ),
        'Statistics'                => array( 'İstatistiki' ),
        'Tags'                      => array( 'Etiketi' ),
        'Unblock'                   => array( 'BloqiWedarne' ),
@@ -127,14 +129,14 @@ $specialPageAliases = array(
        'Uncategorizedpages'        => array( 'PeleyêkeKategorinêbiyê' ),
        'Uncategorizedtemplates'    => array( 'ŞablonêkeKategorinêbiyê' ),
        'Undelete'                  => array( 'Peyserbiya' ),
-       'Unlockdb'                  => array( 'DBSırmiake' ),
+       'Unlockdb'                  => array( 'DBKılitiAke' ),
        'Unusedcategories'          => array( 'KategoriyêkeNêkaryayê' ),
        'Unusedimages'              => array( 'DosyeyêkeNêkaryayê' ),
        'Unusedtemplates'           => array( 'ŞablonêkeNêkaryayê' ),
        'Unwatchedpages'            => array( 'PeleyêkeNêweyneyênê' ),
-       'Upload'                    => array( 'Barke' ),
+       'Upload'                    => array( 'Barkerdış' ),
        'UploadStash'               => array( 'BarkerdışêNımtey' ),
-       'Userlogin'                 => array( 'KarberDekewtış' ),
+       'Userlogin'                 => array( 'Karberkewtış' ),
        'Userlogout'                => array( 'KarberVıcyayış' ),
        'Userrights'                => array( 'HeqêKarberan', 'SysopKerdış', 'BotKerdış' ),
        'Version'                   => array( 'Versiyon' ),
@@ -142,7 +144,7 @@ $specialPageAliases = array(
        'Wantedfiles'               => array( 'DosyeyêkeWazênê' ),
        'Wantedpages'               => array( 'PeleyêkeWazênê' ),
        'Wantedtemplates'           => array( 'ŞablonêkeWazênê' ),
-       'Watchlist'                 => array( 'Listeyseyri' ),
+       'Watchlist'                 => array( 'ListaSeyri' ),
        'Whatlinkshere'             => array( 'PelarêGre' ),
        'Withoutinterwiki'          => array( 'Bêİnterwiki' ),
 );
@@ -300,6 +302,7 @@ $magicWords = array(
        'defaultsort_noreplace'     => array( '0', 'cewabçıniyo', 'noreplace' ),
        'pagesincategory_all'       => array( '0', 'pêro', 'all' ),
        'pagesincategory_pages'     => array( '0', 'peley', 'pages' ),
+       'pagesincategory_subcats'   => array( '0', 'bınkati', 'subcats' ),
        'pagesincategory_files'     => array( '0', 'dosyey', 'files' ),
 );
 
@@ -1179,7 +1182,7 @@ Eke şıma serkari u devam bıkeri [$1 no vurnayiş şıma eşkeni bıvini].",
 Îdarekarî eşkeno ena dif bivîne; belki tiya de [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ploxnayış] de teferruat esto.",
 'rev-delundel' => 'bımocne/bınımne',
 'rev-showdeleted' => 'bımocne',
-'revisiondelete' => 'Bıestere/çımraviyarnayışan peyser bia',
+'revisiondelete' => 'Bestere/çımraviyarnayışan peyser bia',
 'revdelete-nooldid-title' => 'Çımraviyarnayışo waşte nêvêreno',
 'revdelete-nooldid-text' => 'Şıma vıraştışê nê fonksiyoni rê ya yew çımraviyarnayışo waşte diyar nêkerdo, çımraviyarnayışo diyarkerde çıniyo, ya ki şıma wazenê ke çımraviyarnayışê nıkayêni bınımnê.',
 'revdelete-nologtype-title' => 'Qet qeydê cınêdiya',
@@ -1555,7 +1558,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'right-reupload-own' => 'Dosyeyê ke to bar kerdi, inan sero bınuse',
 'right-reupload-shared' => 'Dosyeyê ke ambarê medyao barekerde de, inan mehelli wedare',
 'right-upload_by_url' => 'Yew URL ra dosyan bar bıke',
-'right-purge' => 'Verde ju pela araşt kerdışi hafızay sita besterne',
+'right-purge' => 'Virê sita seba yew pele bêdestur bestere.',
 'right-autoconfirmed' => 'Pelanê ke nême kılit biyê, inan bıvurne',
 'right-bot' => 'Zey yew karê xoserkerdey be',
 'right-nominornewtalk' => 'Pelanê werênayışan rê vurnayışê qıckeki çıniyê, qutiya mesacanê newiyan bıgurene',
@@ -1625,7 +1628,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'action-upload_by_url' => 'Ena dosya yew URL ra bar bike',
 'action-writeapi' => 'ser nuşte API gure bike',
 'action-delete' => 'ena perer besternê',
-'action-deleterevision' => 'nê çımraviyarnayışi bıestere',
+'action-deleterevision' => 'nê çımraviyarnayışi bestere',
 'action-deletedhistory' => 'tarixê ena pel ki estereyî biya, ey bivine',
 'action-browsearchive' => 'pelanê esterıteyan bıgeyre',
 'action-undelete' => 'ena pele reyna biyere',
@@ -1935,7 +1938,7 @@ bıewnê keyepel akerdeyo ya zi bıne vınderê u newe ra tesel bıkerê.
 keyepel nıka zaf meşğulo yew dema herayi de newe ra tesel bıkerê.',
 
 'license' => 'Lisans:',
-'license-header' => 'Lisans',
+'license-header' => 'Lisansdayış',
 'nolicense' => 'Theba nêweçineya',
 'license-nopreview' => '(verqeydî çin o)',
 'upload_source_url' => '(yew URLê raştî, şar rê akerde yo)',
@@ -1958,7 +1961,7 @@ keyepel nıka zaf meşğulo yew dema herayi de newe ra tesel bıkerê.',
 'file-anchor-link' => 'Dosya',
 'filehist' => 'Ravêrdê dosya',
 'filehist-help' => 'bıploxne ser yew tarih u aye tarih dı versionê dosya bıvin.',
-'filehist-deleteall' => 'hemî biestere',
+'filehist-deleteall' => 'pêro bestere',
 'filehist-deleteone' => 'bestere',
 'filehist-revert' => 'reyna biyere',
 'filehist-current' => 'nıkayên',
@@ -2007,8 +2010,8 @@ listeya ke ha ver a têna na {{PLURAL:$1|dosyaya ewwili|dosyaya $1 ewwili}} mocn
 'filerevert-badversion' => 'Vesiyonê lokalê verniyê eno dosya pê ena pulêwext de çin o.',
 
 # File deletion
-'filedelete' => '$1 bıestere',
-'filedelete-legend' => 'Dosya bıestere',
+'filedelete' => '$1 bestere',
+'filedelete-legend' => 'Dosya bestere',
 'filedelete-intro' => "Ti ho dosyayê '''[[Media:$1|$1]]'''i u tarixê ey dosyayê hemî estereno.",
 'filedelete-intro-old' => "Ti ho versiyonê '''[[Media:$1|$1]]'''i [$4 $3, $2] estereno.",
 'filedelete-comment' => 'Sebeb:',
@@ -2391,13 +2394,13 @@ Qey hemkari u pêşniyazi:
 'changed' => 'vurneya',
 
 # Delete
-'deletepage' => 'Pele bıestere',
+'deletepage' => 'Pele bestere',
 'confirm' => 'Testiq ke',
 'excontent' => "behso kêm: '$1'",
 'excontentauthor' => "behso kêm: '$1' no/na ('[[Special:Contributions/$2|$2]]'  teyna iştıraq kerdo)",
 'exbeforeblank' => "behsê verê esteriyayişi: '$1'",
 'exblank' => 'zerreyê peli vengo',
-'delete-confirm' => '"$1" bıestere',
+'delete-confirm' => '"$1" bestere',
 'delete-legend' => 'Bestere',
 'historywarning' => "'''Teme:''' Pela ke şıma esterenê tede yew viyarte be teqriben $1 {{PLURAL:$1|versiyon esto|versiyoni estê}}:",
 'confirmdeletetext' => 'Tı ho yew pele u tarixê pele wederneno.
@@ -2837,11 +2840,11 @@ Yewna name bınus.',
 'movenosubpage' => 'pelê bınıni yê no peli çino.',
 'movereason' => 'Sebeb:',
 'revertmove' => 'peyser bia',
-'delete_and_move' => 'Biestere u bere',
+'delete_and_move' => 'Bestere u bere',
 'delete_and_move_text' => '==gani hewn a bıbıo/bıesteriyo==
 
 " no [[:$1]]" name de yew pel ca ra esto. şıma wazeni pê hewn a kerdışê ey peli vurnayişê nameyi bıkeri?',
-'delete_and_move_confirm' => 'Ya, ena pele biestere',
+'delete_and_move_confirm' => 'Heya, na pele bestere',
 'delete_and_move_reason' => '"[[$1]]" qey vurnayişê nameyi esteriya',
 'selfmove' => 'name yo ke şıma wazeni bıbo, ın name û name yo ke ca ra esto eyni yê /zepê yê. vurnayiş mumkin niyo.',
 'immobile-source-namespace' => '"$1" pelê cayi de nameyi nêkırışyenî',
@@ -3058,517 +3061,7 @@ Tı eşkeno yew sebeb bınus.',
 'tooltip-summary' => 'Yew xulasaya kilm binuse',
 
 # Scripts
-'common.js' => "/**
- * Keep code in MediaWiki:Common.js to a minimum as it is unconditionally
- * loaded for all users on every wiki page. If possible create a gadget that is
- * enabled by default instead of adding it here (since gadgets are fully
- * optimized ResourceLoader modules with possibility to add dependencies etc.)
- *
- * Since common.js isn't a gadget, there is no place to declare its
- * dependencies, so we have to lazy load them with mw.loader.using on demand and
- * then execute the rest in the callback. In most cases these dependencies will
- * be loaded (or loading) already and the callback will not be delayed. In case a
- * dependency hasn't arrived yet it'll make sure those are loaded before this.
- */
-mw.loader.using( 'mediawiki.util', function() {
-/* Begin of mw.loader.using callback */
-
-/**
- * Redirect User:Name/skin.js and skin.css to the current skin's pages
- * (unless the 'skin' page really exists)
- * @source: http://www.mediawiki.org/wiki/Snippets/Redirect_skin.js
- * @rev: 2
- */
-if ( mw.config.get( 'wgArticleId' ) === 0 && mw.config.get( 'wgNamespaceNumber' ) == 2 ) {
-       var titleParts = mw.config.get( 'wgPageName' ).split( '/' );
-       // Make sure there was a part before and after the slash
-       // And that the latter is 'skin.js' or 'skin.css'
-       if ( titleParts.length == 2 ) {
-               var userSkinPage = titleParts.shift() + '/' + mw.config.get( 'skin' );
-               if ( titleParts.slice(-1) == 'skin.js' ) {
-                       window.location.href = mw.util.wikiGetlink( userSkinPage + '.js' );
-               } else if ( titleParts.slice(-1) == 'skin.css' ) {
-                       window.location.href = mw.util.wikiGetlink( userSkinPage + '.css' );
-               }
-       }
-}
-
-/** Map addPortletLink to mw.util 
- */
-window.addPortletLink = function() {
-    return mw.util.addPortletLink.apply( mw.util, arguments );
-};
-
-/** extract a URL parameter from the current URL **********
- *
- * @deprecated: Use mw.util.getParamValue with proper escaping
- */
-window.getURLParamValue = function() {
-    return mw.util.getParamValue.apply( mw.util, arguments );
-};
-
-/** &withCSS= and &withJS= URL parameters *******
- * Allow to try custom scripts from MediaWiki space 
- * without editing personal .css or .js files
- */
-var extraCSS = mw.util.getParamValue(\"withCSS\");
-if ( extraCSS && extraCSS.match(/^MediaWiki:[^&<>=%]*\\.css\$/) ) {
-    importStylesheet(extraCSS);
-}
-var extraJS = mw.util.getParamValue(\"withJS\");
-if ( extraJS && extraJS.match(/^MediaWiki:[^&<>=%]*\\.js\$/) ) {
-    importScript(extraJS);
-}
-
-
-/* Import more specific scripts if necessary */
-if (wgAction == 'edit' || wgAction == 'submit' || wgPageName == 'Special:Upload') { //scripts specific to editing pages
-    importScript('MediaWiki:Common.js/edit.js');
-}
-else if (mw.config.get('wgPageName') == 'Special:Watchlist') { //watchlist scripts
-    mw.loader.load(mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=MediaWiki:Common.js/watchlist.js&action=raw&ctype=text/javascript&smaxage=21600&maxage=86400');
-}
-
-if ( wgNamespaceNumber == 6 ) {
-    importScript('MediaWiki:Common.js/file.js');
-}
-
-/**
- * WikiMiniAtlas
- *
- *  Description: WikiMiniAtlas is a popup click and drag world map.
- *               This script causes all of our coordinate links to display the WikiMiniAtlas popup button.
- *               The script itself is located on meta because it is used by many projects.
- *               See [[Meta:WikiMiniAtlas]] for more information. 
- *  Maintainers: [[User:Dschwen]]
- */
-
-mw.loader.load('//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript&smaxage=21600&maxage=86400');
-
-/* Scripts specific to Internet Explorer */
-if (\$.client.profile().name == 'msie') {
-    /** Internet Explorer bug fix **************************************************
-     *
-     *  Description: Fixes IE horizontal scrollbar bug
-     *  Maintainers: [[User:Tom-]]?
-     */
-    
-    var oldWidth;
-    var docEl = document.documentElement;
-    
-    var fixIEScroll = function() {
-        if (!oldWidth || docEl.clientWidth > oldWidth) {
-            doFixIEScroll();
-        } else {
-            setTimeout(doFixIEScroll, 1);
-        }
-        
-        oldWidth = docEl.clientWidth;
-    };
-    
-    var doFixIEScroll = function () {
-        docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? \"hidden\" : \"\";
-    };
-    
-    document.attachEvent(\"onreadystatechange\", fixIEScroll);
-    document.attachEvent(\"onresize\", fixIEScroll);
-    
-    // In print IE (7?) does not like line-height
-    mw.util.addCSS('@media print { sup, sub, p, .documentDescription { line-height: normal; } }');
-
-    // IE overflow bug
-    mw.util.addCSS('div.overflowbugx { overflow-x: scroll !important; overflow-y: hidden !important; } '
-      + 'div.overflowbugy { overflow-y: scroll !important; overflow-x: hidden !important; }');
-
-    // IE zoomfix
-    // Use to fix right floating div/table inside tables
-    mw.util.addCSS('.iezoomfix div, .iezoomfix table { zoom: 1; }');
-
-    // Import scripts specific to Internet Explorer 6
-    if (\$.client.profile().versionBase == '6') {
-        importScript('MediaWiki:Common.js/IE60Fixes.js');
-    }
-}
-
-/* Fixes for Windows XP font rendering */
-if (navigator.appVersion.search(/windows nt 5/i) != -1) {
-    mw.util.addCSS('.IPA {font-family: \"Lucida Sans Unicode\", \"Arial Unicode MS\";} ' + 
-                   '.Unicode {font-family: \"Arial Unicode MS\", \"Lucida Sans Unicode\";}');
-}
-
-/* Helper script for .hlist class in Common.css
- * Last updated: September 12, 2012
- * Maintainer: [[User:Edokter]]
- */
-if ( \$.client.profile().name == 'msie' ) {
-    /* Add pseudo-selector class to last-child list items in IE 8 */
-    if ( \$.client.profile().versionBase == '8' ) {
-        \$( '.hlist' ).find( 'dd:last-child, dt:last-child, li:last-child' )
-            .addClass( 'hlist-last-child' );
-    }
-    /* Generate interpuncts and parens for IE < 8 */
-    if ( \$.client.profile().versionBase < '8' ) {
-        var hlists = \$( '.hlist' );
-        hlists.find( 'dt:not(:last-child)' )
-            .append( ': ' );
-        hlists.find( 'dd:not(:last-child)' )
-            .append( '<b>·</b> ' );
-        hlists.find( 'li:not(:last-child)' )
-            .append( '<b>·</b> ' );
-        hlists.find( 'dl dl, ol ol, ul ul' )
-            .prepend( '( ' ).append( ') ' );
-    }
-}
-
-/* Test if an element has a certain class
- * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
- *
- * @deprecated:  Use \$(element).hasClass() instead.
- */
-
-window.hasClass = ( function() {
-    var reCache = {};
-    return function (element, className) {
-        return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp(\"(?:\\\\s|^)\" + className + \"(?:\\\\s|\$)\"))).test(element.className);
-    };
-})();
-
-
-/** Interwiki links to featured articles ***************************************
- *
- *  Description: Highlights interwiki links to featured articles (or
- *               equivalents) by changing the bullet before the interwiki link
- *               into a star.
- *  Maintainers: [[User:R. Koot]]
- */
-
-function LinkFA() {
-    if ( document.getElementById( \"p-lang\" ) ) {
-        var InterwikiLinks = document.getElementById( \"p-lang\" ).getElementsByTagName( \"li\" );
-
-        for ( var i = 0; i < InterwikiLinks.length; i++ ) {
-            if ( document.getElementById( InterwikiLinks[i].className + \"-fa\" ) ) {
-                InterwikiLinks[i].className += \" FA\";
-                InterwikiLinks[i].title = \"This is a featured article in another language.\";
-            } else if ( document.getElementById( InterwikiLinks[i].className + \"-ga\" ) ) {
-                InterwikiLinks[i].className += \" GA\";
-                InterwikiLinks[i].title = \"This is a good article in another language.\";
-            }
-        }
-    }
-}
-
-\$( LinkFA );
-
-
-/** Collapsible tables *********************************************************
- *
- *  Description: Allows tables to be collapsed, showing only the header. See
- *               [[Wikipedia:NavFrame]].
- *  Maintainers: [[User:R. Koot]]
- */
-
-var autoCollapse = 2;
-var collapseCaption = \"bınımne\";
-var expandCaption = \"bıvin\";
-
-window.collapseTable = function( tableIndex ){
-    var Button = document.getElementById( \"collapseButton\" + tableIndex );
-    var Table = document.getElementById( \"collapsibleTable\" + tableIndex );
-
-    if ( !Table || !Button ) {
-        return false;
-    }
-
-    var Rows = Table.rows;
-
-    if ( Button.firstChild.data == collapseCaption ) {
-        for ( var i = 1; i < Rows.length; i++ ) {
-            Rows[i].style.display = \"none\";
-        }
-        Button.firstChild.data = expandCaption;
-    } else {
-        for ( var i = 1; i < Rows.length; i++ ) {
-            Rows[i].style.display = Rows[0].style.display;
-        }
-        Button.firstChild.data = collapseCaption;
-    }
-}
-
-function createCollapseButtons(){
-    var tableIndex = 0;
-    var NavigationBoxes = new Object();
-    var Tables = document.getElementsByTagName( \"table\" );
-
-    for ( var i = 0; i < Tables.length; i++ ) {
-        if ( hasClass( Tables[i], \"collapsible\" ) ) {
-
-            /* only add button and increment count if there is a header row to work with */
-            var HeaderRow = Tables[i].getElementsByTagName( \"tr\" )[0];
-            if (!HeaderRow) continue;
-            var Header = HeaderRow.getElementsByTagName( \"th\" )[0];
-            if (!Header) continue;
-
-            NavigationBoxes[ tableIndex ] = Tables[i];
-            Tables[i].setAttribute( \"id\", \"collapsibleTable\" + tableIndex );
-
-            var Button     = document.createElement( \"span\" );
-            var ButtonLink = document.createElement( \"a\" );
-            var ButtonText = document.createTextNode( collapseCaption );
-
-            Button.className = \"collapseButton\";  //Styles are declared in Common.css
-
-            ButtonLink.style.color = Header.style.color;
-            ButtonLink.setAttribute( \"id\", \"collapseButton\" + tableIndex );
-            ButtonLink.setAttribute( \"href\", \"#\" );
-            addHandler( ButtonLink,  \"click\", new Function( \"evt\", \"collapseTable(\" + tableIndex + \" ); return killEvt( evt );\") );
-            ButtonLink.appendChild( ButtonText );
-
-            Button.appendChild( document.createTextNode( \"[\" ) );
-            Button.appendChild( ButtonLink );
-            Button.appendChild( document.createTextNode( \"]\" ) );
-
-            Header.insertBefore( Button, Header.firstChild );
-            tableIndex++;
-        }
-    }
-
-    for ( var i = 0;  i < tableIndex; i++ ) {
-        if ( hasClass( NavigationBoxes[i], \"collapsed\" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], \"autocollapse\" ) ) ) {
-            collapseTable( i );
-        } 
-        else if ( hasClass( NavigationBoxes[i], \"innercollapse\" ) ) {
-            var element = NavigationBoxes[i];
-            while (element = element.parentNode) {
-                if ( hasClass( element, \"outercollapse\" ) ) {
-                    collapseTable ( i );
-                    break;
-                }
-            }
-        }
-    }
-}
-
-\$( createCollapseButtons );
-
-
-/** Dynamic Navigation Bars (experimental) *************************************
- *
- *  Description: See [[Wikipedia:NavFrame]].
- *  Maintainers: UNMAINTAINED
- */
-
-// set up the words in your language
-var NavigationBarHide = '[' + collapseCaption + ']';
-var NavigationBarShow = '[' + expandCaption + ']';
-
-// shows and hides content and picture (if available) of navigation bars
-// Parameters:
-//     indexNavigationBar: the index of navigation bar to be toggled
-window.toggleNavigationBar = function(indexNavigationBar){
-    var NavToggle = document.getElementById(\"NavToggle\" + indexNavigationBar);
-    var NavFrame = document.getElementById(\"NavFrame\" + indexNavigationBar);
-
-    if (!NavFrame || !NavToggle) {
-        return false;
-    }
-
-    // if shown now
-    if (NavToggle.firstChild.data == NavigationBarHide) {
-        for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
-            if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
-                NavChild.style.display = 'none';
-            }
-        }
-    NavToggle.firstChild.data = NavigationBarShow;
-
-    // if hidden now
-    } else if (NavToggle.firstChild.data == NavigationBarShow) {
-        for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
-            if (hasClass(NavChild, 'NavContent') || hasClass(NavChild, 'NavPic')) {
-                NavChild.style.display = 'block';
-            }
-        }
-        NavToggle.firstChild.data = NavigationBarHide;
-    }
-}
-
-// adds show/hide-button to navigation bars
-function createNavigationBarToggleButton(){
-    var indexNavigationBar = 0;
-    // iterate over all < div >-elements 
-    var divs = document.getElementsByTagName(\"div\");
-    for (var i = 0; NavFrame = divs[i]; i++) {
-        // if found a navigation bar
-        if (hasClass(NavFrame, \"NavFrame\")) {
-
-            indexNavigationBar++;
-            var NavToggle = document.createElement(\"a\");
-            NavToggle.className = 'NavToggle';
-            NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
-            NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
-
-            var isCollapsed = hasClass( NavFrame, \"collapsed\" );
-            /*
-             * Check if any children are already hidden.  This loop is here for backwards compatibility:
-             * the old way of making NavFrames start out collapsed was to manually add style=\"display:none\"
-             * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
-             * the content visible without JavaScript support), the new recommended way is to add the class
-             * \"collapsed\" to the NavFrame itself, just like with collapsible tables.
-             */
-            for (var NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling) {
-                if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
-                    if ( NavChild.style.display == 'none' ) {
-                        isCollapsed = true;
-                    }
-                }
-            }
-            if (isCollapsed) {
-                for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
-                    if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) {
-                        NavChild.style.display = 'none';
-                    }
-                }
-            }
-            var NavToggleText = document.createTextNode(isCollapsed ? NavigationBarShow : NavigationBarHide);
-            NavToggle.appendChild(NavToggleText);
-
-            // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
-            for(var j=0; j < NavFrame.childNodes.length; j++) {
-                if (hasClass(NavFrame.childNodes[j], \"NavHead\")) {
-                    NavToggle.style.color = NavFrame.childNodes[j].style.color;
-                    NavFrame.childNodes[j].appendChild(NavToggle);
-                }
-            }
-            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
-        }
-    }
-}
-
-\$( createNavigationBarToggleButton );
-
-
-/** Main Page layout fixes *********************************************************
- *
- *  Description: Adds an additional link to the complete list of languages available.
- *  Maintainers: [[User:AzaToth]], [[User:R. Koot]], [[User:Alex Smotrov]]
- */
-
-if (wgPageName == 'Main_Page' || wgPageName == 'Talk:Main_Page') {
-    \$(function () {
-        mw.util.addPortletLink('p-lang', '//meta.wikimedia.org/wiki/List_of_Wikipedias',
-            'Complete list', 'interwiki-completelist', 'Complete list of Wikipedias');
-    });
-}
-
-
-/** Table sorting fixes ************************************************
-  *
-  *  Description: Disables code in table sorting routine to set classes on even/odd rows
-  *  Maintainers: [[User:Random832]]
-  */
-ts_alternate_row_colors = false;
-
-
-/***** uploadwizard_newusers ********
- * Switches in a message for non-autoconfirmed users at [[Wikipedia:Upload]]
- *
- *  Maintainers: [[User:Krimpet]]
- */
-function uploadwizard_newusers() {
-  if (wgNamespaceNumber == 4 && wgTitle == \"Upload\" && wgAction == \"view\") {
-    var oldDiv = document.getElementById(\"autoconfirmedusers\"),
-        newDiv = document.getElementById(\"newusers\");
-    if (oldDiv && newDiv) {
-      if (typeof wgUserGroups == \"object\" && wgUserGroups) {
-        for (i = 0; i < wgUserGroups.length; i++) {
-          if (wgUserGroups[i] == \"autoconfirmed\") {
-            oldDiv.style.display = \"block\";
-            newDiv.style.display = \"none\";
-            return;
-          }
-        }
-      }
-      oldDiv.style.display = \"none\";
-      newDiv.style.display = \"block\";
-      return;
-    }
-  }
-}
-\$(uploadwizard_newusers);
-
-
-/** IPv6 AAAA connectivity testing 
-
-var __ipv6wwwtest_factor = 100;
-var __ipv6wwwtest_done = 0;
-if ((wgServer != \"https://secure.wikimedia.org\") && (Math.floor(Math.random()*__ipv6wwwtest_factor)==42)) {
-    importScript(\"MediaWiki:Common.js/IPv6.js\");
-}
-**/
-
-/** Magic editintros ****************************************************
- *
- *  Description: Adds editintros on disambiguation pages and BLP pages.
- *  Maintainers: [[User:RockMFR]]
- */
-
-function addEditIntro( name ) {
-  \$( '.editsection, #ca-edit' ).find( 'a' ).each( function( i, el ) {
-    el.href = \$(this).attr(\"href\") + '&editintro=' + name;
-  });
-}
-
-if (wgNamespaceNumber === 0) {
-  \$(function(){
-    if (document.getElementById('disambigbox')) {
-      addEditIntro('Template:Disambig_editintro');
-    }
-  });
-
-  \$(function(){
-    var cats = document.getElementById('mw-normal-catlinks');
-    if (!cats) {
-      return;
-    }
-    cats = cats.getElementsByTagName('a');
-    for (var i = 0; i < cats.length; i++) {
-      if (cats[i].title == 'Category:Living people' || cats[i].title == 'Category:Possibly living people') {
-        addEditIntro('Template:BLP_editintro');
-        break;
-      }
-    }
-  });
-}
-
-/**
- * Description: Stay on the secure server as much as possible
- * Maintainers: [[User:TheDJ]]
- */
-if ( mw.config.get('wgServer') == 'https://secure.wikimedia.org' ) {
-    /* Old secure server */
-    importScript( 'MediaWiki:Common.js/secure.js');
-} else if( document.location && document.location.protocol  && document.location.protocol == \"https:\" ) {
-  /* New secure servers */
-  importScript('MediaWiki:Common.js/secure new.js');
-}
-
-/**
-  * Description: Fix the toggle for Mobile view
-  * https://bugzilla.wikimedia.org/show_bug.cgi?id=38009
-  * Maintainer: [[User:TheDJ]]
-  */
-mw.loader.using( 'jquery.cookie', function() {
-    \$('a[href\$=\"toggle_view_mobile\"]').click(function(){
-        document.cookie = 'stopMobileRedirect=false; domain=.wikipedia.org;'
-                    + 'path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT;'
-    });
-});
-
-/* End of mw.loader.using callback */
-} );
-/* DO NOT ADD CODE BELOW THIS LINE */",
+'common.js' => '/* Any JavaScript here will be loaded for all users on every page load. */',
 
 # Metadata
 'notacceptable' => "formatê ma'lumati no peşkeşwanê wikiyi nêweniyeno.",
@@ -3727,6 +3220,8 @@ Gurênayışê nae de, beno ke sistemê şıma zerar bıvêno.",
 'minutes' => 'verdê {{PLURAL:$1|$1 daka|$1 daka}}',
 'hours' => 'Verdê {{PLURAL:$1|$1 seata|$1 seata}}',
 'days' => 'Verdê {{PLURAL:$1|$1 rocan|$1 rocan}}',
+'months' => '{{PLURAL:$1|aşmi|$1 aşman}}',
+'years' => '{{PLURAL:$1|$1 ser|$1 seran}}',
 'ago' => 'Verdê $1',
 'just-now' => 'Hema newke',
 
@@ -4338,7 +3833,7 @@ Ma rica keno tesdiq bike ke ti raştî wazeno eno pel bivirazo.",
 
 # action=purge
 'confirm_purge_button' => 'Temam',
-'confirm-purge-top' => 'Cacheyê eno pel biestere?',
+'confirm-purge-top' => 'Vervirê na pele bestere?',
 'confirm-purge-bottom' => 'Purge kerdişê yew pel cacheyî estereno u revizyonê penîyî mucneno.',
 
 # action=watch/unwatch
@@ -4677,7 +4172,6 @@ Ena sita dı newke xırabiya teknik esta.',
 'logentry-newusers-create' => 'Hesabê karberi $1 vıraziya',
 'logentry-newusers-create2' => 'Hesabê karberi $1 terefê $3 ra vıraziya',
 'logentry-newusers-autocreate' => 'Hesabê $1 Otomatikmen vıraziya',
-'newuserlog-byemail' => 'pê e-mail ra paralo şiravt',
 'logentry-rights-rights' => '$1 qandê $3 rê ezayina grube $4 ra $5 vuriye',
 'logentry-rights-rights-legacy' => '$1 qandê $3 rê ezayina grube vuriye',
 'logentry-rights-autopromote' => '$1 otomatikmen $4 ra terfi bi ra $5',
index 91f9190..76cae46 100644 (file)
@@ -588,7 +588,7 @@ Móžoš {{SITENAME}} anomymnje dalej wužywaś abo móžoš <span class='plainl
 'gotaccount' => "Maš južo wužywarske konto? '''$1'''.",
 'gotaccountlink' => 'Pśizjawiś se',
 'userlogin-resetlink' => 'Sy pśizjawjeńske daty zabył?',
-'createaccountmail' => 'z e-mailku',
+'createaccountmail' => 'Nachylne pśidatne gronidło wužywaś a jo na slědujucu e-mailowu adresu pósłaś',
 'createaccountreason' => 'Pśicyna:',
 'badretype' => 'Šćitnej gronidle, kótarejž sy zapódał, se njemakajotej.',
 'userexists' => 'Wužywarske mě se južo wužywa.
@@ -795,7 +795,7 @@ Jo se snaź pśesunuł abo wulašował, mjaztym až woglědujoš se bok.',
 Gronidło za toś to nowe konto dajo se na boku ''[[Special:ChangePassword|Gronidło změniś]]'' pśi pśizjawjenju změniś.",
 'newarticle' => '(Nowy nastawk)',
 'newarticletext' => "Sy slědował wótkaz na bok, kótaryž hyšći njeeksistěrujo.
-Aby bok napórał, zapiš do kašćika dołojce (glědaj [[{{MediaWiki:Helppage}}|bok pomocy]] za dalšne informacije). Jolic sy zamólnje how, klikni na tłocašk '''Slědk'' w swójom wobglědowaku.",
+Aby bok napórał, zapiš do kašćika dołojce (glědaj [[{{MediaWiki:Helppage}}|bok pomocy]] za dalšne informacije). Jolic sy zamólnje how, klikni na tłocašk '''Slědk''' w swójom wobglědowaku.",
 'anontalkpagetext' => "---- ''Toś jo diskusijny bok za anonymnego wužywarja, kótaryž njejo dotychměst žedno wužywarske konto załožył abo swójo konto njewužywa. Togodla dejmy numerisku IP-adresu wužywaś, aby jogo/ju identificěrowali. Taka IP-adresa dajo se wót wšakich wužywarjow wužywaś. Jolic sy anonymny wužywaŕ a se mysliš, až su se njerelewantne komentary na tebje měrili, [[Special:UserLogin/signup|załož konto]] abo [[Special:UserLogin|pśizjaw se]], aby se w pśichoźe zmuśenje z drugimi anonymnymi wužywarjami wobinuł.''",
 'noarticletext' => 'Dotychměst toś ten bok hyšći njewopśimujo žeden tekst. Móžoš w drugich bokach [[Special:Search/{{PAGENAME}}|titel togo boka pytaś]], <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} wótpowědne protokole pytaś] abo [{{fullurl:{{FULLPAGENAME}}|action=edit}} toś ten bok wobźěłaś]</span>.',
 'noarticletext-nopermission' => 'Tuchylu njejo žeden tekst na toś tom boku.
@@ -859,7 +859,8 @@ Ty teke wobkšuśijoš, až sy tekst sam napisał abo sy jen wót public domainy
 '''NJEWÓZJAW WÓT COPYRIGHTA ŠĆITANE ŹĚŁA MIMO DOWÓLNOSĆI!'''",
 'copyrightwarning2' => "Pšosym buź se togo wědobny, až wšykne pśinoski na {{SITENAME}} mógu wót drugich wužywarjow se wobźěłaś, narownaś abo wulašowaś. Jolic až njocoš, až twój tekst se mimo zmilnosći wobźěłujo, ga pón jen how njeskładuj.<br /> Ty teke wobkšuśijoš, až sy tekst sam napisał abo sy jen wót public domainy resp. wót pódobneje lichotneje resursy kopěrował (glědaj $1 za dalše detaile). '''NJEWÓZJAW WÓT COPYRIGHTA ŠĆITANE ŹĚŁA MIMO DOWÓLNOSĆI!'''",
 'longpageerror' => "'''Zmólka: Tekst, kótaryž coš składowaś, jo {{PLURAL:$1| jaden kilobajt|$1 kilobajta|$1 kilobajty|$1 kilobajtow}} wjeliki. To jo wěcej ako dowólony maksimum {{PLURAL:$2|jaden kilobajt|$1 kilobajta|$1 kilobajty|$1 kilobajtow}}.''' Składowanje njejo móžno.",
-'readonlywarning' => "'''WARNOWANJE: Datowa banka jo se za wótwardowanje zacyniła, togodla njebuźo tuchylu móžno, twóje změny składowaś. Jolic až coš, ga móžoš tekst do tekstoweje dataje kopěrowaś a pózdźej składowaś.'''
+'readonlywarning' => "'''WARNOWANJE: Datowa banka jo se za wótwardowanje zacyniła, togodla njebuźo tuchylu móžno, twóje změny składowaś.'''
+Jolic coš, ga móžoš tekst do tekstoweje dataje kopěrowaś a pózdźej składowaś.
 
 Administrator, kenž jo ju zastajił, su toś tu pśicynu pódał: $1",
 'protectedpagewarning' => "'''Warnowanje: Toś ten bok jo se zastajił, tak až jano wužywarje z pšawami administratora mógu jen wobźěłaś.'''
@@ -1161,7 +1162,7 @@ Drobnostki móžoš w [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'search-interwiki-default' => '$1 wuslědki:',
 'search-interwiki-more' => '(wěcej)',
 'search-relatedarticle' => 'swójźbne',
-'mwsuggest-disable' => 'Naraźenja pśez AJAX znjemóžniś',
+'mwsuggest-disable' => 'Pytańske naraźenja znjemóžniś',
 'searcheverything-enable' => 'We wšych mjenjowych rumach pytaś',
 'searchrelated' => 'swójźbne',
 'searchall' => 'wše',
@@ -2053,7 +2054,7 @@ Jo nanejmjenjej głowna domena trěbna, na pśikład "*.org"<br />
 # Special:ActiveUsers
 'activeusers' => 'Lisćina aktiwnych wužywarjow',
 '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|změna|změnje|změny|změnow}} w {{PLURAL:$3|slědnem dnju|slědnyma $3 dnjoma|slědnych $3 dnjach|slědnych $3 dnjach}}',
+'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ś',
@@ -2563,7 +2564,7 @@ Móžoš awtomatiski aktualizěrowaś dalejposrědkowanja, kótarež pokazuju na
 Jolic njocoš, pśeglědaj za [[Special:DoubleRedirects|dwójnymi]] abo [[Special:BrokenRedirects|defektnymi daleposrědkowanjami]].
 Sy zagronity, až wótkaze wjedu tam, źož maju wjasć.
 
-Źiwaj na to, až se bok '''nje'''pśesuwa, jolic jo južo bok z nowym titelom, snaźkuli jo prozny abo dalejpósrědnjenje a njama stare wobźěłane wersije. To ma groniś, až móžoš bok zasej slědk pśemjenjowaś, jolic cyniš zmólku, a njemóžoš eksistěrujucy bok pśepisaś.
+Źiwaj na to, až se bok '''nje'''pśesuwa, jolic jo južo bok z nowym titelom, snaźkuli slědny jo dalejpósrědnjenje a njama stare wobźěłane wersije. To ma groniś, až móžoš bok zasej slědk pśemjenjowaś, jolic cyniš zmólku, a njemóžoš eksistěrujucy bok pśepisaś.
 
 '''WARNOWANJE!'''
 To móžo byś drastiska a njewocakowana změna za popularny bok;
@@ -2882,6 +2883,7 @@ W zespominanju dajo se pśicyna pódaś.',
 'pageinfo-robot-noindex' => 'Njeindeksěrujobny',
 'pageinfo-views' => 'Licba zwobraznjenjow',
 'pageinfo-watchers' => 'Licba  wobglědowarjow boka',
+'pageinfo-few-watchers' => 'Mjenjej ako $1 {{PLURAL:$1|wobglědowaŕ|wobglědowarja|wobglědowarje|wobglědowarjow}}',
 'pageinfo-redirects-name' => 'Dalejpósrědnjenja k toś tomu bokoju',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Pódboki toś togo boka',
@@ -3651,7 +3653,7 @@ Wobraze se w połnym wótgranicowanju pokazuju, druge datajowe typy se ze zwěza
 'specialpages-group-highuse' => 'Cesto wužywane boki',
 'specialpages-group-pages' => 'Lisćiny bokow',
 'specialpages-group-pagetools' => 'Rědy bokow',
-'specialpages-group-wiki' => 'Wikijowe daty a rědy',
+'specialpages-group-wiki' => 'Daty a rědy',
 'specialpages-group-redirects' => 'Dalej pósrědnjajuce boki',
 'specialpages-group-spam' => 'Spamowe rědy',
 
@@ -3748,8 +3750,8 @@ Wobraze se w połnym wótgranicowanju pokazuju, druge datajowe typy se ze zwěza
 'logentry-newusers-newusers' => 'Wužywarske konto $1 jo se załožyło',
 'logentry-newusers-create' => 'Wužywarske konto $1 jo se załožyło',
 'logentry-newusers-create2' => '$1 jo załožył wužywarske konto $3',
+'logentry-newusers-byemail' => 'Wužywarske konto $3 jo se wót $1 załožyło a gronidło jo se pśez e-mail pósłało.',
 'logentry-newusers-autocreate' => 'Konto $1 jo se awtomatiski załožyło',
-'newuserlog-byemail' => 'Pótajne słowo bu pśez e-mail pósłane.',
 'logentry-rights-rights' => '$1 jo kupkowe cłonkojstwo za $3 z $4 do $5 změnił',
 'logentry-rights-rights-legacy' => '$1 jo kupkowe cłonkojstwo za $3 změnił',
 'logentry-rights-autopromote' => '$1 jo se awtomatiski wót $4 do $5 pówušył',
@@ -3807,6 +3809,7 @@ Hować móžoš slědujucy jadnory formular wužywaś. Twój komentar pśidajo s
 'api-error-ok-but-empty' => 'Nutśikowna zmólka: Žedne wótegrono wót serwera.',
 'api-error-overwrite' => 'Pśepisowanje eksistujuceje dataje njejo dowólone.',
 'api-error-stashfailed' => 'Nutśikowna zmólka: Serwer njejo mógał temporernu dataju składowaś.',
+'api-error-publishfailed' => 'Nutśkowna zmólka: Serwer njejo mógł nachylnu dataju wozjawiś.',
 'api-error-timeout' => 'Serwer njejo we wócakanem casu wótgronił.',
 'api-error-unclassified' => 'Njeznata zmólka jo nastała.',
 'api-error-unknown-code' => 'Njeznata zmólka: "$1"',
index 71ee574..a7dafad 100644 (file)
 $rtl = true;
 
 $namespaceNames = array(
+       NS_MEDIA            => 'މީޑިއާ',
        NS_SPECIAL          => 'ހާއްޞަ',
+       NS_MAIN             => '',
        NS_TALK             => 'ޚިޔާލު',
        NS_USER             => 'މެމްބަރު',
+       NS_USER_TALK        => 'މެމްބަރުގެ_ވާހަކަ',
        NS_FILE             => 'ފައިލް',
        NS_FILE_TALK        => 'ފައިލް_ޚިޔާލު',
        NS_MEDIAWIKI        => 'މީޑިއާވިކީ',
@@ -60,6 +63,10 @@ $specialPageAliases = array(
 $messages = array(
 # User preference toggles
 'tog-hideminor' => 'ކުދި އުނި އިތުރުތައް އެންމެފަހުގެ ބަދަލުތަކުގެ ލިސްޓުން ފޮރުއްވަވާ',
+'tog-watchlisthideown' => 'މަގޭ ނަޒަރުން މަގޭ ހިއްސާ ފޮރުއްވާ',
+'tog-watchlisthidebots' => 'މަގޭ ނަޒަރުން ބޮޓުންގެ ހިއްސާ ފޮރުއްވާ',
+'tog-watchlisthideminor' => 'މަގޭ ނަޒަރުން ކުދި އުނިއިތުރުތައް ފޮރުއްވާ',
+'tog-watchlisthideliu' => 'މަގޭ ނަޒަރުން ވަދެފައިވާ މެމްބަރުންގެ އުނިއުތުރުތައް ފޮރުއްވާ',
 'tog-ccmeonemails' => 'އަޅުގަނޑު އެހެން މެމްބަރުންނަށް ފޮނުވާ އީމެއިލްގެ ނަކަލެއް އަޅުގަނޑަށް ފޮނުވާ',
 'tog-showhiddencats' => 'ފޮރުވިފައިވާ ޤިސްމުތައް ދައްކަވާ',
 
@@ -252,6 +259,10 @@ $1',
 'youhavenewmessages' => 'ތިޔަބޭފުޅާއަށް $1 ($2)',
 'newmessageslink' => 'އައު މެސެޖުތައް',
 'newmessagesdifflink' => 'އެންމެ ފަހުގެ ބަދަލު',
+'youhavenewmessagesfromusers' => 'ތިބޭފުޅާއަށް {{PLURAL:$3|މެމްބަރެއް|$3 މެމްބަރުން}} $1 ފޮނުއްވާފައިވެއެވެ. ($2)',
+'youhavenewmessagesmanyusers' => 'ތިބޭފުޅާއަށް ގިނަ މެމްބަރުން $1 ފޮނުއްވާފައިވެއެވެ. ($2)',
+'newmessageslinkplural' => '{{PLURAL:$1|އާ މެސެޖެއް|މެސެޖުތައް}}',
+'newmessagesdifflinkplural' => 'ފަހު {{PLURAL:$1|ބަދަލު|ބަދަލުތައް}}',
 'editsection' => 'އުނިއިތުރު ގެންނަވާ',
 'editold' => 'އުނިއިތުރު ގެންނަވާ',
 'viewsourceold' => 'މަސްދަރު ބައްލަވާ',
@@ -396,8 +407,15 @@ $1',
 'accmailtitle' => 'ސިއްރުބަސް ފޮނުވިއްޖެ.',
 'accmailtext' => '"$1" އަށްޓަކައިވާ ސިއްރު ބަސް $2 އަށް ވަނީ ފޮނުވިފައި',
 'newarticle' => '(އައު)',
-'noarticletext' => 'މި ޞަފްޙާގައި އެއްވެސް ލިޔުމެއް ނުވެއެވެ. ތިޔަބޭފުޅާއަށް މި ނަން [[Special:Search/{{PAGENAME}}|އެހެން ޞަފްޙާތަކުން ހޯއްދެވިދާނެއެވެ]]. ނުވަތަ <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} މިއާ ގުޅޭ ލޮގްތައް ހޯއްދެވިދާނެއެވެ].
-[{{fullurl:{{FULLPAGENAME}}|action=edit}} ނުވަތަ މި ޞަފްޙާއަށް އުނިއިތުރު ގެނެވިދާނެއެވެ].</span>.',
+'newarticletext' => "<div style=\"border:1px solid black;\">
+<big>'''ވިކިޕީޑިއާގައި އަދި މިހާތަނަށް ތިނަމުންވާ މަޒުމޫނެއް އެކުލެވިފައިނުވެއެވެ.'''</big>
+* ތިޔަ ވަޑައިގެންނެވި ޞަފްޙާގައި އެއްވެސް ލިޔުމެއް އެކުލެވިފައި ނުވެއެވެ.
+*މި ޞަފްޙާއަށް ތިބޭފުޅާއަށް ވަޑައިގަނެވުނީ އޮޅުމަކުން ކަމަށް ވާނަމަ ކޮމްޕިޔުޓަރުގެ `ވެބް ބްރޯޒަރ` ގެ ''ފަހަތް'' ފިތައް އޮބާލައްވާށެވެ. އޭރުން އެންމެ ފަހުން ހުންނެވި ޞަފްޙާ އަށް ވަޑައިގަނެވޭނެއެވެ.
+* މަޒްމޫނެއް ފެއްޓެވުމަށް ތިރީގައި ވާ ފޮށީގައި ލިޔުއްވުމަށް ފަހު މަޒުމޫނުގެ ނަމޫނާ ބެއްލެވުމަށް ފަހު ކުށެއްވާނަމަ ރަނގަޅު ކުރައްވާފައި ފޮށީގެ ތިރީގައިވާ '''ޞަފްޙާ ރައްކާކުރައްވާ'''އަށް ފިއްތަވާ ލައްވަވާ.
+* އިތުރު އެހީ ބޭނުންފުޅު ނަމަ [[{{MediaWiki:Helppage}}|އެހީ ޞަފްހާއަށް]] ވަޑައިގަންނަވާށެވެ.
+</div>",
+'noarticletext' => 'މި ޞަފްޙާގައި އެއްވެސް ލިޔުމެއް ނުވެއެވެ. ތިޔަބޭފުޅާއަށް މި ނަން [[Special:Search/{{PAGENAME}}|އެހެން ޞަފްޙާއަކުން ހޯއްދެވިދާނެއެވެ]]. ނުވަތަ <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} މިއާ ގުޅޭ ލޮގްތައް ހޯއްދެވިދާނެއެވެ].
+[{{fullurl:{{FULLPAGENAME}}|action=edit}} ނުވަތަ މި ޞަފްޙާއަށް އުނިއިތުރު ގެނެވިދާނެއެވެ].</span>',
 'previewnote' => "'''މިއީ ހަމައެކަނި ނަމޫނާ އެކެވެ.'''
 އަދި ތިބޭފުޅާގެ ބަދަލުތައް ރައްކާނުކުރެވެއެވެ!",
 'editing' => '$1 އަށް އުނިއިތުރު ގެންނަނީ',
@@ -420,6 +438,7 @@ $1',
 ފޮހެލުމުގެ އަދި ނަން ބަދަލުކުރުމުގެ ލޮގް ތިރީގައިވަނީއެވެ.',
 
 # History pages
+'viewpagelogs' => 'މިޞަފްޙާގެ ލޮގުތައް ބައްލަވާ',
 'currentrev' => 'އެންމެފަހުން ގެނެވުނު ބަދަލު',
 'currentrev-asof' => 'އެންމެ ފަހުން ގެނެވުނު ބަދަލު $1',
 'revisionasof' => '$1ގެ ނުސްހާ',
@@ -663,7 +682,7 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'blanknamespace' => '(މައި)',
 
 # Contributions
-'contributions' => 'މެންބަރު ގެ ހިއްސާ',
+'contributions' => '{{GENDER:$1|މެމްބަރުގެ}} ހިއްސާ',
 'mycontris' => 'މަގޭ ހިއްސާ',
 
 'sp-contributions-talk' => 'ވާހަކަ',
@@ -759,6 +778,7 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'tooltip-ca-nstab-category' => 'ޤިސްމު ޞަފްޙާ ބައްލަވާ',
 'tooltip-save' => 'ބަދަލުތައް ރައްކާކުރައްވާ',
 'tooltip-preview' => 'ބަދަލުތައް ދައްކަވާ، ރައްކާކުރެއްވުމުގެ ކުރިން މި ބޭނުންކުރައްވާ!',
+'tooltip-watch' => 'މިޞަފްޙާއަށް ނަޒަރުބަހައްޓަވާ',
 'tooltip-rollback' => '"ކުރީގެ ނުސްހާ އަކަށް ބަދަލުކުރައްވާ" އިން މި ޞަފްޙާއަށް އެންމެ ފަހުން އުނިއިތުރު ގެންނެވި މެމްބަރުގެ އުނިއިތުރު(އުނިއިތުރުތައް) ފޮހެލެވޭނެއެވެ.',
 'tooltip-summary' => 'ކުރު ޚުލާސާއެއް ލިޔުއްވާ',
 
index a49218b..62a5b27 100644 (file)
@@ -73,7 +73,7 @@ $namespaceNames = array(
        NS_TALK             => 'Συζήτηση',
        NS_USER             => 'Χρήστης',
        NS_USER_TALK        => 'Συζήτηση_χρήστη',
-       NS_PROJECT_TALK     => '$1_συζήτηση',
+       NS_PROJECT_TALK     => 'Συζήτηση_$1',
        NS_FILE             => 'Αρχείο',
        NS_FILE_TALK        => 'Συζήτηση_αρχείου',
        NS_MEDIAWIKI        => 'MediaWiki',
@@ -87,8 +87,9 @@ $namespaceNames = array(
 );
 
 $namespaceAliases = array(
-       'Μέσον' => NS_MEDIA,
-       'Εικόνα' => NS_FILE,
+       'Μέσον'            => NS_MEDIA,
+       '$1_συζήτηση'      => NS_PROJECT_TALK,
+       'Εικόνα'           => NS_FILE,
        'Συζήτηση_εικόνας' => NS_FILE_TALK,
 );
 
@@ -101,7 +102,7 @@ $specialPageAliases = array(
        'Block'                     => array( 'Φραγή', 'ΦραγήIP', 'ΦραγήΧρήστη' ),
        'Blockme'                   => array( 'ΦραγήΕμένα' ),
        'Booksources'               => array( 'ΠηγέςΒιβλίων' ),
-       'BrokenRedirects'           => array( 'Î\9bανθαÏ\83μένεςΑνακατευθύνσεις' ),
+       'BrokenRedirects'           => array( 'Î\9aαÏ\84εÏ\83Ï\84Ï\81αμμένεςΑνακατευθύνσεις' ),
        'Categories'                => array( 'Κατηγορίες' ),
        'ChangePassword'            => array( 'ΑλλαγήΚωδικού', 'ΑρχικοποίησηΠάσου', 'ΑρχικοποίησηΚωδικού' ),
        'Confirmemail'              => array( 'ΕπιβεβαίωσηEmail' ),
@@ -223,6 +224,7 @@ $magicWords = array(
        'pagenamee'                 => array( '1', 'ΟΝΟΜΑΣΕΛΙΔΑΣΚ', 'PAGENAMEE' ),
        'namespace'                 => array( '1', 'ΠΕΡΙΟΧΗ', 'NAMESPACE' ),
        'namespacee'                => array( '1', 'ΠΕΡΙΟΧΗΚ', 'NAMESPACEE' ),
+       'namespacenumber'           => array( '1', 'ΑΡΙΘΜΟΣΟΝΟΜΑΤΟΣΧΩΡΟΥ', 'NAMESPACENUMBER' ),
        'talkspace'                 => array( '1', 'ΠΕΡΙΟΧΗΣΥΖΗΤΗΣΕΩΝ', 'TALKSPACE' ),
        'talkspacee'                => array( '1', 'ΠΕΡΙΟΧΗΣΥΖΗΤΗΣΕΩΝΚ', 'TALKSPACEE' ),
        'subjectspace'              => array( '1', 'ΠΕΡΙΟΧΗΘΕΜΑΤΩΝ', 'SUBJECTSPACE', 'ARTICLESPACE' ),
@@ -486,6 +488,7 @@ $messages = array(
 'newwindow' => '(ανοίγει σε ξεχωριστό παράθυρο)',
 'cancel' => 'Ακύρωση',
 'moredotdotdot' => 'Περισσότερα...',
+'morenotlisted' => 'Περισσότερα δεν αναφέρονται...',
 'mypage' => 'Σελίδα',
 'mytalk' => 'Συζήτηση',
 'anontalk' => 'Οι συζητήσεις αυτής της διεύθυνσης IP',
@@ -785,7 +788,7 @@ $2',
 'gotaccount' => "Έχετε ήδη έναν λογαριασμό; '''$1'''.",
 'gotaccountlink' => 'Είσοδος',
 'userlogin-resetlink' => 'Ξεχάσατε τα στοιχεία σύνδεσής σας;',
-'createaccountmail' => 'Î\9cε Î·Î»ÎµÎºÏ\84Ï\81ονικÏ\8c Ï\84αÏ\87Ï\85δÏ\81ομείο',
+'createaccountmail' => 'ΧÏ\81ήÏ\83η Ï\84Ï\85Ï\87αίοÏ\85 Ï\80Ï\81οÏ\83Ï\89Ï\81ινοÏ\8d ÎºÏ\89δικοÏ\8d Ï\80Ï\81Ï\8cÏ\83βαÏ\83ηÏ\82 ÎºÎ±Î¹ Î±Ï\80οÏ\83Ï\84ολή Ï\84οÏ\85 Ï\83Ï\84η Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η Î·Î»ÎµÎºÏ\84Ï\81ονικοÏ\8d Ï\84αÏ\87Ï\85δÏ\81ομείοÏ\85 Ï\80οÏ\85 ÎºÎ±Î¸Î¿Ï\81ίζεÏ\84αι Ï\80αÏ\81ακάÏ\84Ï\89',
 'createaccountreason' => 'Αιτία:',
 'badretype' => 'Οι κωδικοί που έχετε δηλώσει δεν συμφωνούν μεταξύ τους.',
 'userexists' => 'Το όνομα χρήστη που εισαγάγατε βρίσκεται ήδη σε χρήση.
@@ -851,6 +854,7 @@ $2',
 # E-mail sending
 'php-mail-error-unknown' => 'Άγνωστο σφάλμα στη συνάρτηση mail() της PHP.',
 'user-mail-no-addy' => 'Προσπαθήσατε να στείλετε e-mail χωρίς μια διεύθυνση e-mail.',
+'user-mail-no-body' => 'Προσπάθησε να στείλει e-mail με ένα κενό ή αδικαιολόγητα σύντομο σώμα.',
 
 # Change password dialog
 'resetpass' => 'Αλλαγή κωδικού πρόσβασης',
@@ -1063,7 +1067,8 @@ $2
 '''ΠΑΡΑΚΑΛΟΥΜΕ ΝΑ ΜΗΝ ΤΟΠΟΘΕΤΕΙΤΕ ΠΝΕΥΜΑΤΙΚΑ ΚΑΤΟΧΥΡΩΜΕΝΟ ΕΡΓΟ ΧΩΡΙΣ ΑΔΕΙΑ!'''",
 'longpageerror' => "'''Σφάλμα: Το κείμενο που καταχωρήσατε έχει μήκος {{PLURAL:$1|ένα kilobyte|$1 kilobytes}}, το οποίο είναι μεγαλύτερο από το μέγιστο {{PLURAL:$2|του ενός kilobyte|των $2 kilobytes}}.'''
 Δεν μπορεί να αποθηκευτεί.",
-'readonlywarning' => "'''ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η βάση δεδομένων έχει κλειδωθεί για συντήρηση, έτσι δεν θα μπορέσετε να αποθηκεύσετε αυτά που έχετε επεξεργαστεί. Μπορείτε αν θέλετε να αποθηκεύσετε το κείμενο σε αρχείο κειμένου (με αποκοπή-και-επικόλληση) για να το χρησιμοποιήσετε αργότερα.'''
+'readonlywarning' => "'''Προειδοποίηση: Η βάση δεδομένων έχει κλειδωθεί για συντήρηση, έτσι δεν θα μπορέσετε να αποθηκεύσετε τις επεξεργασίες σας αυτή τη στιγμή.'''
+Μπορείτε αν θέλετε να μεταφέρετε με αντιγραφή-επικόλληση το κείμενό σας σε αρχείο κειμένου και να το αποθηκεύσετε για αργότερα.
 
 Ο διαχειριστής που την κλείδωσε έδωσε την εξής εξήγηση: $1",
 'protectedpagewarning' => "'''Προειδοποίηση: Αυτή η σελίδα έχει κλειδωθεί ώστε μόνο χρήστες με δικαιώματα διαχειριστή μπορούν να την επεξεργαστούν.'''
@@ -1338,7 +1343,7 @@ $1",
 'viewprevnext' => 'Εμφάνιση ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-legend' => 'Επιλογές αναζήτησης',
 'searchmenu-exists' => "'''Υπάρχει μια σελίδα που ονομάζεται \"[[:\$1]]\" σε αυτό το wiki'''",
-'searchmenu-new' => "'''Δημιουργήστε τη σελίδα \"[[:\$1]]\" σε αυτό το wiki!'''",
+'searchmenu-new' => "'''Δημιουργήστε τη σελίδα «[[:$1]]» σε αυτό το wiki!'''",
 'searchhelp-url' => 'Help:Περιεχόμενα',
 'searchmenu-prefix' => '[[Special:PrefixIndex/$1|Πλοηγηθείτε σε σελίδες με αυτό το πρόθεμα]]',
 'searchprofile-articles' => 'Σελίδες περιεχομένων',
@@ -1361,14 +1366,14 @@ $1",
 'search-interwiki-default' => '$1 αποτελέσματα:',
 'search-interwiki-more' => '(περισσότερα)',
 'search-relatedarticle' => 'Σχετικά',
-'mwsuggest-disable' => 'Î\91Ï\80ενεÏ\81γοÏ\80οίηÏ\83η Ï\84Ï\89ν Ï\80Ï\81οÏ\84άÏ\83εÏ\89ν AJAX',
+'mwsuggest-disable' => 'Î\91Ï\80ενεÏ\81γοÏ\80οίηÏ\83η Ï\80Ï\81οÏ\84άÏ\83εÏ\89ν Î±Î½Î±Î¶Î®Ï\84ηÏ\83ηÏ\82',
 'searcheverything-enable' => 'Αναζήτηση σε όλες τις περιοχές ονομάτων',
 'searchrelated' => 'σχετικά',
 'searchall' => 'όλα',
 'showingresults' => "Δείτε παρακάτω μέχρι τα {{PLURAL:$1|'''1'''αποτέλεσμα|'''$1''' αποτελέσματα}} ξεκινώντας με #'''$2'''.",
 'showingresultsnum' => "Εμφάνιση {{PLURAL:$3|'''1''' αποτελέσματος|'''$3''' αποτελεσμάτων}} αρχίζοντας με #'''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Αποτέλεσμα '''$1''' από '''$3'''|Αποτελέσματα '''$1 - $2''' από '''$3'''}} για '''$4'''",
-'nonefound' => "'''ΣημείÏ\89Ï\83η''': Î\9fι Î±Î½ÎµÏ\80ιÏ\84Ï\85Ï\87είÏ\82 Î±Î½Î±Î¶Î·Ï\84ήÏ\83ειÏ\82 Î¿Ï\86είλονÏ\84αι Ï\83Ï\85νήθÏ\89Ï\82 Ï\83Ï\84ο Ï\8cÏ\84ι Î­Ï\87οÏ\85με Ï\83Ï\85μÏ\80εÏ\81ιλάβει Ï\83Ï\84α ÎºÏ\81ιÏ\84ήÏ\81ια Î¼Ï\8cνο Ï\83Ï\85γκεκÏ\81ιμένεÏ\82 Ï\80εÏ\81ιοÏ\87έÏ\82 Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν. Î\94οκιμάÏ\83Ï\84ε Î½Î± Ï\80Ï\81οÏ\83θέÏ\83εÏ\84ε Ï\84ο Ï\80Ï\81Ï\8cθεμα ''all:'' - ''Ï\8cλα:'' Ï\83Ï\84ην Î±Î½Î±Î¶Î®Ï\84ηÏ\83η Î³Î¹Î± Î½Î± Ï\88άξεÏ\84ε Ï\83ε Ï\8cλα Ï\84α Ï\80εÏ\81ιεÏ\87Ï\8cμενα (Ï\83Ï\85μÏ\80εÏ\81ιλαμβανÏ\8cμενÏ\89ν Ï\84Ï\89ν Ï\83ελίδÏ\89ν Ï\83Ï\85ζηÏ\84ήÏ\83εÏ\89Ï\82, Ï\80Ï\81οÏ\84á½\90Ï\80Ï\89ν ÎºÏ\84λ.) Î® Ï\87Ï\81ηÏ\83ιμοÏ\80οιήÏ\83Ï\84ε Ï\84ην ÎµÏ\80ιθÏ\85μηÏ\84ή Ï\80εÏ\81ιοÏ\87ή Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν.",
+'nonefound' => "'''ΣημείÏ\89Ï\83η''': Î\9fι Î±Î½ÎµÏ\80ιÏ\84Ï\85Ï\87είÏ\82 Î±Î½Î±Î¶Î·Ï\84ήÏ\83ειÏ\82 Î¿Ï\86είλονÏ\84αι Ï\83Ï\85νήθÏ\89Ï\82 Ï\83Ï\84ο Ï\8cÏ\84ι Î­Ï\87οÏ\85με Ï\83Ï\85μÏ\80εÏ\81ιλάβει Ï\83Ï\84α ÎºÏ\81ιÏ\84ήÏ\81ια Î¼Ï\8cνο Ï\83Ï\85γκεκÏ\81ιμένοÏ\85Ï\82 Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81οÏ\85Ï\82. Î\94οκιμάÏ\83Ï\84ε Î½Î± Ï\80Ï\81οÏ\83θέÏ\83εÏ\84ε Ï\84ο Ï\80Ï\81Ï\8cθεμα ''all:'' - ''Ï\8cλα:'' Ï\83Ï\84ην Î±Î½Î±Î¶Î®Ï\84ηÏ\83η Î³Î¹Î± Î½Î± Ï\88άξεÏ\84ε Ï\83ε Ï\8cλα Ï\84α Ï\80εÏ\81ιεÏ\87Ï\8cμενα (Ï\83Ï\85μÏ\80εÏ\81ιλαμβανÏ\8cμενÏ\89ν Ï\84Ï\89ν Ï\83ελίδÏ\89ν Ï\83Ï\85ζηÏ\84ήÏ\83εÏ\89Ï\82, Ï\80Ï\81οÏ\84Ï\8dÏ\80Ï\89ν ÎºÏ\84λ.) Î® Ï\87Ï\81ηÏ\83ιμοÏ\80οιήÏ\83Ï\84ε Ï\84ον ÎµÏ\80ιθÏ\85μηÏ\84Ï\8c Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο.",
 'search-nonefound' => 'Δεν υπάρχουν αποτελέσματα που να ταιριάζουν με την αναζήτησή σας.',
 'powersearch' => 'Αναλυτική αναζήτηση',
 'powersearch-legend' => 'Αναλυτική αναζήτηση',
@@ -2049,11 +2054,11 @@ $1',
 
 # Random page
 'randompage' => 'Τυχαία σελίδα',
-'randompage-nopages' => 'Δεν υπάρχουν σελίδες σε {{PLURAL:$2|αυτή την περιοχή ονομάτων|αυτές τις περιοχές ονομάτων}}: $1.',
+'randompage-nopages' => 'Δεν υπάρχουν σελίδες {{PLURAL:$2|στον ακόλουθο ονοματοχώρο|στους ακόλουθους ονοματοχώρους}}: $1.',
 
 # Random redirect
 'randomredirect' => 'Τυχαία ανακατεύθυνση',
-'randomredirect-nopages' => 'Δεν υπάρχουν ανακατευθύνσεις σε αυτή την περιοχή ονόματος "$1".',
+'randomredirect-nopages' => 'Δεν υπάρχουν ανακατευθύνσεις στον ονοματοχώρο "$1".',
 
 # Statistics
 'statistics' => 'Στατιστικά',
@@ -2135,7 +2140,7 @@ $1',
 'mostinterwikis' => 'Σελίδες με τους περισσότερους διαγλωσσικούς συνδέσμους',
 'mostrevisions' => 'Άρθρα με τις περισσότερες αναθεωρήσεις',
 'prefixindex' => 'Όλες οι σελίδες με πρόθεμα',
-'prefixindex-namespace' => 'Όλες οι σελίδες με πρόθεμα (περιοχής  $1)',
+'prefixindex-namespace' => 'Όλες οι σελίδες με πρόθεμα (ονοματοχώρος $1)',
 'shortpages' => 'Σύντομες σελίδες',
 'longpages' => 'Εκτενείς σελίδες',
 'deadendpages' => 'Αδιέξοδες σελίδες',
@@ -2196,7 +2201,7 @@ $1',
 'allpagesfrom' => 'Εμφάνιση σελίδων που αρχίζουν από:',
 'allpagesto' => 'Εμφάνιση σελίδων που λήγουν σε:',
 'allarticles' => 'Όλα τα άρθρα',
-'allinnamespace' => 'Î\8cλεÏ\82 Î¿Î¹ Ï\83ελίδεÏ\82 (Ï\83Ï\84ην Ï\80εÏ\81ιοÏ\87ή $1)',
+'allinnamespace' => 'Î\8cλεÏ\82 Î¿Î¹ Ï\83ελίδεÏ\82 (Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο $1)',
 'allnotinnamespace' => 'Όλες οι σελίδες (που δεν βρίσκονται στην περιοχή $1)',
 'allpagesprev' => 'Προηγούμενες',
 'allpagesnext' => 'Επόμενες',
@@ -2232,7 +2237,7 @@ $1',
 'linksearch-ok' => 'Αναζήτηση',
 'linksearch-text' => 'Μπορούν να χρησιμοποιηθούν χαρακτήρες μπαλαντέρ όπως "*.wikipedia.org". 
 Χρειάζεται τουλάχιστον μια κατάληξη ανωτάτου επιπέδου, για παράδειγμα "*.org".<br />
-Υποστηριζόμενα πρωτόκολλα: <code>$1</code> (αν δεν οριστεί πρωτόκολλο η προεπιλογή είναι http://).',
+Υποστηριζόμενα {{PLURAL:$2|πρωτόκολλο|πρωτόκολλα}}: <code>$1</code> (αν δεν οριστεί πρωτόκολλο η προεπιλογή είναι http://).',
 'linksearch-line' => 'Η $1 συνδεδεμένη από την $2',
 'linksearch-error' => 'Λέξεις-μπαλαντέρ μπορεί να εμφανιστούν μόνο στην αρχή τού ονόματος ιστοτόπου (hostname).',
 
@@ -2245,7 +2250,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Κατάλογος ενεργών χρηστών',
 'activeusers-intro' => 'Αυτή είναι μια λίστα από χρήστες που είχαν κάποιου είδους δραστηριότητα {{PLURAL:$1|την τελευταία $1 μέρα|τις τελευταίες $1 μέρες}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|επεξεργασία|επεξεργασίες}} {{PLURAL:$3|την τελευταία ημέρα|τις τελευταίες $3 ημέρες}}',
+'activeusers-count' => '$1 {{PLURAL:$1|ενέργεια|ενέργειες}} {{PLURAL:$3|την τελευταία μέρα|τις τελευταίες $3 μέρες}}',
 'activeusers-from' => 'Προβολή χρηστών ξεκινώντας από:',
 'activeusers-hidebots' => 'Απόκρυψη bots',
 'activeusers-hidesysops' => 'Απόκρυψη διαχειριστών',
@@ -2457,6 +2462,8 @@ $UNWATCHURL
 'prot_1movedto2' => 'Η [[$1]] μετακινήθηκε στη θέση [[$2]]',
 'protect-badnamespace-title' => 'Μη-προστατευόμενη ομάδα σελίδων',
 'protect-badnamespace-text' => 'Οι  σελίδες σε αυτόν τον ονοματοχώρο δεν μπορούν να κλειδωθούν.',
+'protect-norestrictiontypes-text' => 'Αυτή η σελίδα δεν μπορούν να προστατευθούν δεδομένου ότι δεν υπάρχουν διαθέσιμοι τύποι κλειδώματος.',
+'protect-norestrictiontypes-title' => 'Μη-προστατευόμενη σελίδα',
 'protect-legend' => 'Επιβεβαίωση κλειδώματος',
 'protectcomment' => 'Αιτία:',
 'protectexpiry' => 'Λήξη',
@@ -2472,9 +2479,9 @@ $UNWATCHURL
 Εδώ είναι οι τρέχουσες ρυθμίσεις για τη σελίδα '''$1''':",
 'protect-cascadeon' => 'Αυτή η σελίδα είναι προς το παρόν προστατευμένη επειδή περιλαμβάνεται {{PLURAL:$1|στην ακόλουθη σελίδα, η οποία έχει|στις ακόλουθες σελίδες, οι οποίες έχουν}} τη διαδοχική προστασία ενεργοποιημένη. Μπορείτε να αλλάξετε το επίπεδο προστασίας αυτής της σελίδας, αλλά δεν θα επηρεάσει τη διαδοχική προστασία.',
 'protect-default' => 'Να επιτρέπονται όλοι οι χρήστες',
-'protect-fallback' => 'Î\91ίÏ\84ηÏ\83η Î´Î¹ÎºÎ±Î¹Ï\89μάÏ\84Ï\89ν "$1"',
-'protect-level-autoconfirmed' => 'ΦÏ\81αγή Î½Î­Ï\89ν ÎºÎ±Î¸Ï\8eÏ\82 ÎºÎ±Î¹ Î¼Î· ÎµÎ³Î³ÎµÎ³Ï\81αμμένÏ\89ν Ï\87Ï\81ηÏ\83Ï\84Ï\8eν',
-'protect-level-sysop' => 'Î\9cÏ\8cνο διαχειριστές',
+'protect-fallback' => 'Î\9dα ÎµÏ\80ιÏ\84Ï\81έÏ\80εÏ\84αι Î¼Ï\8cνο Ï\83ε Ï\87Ï\81ήÏ\83Ï\84εÏ\82 Î¼Îµ Î´Î¹ÎºÎ±Î¹Ï\8eμαÏ\84α Â«$1»',
+'protect-level-autoconfirmed' => 'Î\9dα ÎµÏ\80ιÏ\84Ï\81έÏ\80ονÏ\84αι Î¼Ï\8cνο Î±Ï\85Ï\84οεÏ\80ιβεβαιÏ\89μένοι Ï\87Ï\81ήÏ\83Ï\84εÏ\82',
+'protect-level-sysop' => 'Î\9dα ÎµÏ\80ιÏ\84Ï\81έÏ\80εÏ\84αι Î¼Ï\8cνο Ï\83Ï\84οÏ\85Ï\82 διαχειριστές',
 'protect-summary-cascade' => 'διαδοχική',
 'protect-expiring' => 'λήγει στις $1 (UTC)',
 'protect-expiring-local' => 'λήγει στις $1',
@@ -2563,11 +2570,11 @@ $1',
 'undelete-show-file-submit' => 'Ναι',
 
 # Namespace form on various pages
-'namespace' => 'ΠεÏ\81ιοÏ\87ή:',
+'namespace' => 'Î\9fνομαÏ\84οÏ\87Ï\8eÏ\81οÏ\82:',
 'invert' => 'Αντιστροφή της επιλογής',
 'tooltip-invert' => 'Επιλέξτε αυτό το πλαίσιο για να αποκρύψετε αλλαγές σε σελίδες μέσα στον επιλεγμένο χώρο ονομάτων (και των συσχετικών χώρων ονομάτων, εάν επιλεγχθούν)',
 'namespace_association' => 'Συσχετισμένος ονοματοχώρος',
-'tooltip-namespace_association' => 'Επιλέξτε αυτό το πλαίσιο για να συμπεριλάβετε τον χώρο ονομάτων συζήτησης ή θέματος που σχετίζονται με τον επιλεγμένο χώρο ονομάτων',
+'tooltip-namespace_association' => 'Επιλέξτε αυτό το κουτάκι για να συμπεριλάβετε τον ονοματοχώρο συζήτησης ή θέματος που σχετίζεται με τον επιλεγμένο ονοματοχώρο',
 'blanknamespace' => '(Αρχική περιοχή)',
 
 # Contributions
@@ -2603,7 +2610,7 @@ $1',
 'whatlinkshere-page' => 'Σελίδα:',
 'linkshere' => "Οι ακόλουθες σελίδες συνδέουν στη σελίδα '''[[:$1]]''':",
 'nolinkshere' => "Δεν υπάρχουν σελίδες που να συνδέουν στη σελίδα '''[[:$1]]'''.",
-'nolinkshere-ns' => "Î\9aαμία Ï\83ελίδα Î´ÎµÎ½ Ï\83Ï\85νδέει Ï\83Ï\84ο '''[[:$1]]''' Ï\83Ï\84ην ÎµÏ\80ιλεγμένη Ï\80εÏ\81ιοÏ\87ή Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν.",
+'nolinkshere-ns' => "Î\9aαμία Ï\83ελίδα Î´ÎµÎ½ Ï\83Ï\85νδέει Ï\83Ï\84ο '''[[:$1]]''' Ï\83Ï\84ον ÎµÏ\80ιλεγμένο Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο.",
 'isredirect' => 'σελίδα ανακατεύθυνσης',
 'istemplate' => 'ενσωμάτωση',
 'isimage' => 'σύνδεσμος αρχείου',
@@ -2765,18 +2772,19 @@ $1',
 # Move page
 'move-page' => 'Μετακίνηση $1',
 'move-page-legend' => 'Μετακίνηση σελίδας',
-'movepagetext' => "ΧÏ\81ηÏ\83ιμοÏ\80οιÏ\8eνÏ\84αÏ\82 Ï\84η Ï\86Ï\8cÏ\81μα Ï\80οÏ\85 Î±ÎºÎ¿Î»Î¿Ï\85θεί Î¼Ï\80οÏ\81είÏ\84ε Î½Î± Î¼ÎµÏ\84ονομάÏ\83εÏ\84ε Ï\83ελίδεÏ\82 ÎºÎ±Î¹ Î½Î± Î¼ÎµÏ\84αÏ\86έÏ\81εÏ\84ε Ï\8cλο Ï\84ο Î¹Ï\83Ï\84οÏ\81ικÏ\8c Ï\84οÏ\85ς στο νέο όνομα.
-Ο παλιός τίτλος της σελίδας θα γίνει μια σελίδα ανακατεύθυνσης στο νέο τίτλο.
-Μπορείτε να ενημερώσετε τις ανακατευθύνσεις που οδηγούν στον αρχικό τίτλο αυτόματα.
\91ν ÎµÏ\80ιλέξεÏ\84ε Î½Î± Î¼Î·Î½ Î³Î¯Î½ÎµÎ¹, Î¸Î± Ï\80Ï\81έÏ\80ει Î½Î± ÎµÎ»Î­Î³Î¾ÎµÏ\84ε Ï\84ιÏ\82 [[Special:DoubleRedirects|διÏ\80λέÏ\82]] ÎºÎ±Î¹ Ï\84ιÏ\82 [[Special:BrokenRedirects|κατεστραμμένες ανακατευθύνσεις]].
-Είστε υπεύθυνος να επιβεβαιώσετε ότι οι σύνδεσμοι εξακολουθούν να οδηγούν προς τις κατευθύνσεις που πρέπει.
+'movepagetext' => "ΧÏ\81ηÏ\83ιμοÏ\80οιÏ\8eνÏ\84αÏ\82 Ï\84η Ï\86Ï\8cÏ\81μα Ï\80οÏ\85 Î±ÎºÎ¿Î»Î¿Ï\85θεί Î¸Î± Î³Î¯Î½ÎµÎ¹ Î¼ÎµÏ\84ονομαÏ\83ία Ï\83ελίδαÏ\82, Î¼ÎµÏ\84αÏ\86έÏ\81ονÏ\84αÏ\82 Ï\8cλο Ï\84ο Î¹Ï\83Ï\84οÏ\81ικÏ\8c Ï\84ης στο νέο όνομα.
+Ο παλιός τίτλος της σελίδας θα γίνει σελίδα ανακατεύθυνσης προς τον νέο τίτλο.
+Μπορείτε να ενημερώσετε αυτόματα τις ανακατευθύνσεις που οδηγούν στον αρχικό τίτλο.
\91ν ÎµÏ\80ιλέξεÏ\84ε Î½Î± Î¼Î·Î½ ÎµÎ½Î·Î¼ÎµÏ\81Ï\89θοÏ\8dν Î±Ï\85Ï\84Ï\8cμαÏ\84α, Î¼Î·Î½ Î¾ÎµÏ\87άÏ\83εÏ\84ε Î½Î± ÎµÎ»Î­Î³Î¾ÎµÏ\84ε Î³Î¹Î± [[Special:DoubleRedirects|διÏ\80λέÏ\82]] Î® [[Special:BrokenRedirects|κατεστραμμένες ανακατευθύνσεις]].
+Είναι δική σας ευθύνη να επιβεβαιώσετε ότι οι σύνδεσμοι εξακολουθούν να δείχνουν προς τη σωστή κατεύθυνση.
 
-Λάβετε υπόψη σας ότι η σελίδα '''δεν''' θα μετακινηθεί αν υπάρχει ήδη μια άλλη σελίδα κάτω από το νέο τίτλο, εκτός αν η σελίδα αυτή είναι κενή ή είναι ανακατεύθυνση χωρίς ιστορικό επεξεργασίας.
-Αυτό σημαίνει ότι, στην περίπτωση που έχετε κάνει λάθος, μπορείτε να μετονομάσετε μια σελίδα ξαναδίνοντας της την αρχική της ονομασία αλλά δεν μπορείτε να αντικαταστήσετε μια υπάρχουσα σελίδα.
+Λάβετε υπόψιν σας ότι η σελίδα '''δεν''' θα μετακινηθεί αν υπάρχει ήδη μια άλλη σελίδα υπό το νέο τίτλο, εκτός αν η σελίδα αυτή είναι ανακατεύθυνση και δεν έχει ιστορικό επεξεργασίας.
+
+Αυτό σημαίνει ότι σε περίπτωση λάθους μπορείτε να μετονομάσετε ξανά μια σελίδα δίνοντας της την αρχική της ονομασία αλλά δεν μπορείτε να αντικαταστήσετε μια υπάρχουσα σελίδα.
 
 '''ΠΡΟΣΟΧΗ!'''
\97 Î¼ÎµÏ\84ονομαÏ\83ία Ï\83ελίδαÏ\82 ÎµÎ¯Î½Î±Î¹ Î¼Î¹Î± Î±Î¹Ï\86νίδια ÎºÎ±Î¹ Î´Ï\81αÏ\83Ï\84ική Î±Î»Î»Î±Î³Î® όταν πρόκειται για δημοφιλείς σελίδες.
-Παρακαλούμε, πριν το αποφασίσετε, να εξετάσετε προσεκτικά τις πιθανές επιπτώσεις αυτής της ενέργειας.",
\91Ï\85Ï\84ή Î· Î±Î»Î»Î±Î³Î® Î¼Ï\80οÏ\81εί Î½Î± Î±Ï\80οβεί Î´Ï\81αÏ\83Ï\84ική ÎºÎ±Î¹ Î±Î½Î±Ï\80άνÏ\84εÏ\87η όταν πρόκειται για δημοφιλείς σελίδες.
+Παρακαλούμε βεβαιωθείτε ότι αντιλαμβάνεστε τις επιπτώσεις αυτής της ενέργειας πριν προχωρήσετε.",
 'movepagetext-noredirectfixer' => "Χρησιμοποιώντας τη φόρμα που ακολουθεί μπορείτε να μετονομάσετε σελίδες και να μεταφέρετε όλο το ιστορικό τους στο νέο όνομα.
 Ο παλιός τίτλος της σελίδας θα γίνει μια σελίδα ανακατεύθυνσης στο νέο τίτλο.
 Μπορείτε να ενημερώσετε τις ανακατευθύνσεις που οδηγούν στον αρχικό τίτλο αυτόματα.
@@ -2835,8 +2843,8 @@ $1',
 'delete_and_move_confirm' => 'Ναι, διέγραψε τη σελίδα',
 'delete_and_move_reason' => 'Διαγράφηκε για να δημιουργήσει χώρο για μετακίνηση από το "[[$1]]"',
 'selfmove' => 'Ο τίτλος προέλευσης είναι ο ίδιος με τον τίτλο προορισμού -δεν είναι δυνατόν να μετακινηθεί μια σελίδα προς τον εαυτό της.',
-'immobile-source-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84η Ï\80εÏ\81ιοÏ\87ή "$1"',
-'immobile-target-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84ην Ï\80εÏ\81ιοÏ\87ή "$1"',
+'immobile-source-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο "$1"',
+'immobile-target-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο "$1"',
 'immobile-target-namespace-iw' => 'Ο σύνδεσμος-interwiki δεν είναι έγκυρος στόχος για την μετακίνηση σελίδας.',
 'immobile-source-page' => 'Αυτή η σελίδα δεν είναι δυνατό να μετακινηθεί.',
 'immobile-target-page' => 'Δεν μπορεί να μετακινηθεί σε αυτόν τον τίτλο.',
@@ -2917,7 +2925,7 @@ $1',
 'import-interwiki-history' => 'Αντιγραφή όλων των εκδόσεων του ιστορικού για αυτή τη σελίδα',
 'import-interwiki-templates' => 'Συμπερίληψη όλων των προτύπων',
 'import-interwiki-submit' => 'Εισαγωγή',
-'import-interwiki-namespace' => 'ΠÏ\81οοÏ\81ιÏ\83μÏ\8cÏ\82 Ï\83Ï\84ην Ï\80εÏ\81ιοÏ\87ή Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν:',
+'import-interwiki-namespace' => 'ΠÏ\81οοÏ\81ιÏ\83μÏ\8cÏ\82 Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο:',
 'import-upload-filename' => 'Όνομα αρχείου:',
 'import-comment' => 'Σχόλιο:',
 'importtext' => 'Παρακαλούμε εξάγετε το αρχείο από το πηγαίο wiki (χρησιμοποιώντας το [[Special:Export|εργαλείο εξαγωγής]]), αποθηκεύστε το στον υπολογιστή σας και μεταφορτώστε το από εκεί.',
@@ -3129,6 +3137,7 @@ $1',
 'pageinfo-protect-cascading' => 'Οι προστασίες ξεκινούν τη διαδοχή τους από εδώ',
 'pageinfo-protect-cascading-yes' => 'Ναι',
 'pageinfo-protect-cascading-from' => 'Οι προστασίες ξεκινούν τη διαδοχή τους από',
+'pageinfo-category-info' => 'Πληροφορίες κατηγορίας',
 'pageinfo-category-pages' => 'Αριθμός σελίδων',
 'pageinfo-category-subcats' => 'Αριθμός υποκατηγοριών',
 'pageinfo-category-files' => 'Αριθμός αρχείων',
@@ -3213,6 +3222,8 @@ $1',
 'minutes' => '{{PLURAL:$1|$1 λεπτό|$1 λεπτά}}',
 'hours' => '{{PLURAL:$1|$1 ώρα|$1 ώρες}}',
 'days' => '{{PLURAL:$1|$1 μέρα|$1 μέρες}}',
+'months' => '{{PLURAL:$1|$1 μήνας|$1 μήνες}}',
+'years' => '{{PLURAL:$1|$1 έτος|$1 έτη}}',
 'ago' => '$1 πριν',
 'just-now' => 'μόλις τώρα',
 
@@ -3663,42 +3674,51 @@ $1',
 'confirmemail_loggedin' => 'Η ηλεκτρονική σας διεύθυνση επαληθεύτηκε.',
 'confirmemail_error' => 'Παρουσιάστηκε λάθος κατά την αποθήκευση των ρυθμίσεών σας.',
 'confirmemail_subject' => 'Επαλήθευση ηλεκτρονικής διεύθυνσης του {{SITENAME}}',
-'confirmemail_body' => 'Κάποιος -πιθανόν εσείς- από τη διεύθυνση IP $1, δημιούργησε στον ιστότοπο {{SITENAME}} το λογαριασμό χρήστη "$2" με αυτή την ηλεκτρονική διεύθυνση.
+'confirmemail_body' => 'Κάποιος, πιθανότατα εσείς, από τη διεύθυνση IP $1,
+δημιούργησε λογαριασμό χρήστη «$2»
+με αυτήν τη διεύθυνση ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}.
 
-Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε εσάς και για να ενεργοποιηθούν οι δυνατότητες e-mail του {{SITENAME}}, ακολουθήστε αυτό το σύνδεσμο:
+Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να ενεργοποιήσετε
+τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}, ανοίξτε στον περιηγητή σας αυτόν το σύνδεσμο:
 
 $3
 
-Αν *δεν* δημιουργήσατε εσείς το συγκεκριμένο λογαριασμό, ακολουθήστε τον παρακάτω σύνδεσμο για να ακυρώσετε την επιβεβαίωση της διεύθυνσης e-mail:
+Εάν *δεν* δημιουργήσατε εσείς το λογαριασμό χρήστη, ακολουθήστε αυτόν τον σύνδεσμο
+για να ακυρώσετε την επιβεβαίωση της διεύθυνσης ηλεκτρονικού ταχυδρομείου:
 
 $5
 
-Ο κωδικός επιβεβαίωσης θα λήξει στις $4.',
-'confirmemail_body_changed' => 'Κάποιος - πιθανόν εσείς - από τη διεύθυνση IP $1, άλλαξε στον ιστότοπο {{SITENAME}} την ηλεκτρονική διεύθυνση του λογαριασμού χρήστη "$2".
+Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $6, στις $7.',
+'confirmemail_body_changed' => 'Κάποιος, πιθανότατα εσείς, από τη διεύθυνση IP $1,
+άλλαξε τη διεύθυνση ηλεκτρονικού ταχυδρομείου του λογαριασμού χρήστη «$2»
+σε αυτήν τη διεύθυνση ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}.
 
-Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε εσάς και για να ενεργοποιηθούν οι δυνατότητες e-mail του {{SITENAME}}, ακολουθήστε αυτό το σύνδεσμο:
+Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να ενεργοποιήσετε πάλι
+τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}, ανοίξτε στον περιηγητή σας αυτόν το σύνδεσμο:
 
 $3
 
-Αν ο λογαριασμός *δεν* ανήκει σε σας, ακολουθήστε τον παρακάτω σύνδεσμο για να ακυρώσετε την επιβεβαίωση της διεύθυνσης e-mail:
+Εάν ο λογαριασμός *δεν* ανήκει σε σας, ακολουθήστε αυτόν τον σύνδεσμο
+για να ακυρώσετε την επιβεβαίωση της διεύθυνσης ηλεκτρονικού ταχυδρομείου:
 
 $5
 
-Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $4.',
-'confirmemail_body_set' => 'Κάποιος, πιθανόν εσείς, από τη διεύθυνση IP $1, έχει θέσει τη διεύθυνση 
-ηλεκτρονικού ταχυδρομείου (e-mail) του λογαριασμού " $2 "σε αυτή τη διεύθυνση στο {{SITENAME}}.
+Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $6, στις $7.',
+'confirmemail_body_set' => 'Κάποιος, πιθανότατα εσείς, από τη διεύθυνση IP $1,
+όρισε αυτήν τη διεύθυνση ηλεκτρονικού ταχυδρομείου ως διεύθυνση ηλεκτρονικού ταχυδρομείου
+του λογαριασμού χρήστη «$2» στον ιστότοπο {{SITENAME}}.
 
-Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να επανενεργοποιήσετε
-τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον/στην/στα {{SITENAME}}, ανοίξτε αυτό το σύνδεσμο στον φυλλομετρητή (browser) σας:
+Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να ενεργοποιήσετε πάλι
+τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}, ανοίξτε στον περιηγητή σας αυτόν το σύνδεσμο:
 
 $3
 
-Εάν ο λογαριασμός * δεν * ανήκει σε σας, ακολουθήστε αυτόν τον σύνδεσμο
-για Î½Î± Î±ÎºÏ\85Ï\81Ï\8eÏ\83εÏ\84ε Ï\84ο e-mail ÎµÏ\80ιβεβαίÏ\89Ï\83ηÏ\82 Ï\84ηÏ\82 Î´Î¹ÎµÏ\8dθÏ\85νÏ\83ηÏ\82
+Εάν ο λογαριασμός *δεν* ανήκει σε σας, ακολουθήστε αυτόν τον σύνδεσμο
+για Î½Î± Î±ÎºÏ\85Ï\81Ï\8eÏ\83εÏ\84ε Ï\84ην ÎµÏ\80ιβεβαίÏ\89Ï\83η Ï\84ηÏ\82 Î´Î¹ÎµÏ\8dθÏ\85νÏ\83ηÏ\82 Î·Î»ÎµÎºÏ\84Ï\81ονικοÏ\8d Ï\84αÏ\87Ï\85δÏ\81ομείοÏ\85:
 
 $5
 
-Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $4.',
+Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $6, στις $7.',
 'confirmemail_invalidated' => 'Η επιβεβαίωσης της διεύθυνσης e-mail ακυρώθηκε',
 'invalidateemail' => 'Ακύρωση επιβεβαίωσης της διεύθυνσης e-mail',
 
@@ -3860,7 +3880,7 @@ $5
 'specialpages-group-highuse' => 'Πολυσύχναστες σελίδες',
 'specialpages-group-pages' => 'Κατάλογοι σελίδων',
 'specialpages-group-pagetools' => 'Εργαλεία σελίδων',
-'specialpages-group-wiki' => 'Î\92ικι Î´εδομένα και εργαλεία',
+'specialpages-group-wiki' => 'Î\94εδομένα και εργαλεία',
 'specialpages-group-redirects' => 'Ανακατεύθυνση ειδικών σελίδων',
 'specialpages-group-spam' => 'Εργαλεία κατά των ανεπιθύμητων διαφημιστικών',
 
@@ -3892,13 +3912,13 @@ $5
 'tags-hitcount' => '$1 {{PLURAL:$1|αλλαγή|αλλαγές}}',
 
 # Special:ComparePages
-'comparepages' => 'ΣÏ\85γκÏ\81ίνεÏ\84ε Ï\84ιÏ\82 Ï\83ελίδεÏ\82',
+'comparepages' => 'ΣÏ\8dγκÏ\81ιÏ\83η Ï\83ελίδÏ\89ν',
 'compare-selector' => 'Συγκρίνετε τις αναθεωρήσεις των σελίδων',
 'compare-page1' => 'Σελίδα 1',
 'compare-page2' => 'Σελίδα 2',
 'compare-rev1' => 'Αναθεώρηση 1',
 'compare-rev2' => 'Αναθεώρηση 2',
-'compare-submit' => 'ΣÏ\85γκÏ\81ίνεÏ\84ε',
+'compare-submit' => 'ΣÏ\8dγκÏ\81ιÏ\83η',
 'compare-invalid-title' => 'Ο τίτλος που καθορίσατε δεν είναι έγκυρος.',
 'compare-title-not-exists' => 'Ο τίτλος που καθορίσατε δεν υπάρχει.',
 'compare-revision-not-exists' => 'Η αναθεώρηση που καθορίσατε δεν υπάρχει.',
@@ -3933,9 +3953,12 @@ $5
 'logentry-delete-restore' => 'Ο/η $1 αποκατέστησε τη σελίδα $3',
 'logentry-delete-event' => '{{GENDER:$1|Ο|Η}} $1 άλλαξε την ορατότητα σε {{PLURAL:$5|ένα γεγονός καταγραφής|$5 log events}} στο $3: $4',
 'logentry-delete-revision' => '{{GENDER:$1|Ο|Η}} $1 άλλαξε την ορατότητα {{PLURAL:$5|μιας έκδοσης|$5 εκδόσεων}} στη σελίδα $3: $4',
-'logentry-delete-event-legacy' => '{{GENDER:$2|Ο|Η}} $1 άλλαξε την ορατότητα της καταγραφής συμβάντων στη σελίδα $3',
+'logentry-delete-event-legacy' => '{{GENDER:$2|Ο|Η}} $1 άλλαξε την ορατότητα των καταγραφόμενων συμβάντων στη σελίδα $3',
 'logentry-delete-revision-legacy' => '{{GENDER:$1|Ο|Η}} $1 άλλαξε την  ορατότητα των αναθεωρήσεων στη σελίδα $3',
 'logentry-suppress-delete' => '{{GENDER:$1|Ο|Η}} $1 διέγραψε τη σελίδα $3',
+'logentry-suppress-event' => '{{Gender:$2|Ο|Η}} $1 άλλαξε μυστικά την ορατότητα {{PLURAL:$5|ενός καταγραφόμενου συμβάντος|$5 καταγραφόμενων συμβάντων}} στη σελίδα $3: $4',
+'logentry-suppress-revision' => '{{Gender:$2|Ο|Η}} $1 άλλαξε μυστικά την ορατότητα {{PLURAL:$5|μίας αναθεώρησης|$5 αναθεωρήσεων}} στη σελίδα $3: $4',
+'logentry-suppress-event-legacy' => '{{Gender:$2|Ο|Η}} $1 άλλαξε μυστικά την ορατότητα των καταγραφόμενων συμβάντων στη σελίδα $3',
 'logentry-suppress-revision-legacy' => '$1 κρυφά άλλαξαν την  ορατότητα των αναθεωρήσεων στη σελίδα $3',
 'revdelete-content-hid' => 'το περιεχόμενο αποκρύφθηκε',
 'revdelete-summary-hid' => 'Η σύνοψη επεξεργασίας αποκρύφθηκε',
@@ -3955,7 +3978,6 @@ $5
 'logentry-newusers-create' => 'Ο λογαριασμός χρήστη $1 δημιουργήθηκε',
 'logentry-newusers-create2' => 'Ο λογαριασμός χρήστη $3 δημιουργήθηκε από {{GENDER:$1|τον|την}} $1',
 'logentry-newusers-autocreate' => 'Ο λογαριασμός $1 δημιουργήθηκε αυτόματα',
-'newuserlog-byemail' => 'ο κωδικός έχει σταλεί μέσω ηλεκτρονικού μηνύματος',
 'logentry-rights-rights-legacy' => '{{GENDER:$1|Ο|Η}} $1 άλλαξε την ιδιότητα μέλους ομάδας {{GENDER:$1|του|της}} $3',
 'logentry-rights-autopromote' => '$1 προωθήθηκε αυτόματα από το $4 στο $5',
 'rightsnone' => '(κανένα)',
@@ -4012,6 +4034,7 @@ $5
 'api-error-ok-but-empty' => 'Εσωτερικό σφάλμα: δεν υπάρχει απάντηση από το διακομιστή.',
 'api-error-overwrite' => 'Αντικατάσταση ενός υπάρχοντος αρχείου δεν επιτρέπεται.',
 'api-error-stashfailed' => 'Εσωτερικό σφάλμα: ο διακομιστής απέτυχε να αποθηκεύσει το προσωρινό αρχείο.',
+'api-error-publishfailed' => 'Εσωτερικό σφάλμα: ο διακομιστής απέτυχε να αποθηκεύσει το προσωρινό αρχείο.',
 'api-error-timeout' => 'Ο διακομιστής δεν αποκρίθηκε εντός του αναμενόμενου χρόνου.',
 'api-error-unclassified' => 'Προέκυψε ένα άγνωστο σφάλμα.',
 'api-error-unknown-code' => 'Άγνωστο σφάλμα: "$1"',
index ab27dc6..d3f1327 100644 (file)
@@ -1095,7 +1095,7 @@ Do not forget to change your [[Special:Preferences|{{SITENAME}} preferences]].',
 'gotaccount'                 => 'Already have an account? $1.',
 'gotaccountlink'             => 'Log in',
 'userlogin-resetlink'        => 'Forgotten your login details?',
-'createaccountmail'          => 'By e-mail',
+'createaccountmail'          => 'Use a temporary random password and send it to the e-mail address specified below',
 'createaccountreason'        => 'Reason:',
 'badretype'                  => 'The passwords you entered do not match.',
 'userexists'                 => 'Username entered already in use.
@@ -1443,7 +1443,7 @@ You are also promising us that you wrote this yourself, or copied it from a publ
 'longpageerror'                    => "'''Error: The text you have submitted is {{PLURAL:$1|one kilobyte|$1 kilobytes}} long, which is longer than the maximum of {{PLURAL:$2|one kilobyte|$2 kilobytes}}.'''
 It cannot be saved.",
 'readonlywarning'                  => "'''Warning: The database has been locked for maintenance, so you will not be able to save your edits right now.'''
-You may wish to cut-n-paste the text into a text file and save it for later.
+You may wish to copy and paste your text into a text file and save it for later.
 
 The administrator who locked it offered this explanation: $1",
 'protectedpagewarning'             => "'''Warning: This page has been protected so that only users with administrator privileges can edit it.'''
@@ -1764,7 +1764,7 @@ Details can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'search-interwiki-custom'          => '', # do not translate or duplicate this message to other languages
 'search-interwiki-more'            => '(more)',
 'search-relatedarticle'            => 'Related',
-'mwsuggest-disable'                => 'Disable AJAX suggestions',
+'mwsuggest-disable'                => 'Disable search suggestions',
 'searcheverything-enable'          => 'Search in all namespaces',
 'searchrelated'                    => 'related',
 'searchall'                        => 'all',
@@ -2774,7 +2774,7 @@ Supported {{PLURAL:$2|protocol|protocols}}: <code>$1</code> (defaults to http://
 'activeusers'            => 'Active users list',
 'activeusers-summary'    => '', # do not translate or duplicate this message to other languages
 '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|edit|edits}} in the last {{PLURAL:$3|day|$3 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',
@@ -2841,7 +2841,7 @@ The e-mail address you entered in [[Special:Preferences|your user preferences]]
 'usermessage-template' => 'MediaWiki:UserMessage', # only translate this message to other languages if you have to change it
 
 # Watchlist
-'watchlist'            => 'My watchlist',
+'watchlist'            => 'Watchlist',
 'watchlist-summary'    => '', # do not translate or duplicate this message to other languages
 'mywatchlist'          => 'Watchlist',
 'watchlistfor2'        => 'For $1 $2',
@@ -2880,16 +2880,16 @@ Future changes to this page and its associated talk page will be listed there.',
 'enotif_mailer'                => '{{SITENAME}} notification mailer',
 'enotif_reset'                 => 'Mark all pages visited',
 'enotif_impersonal_salutation' => '{{SITENAME}} user',
-'enotif_subject_deleted'       => '{{SITENAME}} page $1 has been deleted by {{gender:$2|$2}}',
-'enotif_subject_created'       => '{{SITENAME}} page $1 has been created by {{gender:$2|$2}}',
-'enotif_subject_moved'         => '{{SITENAME}} page $1 has been moved by {{gender:$2|$2}}',
-'enotif_subject_restored'      => '{{SITENAME}} page $1 has been restored by {{gender:$2|$2}}',
-'enotif_subject_changed'       => '{{SITENAME}} page $1 has been changed by {{gender:$2|$2}}',
-'enotif_body_intro_deleted'    => 'The {{SITENAME}} page $1 has been deleted on $PAGEEDITDATE by {{gender:$2|$2}}, see $3.',
-'enotif_body_intro_created'    => 'The {{SITENAME}} page $1 has been created on $PAGEEDITDATE by {{gender:$2|$2}}, see $3 for the current revision.',
-'enotif_body_intro_moved'      => 'The {{SITENAME}} page $1 has been moved on $PAGEEDITDATE by {{gender:$2|$2}}, see $3 for the current revision.',
-'enotif_body_intro_restored'   => 'The {{SITENAME}} page $1 has been restored on $PAGEEDITDATE by {{gender:$2|$2}}, see $3 for the current revision.',
-'enotif_body_intro_changed'    => 'The {{SITENAME}} page $1 has been changed on $PAGEEDITDATE by {{gender:$2|$2}}, see $3 for the current revision.',
+'enotif_subject_deleted'       => '{{SITENAME}} page $1 has been {{GENDER:$2|deleted}} by $2',
+'enotif_subject_created'       => '{{SITENAME}} page $1 has been {{GENDER:$2|created}} by $2',
+'enotif_subject_moved'         => '{{SITENAME}} page $1 has been {{GENDER:$2|moved}} by $2',
+'enotif_subject_restored'      => '{{SITENAME}} page $1 has been {{GENDER:$2|restored}} by $2',
+'enotif_subject_changed'       => '{{SITENAME}} page $1 has been {{GENDER:$2|changed}} by $2',
+'enotif_body_intro_deleted'    => 'The {{SITENAME}} page $1 has been {{GENDER:$2|deleted}} on $PAGEEDITDATE by $2, see $3.',
+'enotif_body_intro_created'    => 'The {{SITENAME}} page $1 has been {{GENDER:$2|created}} on $PAGEEDITDATE by $2, see $3 for the current revision.',
+'enotif_body_intro_moved'      => 'The {{SITENAME}} page $1 has been {{GENDER:$2|moved}} on $PAGEEDITDATE by $2, see $3 for the current revision.',
+'enotif_body_intro_restored'   => 'The {{SITENAME}} page $1 has been {{GENDER:$2|restored}} on $PAGEEDITDATE by $2, see $3 for the current revision.',
+'enotif_body_intro_changed'    => 'The {{SITENAME}} page $1 has been {{GENDER:$2|changed}} on $PAGEEDITDATE by $2, see $3 for the current revision.',
 'enotif_lastvisited'           => 'See $1 for all changes since your last visit.',
 'enotif_lastdiff'              => 'See $1 to view this change.',
 'enotif_anon_editor'           => 'anonymous user $1',
@@ -3336,7 +3336,7 @@ You can update redirects that point to the original title automatically.
 If you choose not to, be sure to check for [[Special:DoubleRedirects|double]] or [[Special:BrokenRedirects|broken redirects]].
 You are responsible for making sure that links continue to point where they are supposed to go.
 
-Note that the page will '''not''' be moved if there is already a page at the new title, unless it is a redirect and has no past edit history.
+Note that the page will '''not''' be moved if there is already a page at the new title, unless the latter is a redirect and has no past edit history.
 This means that you can rename a page back to where it was renamed from if you make a mistake, and you cannot overwrite an existing page.
 
 '''Warning!'''
@@ -3768,6 +3768,7 @@ This is probably caused by a link to a blacklisted external site.',
 'pageinfo-robot-noindex'          => 'Not indexable',
 'pageinfo-views'                  => 'Number of views',
 'pageinfo-watchers'               => 'Number of page watchers',
+'pageinfo-few-watchers'           => 'Fewer than $1 {{PLURAL:$1|watcher|watchers}}',
 'pageinfo-redirects-name'         => 'Redirects to this page',
 'pageinfo-redirects-value'        => '$1', # only translate this message to other languages if you have to change it
 'pageinfo-subpages-name'          => 'Subpages of this page',
@@ -4786,7 +4787,7 @@ Images are shown in full resolution, other file types are started with their ass
 'specialpages-group-highuse'     => 'High use pages',
 'specialpages-group-pages'       => 'Lists of pages',
 'specialpages-group-pagetools'   => 'Page tools',
-'specialpages-group-wiki'        => 'Wiki data and tools',
+'specialpages-group-wiki'        => 'Data and tools',
 'specialpages-group-redirects'   => 'Redirecting special pages',
 'specialpages-group-spam'        => 'Spam tools',
 
@@ -4886,8 +4887,8 @@ This site is experiencing technical difficulties.',
 'logentry-newusers-newusers'          => 'User account $1 was created',
 'logentry-newusers-create'            => 'User account $1 was created',
 'logentry-newusers-create2'           => 'User account $3 was created by $1',
+'logentry-newusers-byemail'           => 'User account $3 was created by $1 and password was sent by e-mail',
 'logentry-newusers-autocreate'        => 'User account $1 was created automatically',
-'newuserlog-byemail'                  => 'password sent by e-mail',
 'logentry-rights-rights'              => '$1 changed group membership for $3 from $4 to $5',
 'logentry-rights-rights-legacy'       => '$1 changed group membership for $3',
 'logentry-rights-autopromote'         => '$1 was automatically promoted from $4 to $5',
@@ -4970,6 +4971,7 @@ Otherwise, you can use the easy form below. Your comment will be added to the pa
 'api-error-ok-but-empty'                  => 'Internal error: No response from server.',
 'api-error-overwrite'                     => 'Overwriting an existing file is not allowed.',
 'api-error-stashfailed'                   => 'Internal error: Server failed to store temporary file.',
+'api-error-publishfailed'                 => 'Internal error: Server failed to publish temporary file.',
 'api-error-timeout'                       => 'The server did not respond within the expected time.',
 'api-error-unclassified'                  => 'An unknown error occurred.',
 'api-error-unknown-code'                  => 'Unknown error: "$1".',
index f19e10e..a0f8627 100644 (file)
@@ -751,7 +751,7 @@ Ne forgesu ŝanĝi viajn [[Special:Preferences|{{SITENAME}}-preferojn]]',
 'gotaccount' => "Ĉu vi jam havas konton? '''$1'''.",
 'gotaccountlink' => 'Ensaluti',
 'userlogin-resetlink' => 'Ĉu vi forgesis ensalutajn detalojn?',
-'createaccountmail' => 'retpoŝte',
+'createaccountmail' => 'Uzi provizoran hazardsignan pasvorton kaj sendi ĝin al la retpoŝto suben',
 'createaccountreason' => 'Kialo:',
 'badretype' => 'La pasvortojn kiujn vi tajpis ne egalas.',
 'userexists' => 'Salutnomo enigita jam estas uzata.
@@ -2313,7 +2313,7 @@ La retadreso kiun vi enigis en [[Special:Preferences|viaj preferoj]] aperos kiel
 'usermessage-editor' => 'Mesaĝanto de sistemo',
 
 # Watchlist
-'watchlist' => 'Atentaro',
+'watchlist' => 'Mia atentaro',
 'mywatchlist' => 'Atentaro',
 'watchlistfor2' => 'Por $1 $2',
 'nowatchlist' => 'Vi ne jam elektis priatenti iun ajn paĝon.',
@@ -3152,6 +3152,10 @@ Datoj de versioj kaj nomoj de redaktantoj estos preservitaj.
 'pageinfo-protect-cascading' => 'Protektado kaskade fontas el ĉi tie',
 'pageinfo-protect-cascading-yes' => 'Jes',
 'pageinfo-protect-cascading-from' => 'Protektado kaskade fontas el',
+'pageinfo-category-info' => 'Informo pri kategorio',
+'pageinfo-category-pages' => 'Nombro de paĝoj',
+'pageinfo-category-subcats' => 'Nombro de subkategorioj',
+'pageinfo-category-files' => 'Nombro de dosieroj',
 
 # Skin names
 'skinname-standard' => 'Klasiko',
@@ -3239,6 +3243,7 @@ $1',
 'hours' => '{{PLURAL:$1|$1 horo|$1 horoj}}',
 'days' => '{{PLURAL:$1|$1 tago|$1 tagoj}}',
 'months' => '{{PLURAL:$1|$1 monato|$1 monatoj}}',
+'years' => '{{PLURAL:$1|$1 jaro|$1 jaroj}}',
 'ago' => 'antaŭ $1',
 'just-now' => 'ĵus nune',
 
@@ -3950,7 +3955,7 @@ Bildoj montriĝas en plena distingivo, aliaj dosiertipoj estas malfermataj rekte
 'specialpages-group-highuse' => 'Plej uzitaj paĝoj',
 'specialpages-group-pages' => 'Listoj de paĝoj',
 'specialpages-group-pagetools' => 'Paĝaj iloj',
-'specialpages-group-wiki' => 'Vikidatenoj kaj iloj',
+'specialpages-group-wiki' => 'Datenoj kaj iloj',
 'specialpages-group-redirects' => 'Alidirektantaj specialaj paĝoj',
 'specialpages-group-spam' => 'Kontraŭspamiloj',
 
@@ -4048,7 +4053,6 @@ Bildoj montriĝas en plena distingivo, aliaj dosiertipoj estas malfermataj rekte
 'logentry-newusers-create' => '$1 kreis konton',
 'logentry-newusers-create2' => '$1 kreis uzanton $3',
 'logentry-newusers-autocreate' => 'Konto $1 estis kreita aŭtomate',
-'newuserlog-byemail' => 'pasvorto sendita retpoŝte',
 'logentry-rights-rights' => '$1 ŝanĝis grupan membrecon por $3 de $4 al $5',
 'logentry-rights-rights-legacy' => '$1 ŝanĝis grupan membrecon por $3',
 'logentry-rights-autopromote' => '$1 estis aŭtomate altrangigita de $4 al $5',
@@ -4105,7 +4109,8 @@ Aŭ vi povas uzi la facilan formularon sube. Via komento estos aldonita al la pa
 'api-error-nomodule' => 'Interna eraro: ne troveblas alŝuta helpilaro.',
 'api-error-ok-but-empty' => 'Interna eraro: nenia respondo de la servilo.',
 'api-error-overwrite' => 'Anstataŭigo de ekzistanta dosiero ne permesatas.',
-'api-error-stashfailed' => 'Interna eraro: la servilo malsukcesis stoki dumtempan dosieron.',
+'api-error-stashfailed' => 'Interna eraro: la servilo malsukcesis stoki provizoran dosieron.',
+'api-error-publishfailed' => 'Interna eraro: Servilo malsukcesis eldoni provizoran dosieron.',
 'api-error-timeout' => 'La servilo ne respondis ene de la antaŭvidita tempo.',
 'api-error-unclassified' => 'Okazis nekonata eraro',
 'api-error-unknown-code' => 'Nekonata eraro: "$1"',
index 81f22e8..42bd97b 100644 (file)
@@ -43,6 +43,7 @@
  * @author Fluence
  * @author Gustronico
  * @author Gwickwire
+ * @author Hazard-SJ
  * @author Hercule
  * @author Icvav
  * @author Imre
@@ -361,7 +362,7 @@ $linkTrail = '/^([a-záéíóúñ]+)(.*)$/sDu';
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Subrayar enlaces:',
+'tog-underline' => 'Subrayar los enlaces:',
 'tog-justify' => 'Justificar los párrafos',
 'tog-hideminor' => 'Ocultar las ediciones menores en los cambios recientes',
 'tog-hidepatrolled' => 'Ocultar las ediciones patrulladas en los cambios recientes',
@@ -409,14 +410,14 @@ $messages = array(
 
 'underline-always' => 'Siempre',
 'underline-never' => 'Nunca',
-'underline-default' => 'Aspecto (skin) o navegador predeterminado',
+'underline-default' => 'Aspecto (skin) o valor predeterminado del navegador',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Estilo de tipografía del área de edición:',
 'editfont-default' => 'Predeterminado del navegador',
 'editfont-monospace' => 'Tipografía monoespaciada',
-'editfont-sansserif' => 'Tipografía sans-serif',
-'editfont-serif' => 'Tipografía serif',
+'editfont-sansserif' => 'Tipo de letra de palo seco',
+'editfont-serif' => 'Tipo de letra con serifas',
 
 # Dates
 'sunday' => 'domingo',
@@ -494,6 +495,7 @@ $messages = array(
 'newwindow' => '(se abre en una ventana nueva)',
 'cancel' => 'Cancelar',
 'moredotdotdot' => 'Más...',
+'morenotlisted' => 'Más no en la lista...',
 'mypage' => 'Mi página',
 'mytalk' => 'Discusión',
 'anontalk' => 'Discusión para esta IP',
@@ -628,7 +630,7 @@ $1',
 'youhavenewmessagesmanyusers' => 'Tienes $1 de muchos usuarios ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|un nuevo mensaje|mensajes nuevos}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|última modificación|últimos cambios}}',
-'youhavenewmessagesmulti' => 'Tienes nuevos mensajes en $1',
+'youhavenewmessagesmulti' => 'Tienes mensajes nuevos en $1',
 'editsection' => 'editar',
 'editold' => 'editar',
 'viewsourceold' => 'ver código fuente',
@@ -782,7 +784,7 @@ No olvides cambiar tus [[Special:Preferences|preferencias de {{SITENAME}} ]].',
 'externaldberror' => 'Hubo un error de autenticación externa de la base de datos o bien no tienes autorización para actualizar tu cuenta externa.',
 'login' => 'Iniciar sesión',
 'nav-login-createaccount' => 'Iniciar sesión / crear cuenta',
-'loginprompt' => "Es necesario habilitar las ''cookies'' en el navegador para registrarse en {{SITENAME}}.",
+'loginprompt' => "Necesita activar las ''cookies'' en el navegador para iniciar sesión en {{SITENAME}}.",
 'userlogin' => 'Iniciar sesión / crear cuenta',
 'userloginnocreate' => 'Iniciar sesión',
 'logout' => 'Cerrar sesión',
@@ -794,7 +796,7 @@ No olvides cambiar tus [[Special:Preferences|preferencias de {{SITENAME}} ]].',
 'gotaccount' => '¿Ya tienes una cuenta? $1.',
 'gotaccountlink' => 'Entrar',
 'userlogin-resetlink' => '¿Olvidaste tus datos de acceso?',
-'createaccountmail' => 'por correo electrónico',
+'createaccountmail' => 'Usar una contraseña aleatoria temporal y enviarla a la siguiente dirección de correo electrónico',
 'createaccountreason' => 'Motivo:',
 'badretype' => 'Las contraseñas no coinciden.',
 'userexists' => 'El nombre de usuario indicado ya está en uso.
@@ -868,6 +870,7 @@ Puedes ignorar este mensaje si esta cuenta fue creada por error.',
 # E-mail sending
 'php-mail-error-unknown' => 'Error desconocido en la función mail() de PHP.',
 'user-mail-no-addy' => 'Se ha intentado enviar correo electrónico sin una dirección de correo electrónico.',
+'user-mail-no-body' => 'Trató de enviar un correo electrónico con un cuerpo vacío o excesivamente corto.',
 
 # Change password dialog
 'resetpass' => 'Cambiar la contraseña',
@@ -1094,10 +1097,10 @@ Si la guardas, se perderán los cambios realizados desde esta revisión.",
 '''¡No uses escritos con copyright sin permiso!'''",
 'longpageerror' => "'''Error: El texto que has enviado ocupa {{PLURAL:$1|un kilobyte|$1 kilobytes}}, que excede el máximo de {{PLURAL:$2|un kilobyte|$2 kilobytes}}.''' 
 No se lo puede guardar.",
-'readonlywarning' => "'''Aviso: La base de datos ha sido bloqueada por cuestiones de mantenimiento, así que no podrás guardar tus modificaciones en este momento.
-Puedes copiar y pegar el texto en un archivo y guardarlo para más tarde.'''
+'readonlywarning' => "'''Advertencia: La base de datos ha sido bloqueada para mantenimiento, así que no podrás guardar tus ediciones en este momento.'''
+Quizás quieras copiar y pegar tu texto en un archivo de texto y guardarlo para después.
 
-El administrador que la bloqueó dio esta explicación: $1",
+El administrador que lo bloqueó ofreció esta explicación: $1",
 'protectedpagewarning' => "'''Aviso: Esta página ha sido protegida de manera que solo usuarios con permisos de administrador puedan editarla.'''
 A continuación se muestra la última entrada de registro para referencia:",
 'semiprotectedpagewarning' => "'''Nota:''' Esta página ha sido protegida para que solo usuarios registrados puedan editarla.
@@ -1403,7 +1406,7 @@ Los detalles pueden encontrarse en el [{{fullurl:{{#Special:Log}}/delete|page={{
 'search-interwiki-default' => 'Resultados de $1:',
 'search-interwiki-more' => '(más)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Desactivar AJAX al realizar búsquedas',
+'mwsuggest-disable' => 'Desactivar las sugerencias de búsqueda',
 'searcheverything-enable' => 'Buscar en todos los espacios de nombres',
 'searchrelated' => 'relacionado',
 'searchall' => 'todos',
@@ -1500,8 +1503,8 @@ Cualquiera que conozca la clave en este campo será capaz de leer tu lista de se
 'allowemail' => 'Aceptar correo electrónico de otros usuarios',
 'prefs-searchoptions' => 'Buscar',
 'prefs-namespaces' => 'Espacios de nombres',
-'defaultns' => 'Buscar en estos espacios de nombres por defecto:',
-'default' => 'por defecto',
+'defaultns' => 'De lo contrario, buscar en estos espacios de nombres:',
+'default' => 'predeterminado',
 'prefs-files' => 'Archivos',
 'prefs-custom-css' => 'CSS personalizado',
 'prefs-custom-js' => 'JavaScript personalizado',
@@ -2002,7 +2005,7 @@ Para óptima seguridad, img_auth.php está desactivado.',
 
 # Special:ListFiles
 'listfiles-summary' => 'Esta página especial muestra todos los archivos subidos.
-Cuando es filtrado por el usuario, sólo los archivos cargados por el usuario se muestran en su versión más reciente.',
+Cuando el usuario la filtra, solo se muestran los archivos cargados por el usuario en su versión más reciente.',
 'listfiles_search_for' => 'Buscar por nombre de imagen:',
 'imgfile' => 'archivo',
 'listfiles' => 'Lista de archivos',
@@ -2307,7 +2310,7 @@ Es necesario, por lo menos, un dominio de alto nivel, por ejemplo "*.org".<br />
 # Special:ActiveUsers
 '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|edición|ediciones}} en los últimos {{PLURAL:$3|día|$3 días}}',
+'activeusers-count' => '$1 {{PLURAL:$1|acción|acciones}} en los últimos {{PLURAL:$3|día|$3 días}}',
 'activeusers-from' => 'Mostrando a los usuarios empezando por:',
 'activeusers-hidebots' => 'Ocultar robots',
 'activeusers-hidesysops' => 'Ocultar administradores',
@@ -2335,10 +2338,10 @@ Puede haber información adicional sobre privilegios individuales en [[{{MediaWi
 # E-mail user
 'mailnologin' => 'Ninguna dirección de envio',
 'mailnologintext' => 'Debes [[Special:UserLogin|iniciar sesión]] y tener una dirección electrónica válida en tus [[Special:Preferences|preferencias]] para enviar un correo electrónico a otros usuarios.',
-'emailuser' => 'Enviar correo electrónico a este usuario',
+'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}}',
 'emailuser-title-notarget' => 'Enviar un correo electrónico al usuario',
-'emailpage' => 'Correo electrónico a usuario',
+'emailpage' => 'Enviar un correo electrónico a un usuario',
 'emailpagetext' => 'Puedes usar el formulario de abajo para enviar un correo electrónico a {{GENDER:$1|este usuario|esta usuaria}}.
 La dirección de correo electrónico que indicaste en [[Special:Preferences|tus preferencias de usuario]] aparecerá en el campo "Remitente" o "De" para que el destinatario pueda responderte.',
 'usermailererror' => 'El sistema de correo devolvió un error:',
@@ -2515,6 +2518,8 @@ Véase [[Special:ProtectedPages|la lista de páginas protegidas]] para ver las p
 'prot_1movedto2' => 'heredando la protección al trasladar [[$1]] a [[$2]]',
 'protect-badnamespace-title' => 'Espacio de nombres no protegible',
 'protect-badnamespace-text' => 'Las páginas de este espacio de nombres no pueden ser protegidas',
+'protect-norestrictiontypes-text' => 'Esta página no se puede proteger ya que no hay ningún tipo de restricción disponible.',
+'protect-norestrictiontypes-title' => 'Página no protegible',
 'protect-legend' => 'Confirmar protección',
 'protectcomment' => 'Motivo:',
 'protectexpiry' => 'Caducidad:',
@@ -2529,9 +2534,9 @@ A continuación se muestran las opciones actuales de la página '''$1''':",
 A continuación se muestran las opciones actuales de la página '''$1''':",
 'protect-cascadeon' => 'Actualmente esta página está protegida porque está incluida en {{PLURAL:$1|la siguiente página|las siguientes páginas}}, que tienen activada la opción de protección en cascada. Puedes cambiar el nivel de protección de esta página, pero no afectará a la protección en cascada.',
 'protect-default' => 'Permitir todos los usuarios',
-'protect-fallback' => 'Necesita el permiso «$1»',
-'protect-level-autoconfirmed' => 'Bloquear usuarios nuevos y no registrados',
-'protect-level-sysop' => 'Solo administradores',
+'protect-fallback' => 'Solo permitir usuarios con el permiso «$1»',
+'protect-level-autoconfirmed' => 'Solo permitir usuarios autoconfirmados',
+'protect-level-sysop' => 'Solo permitir administradores',
 'protect-summary-cascade' => 'en cascada',
 'protect-expiring' => 'caduca el $1 (UTC)',
 'protect-expiring-local' => 'caduca el $1',
@@ -2792,7 +2797,7 @@ Sin embargo, está bloqueada como parte del rango $2, que puede ser desbloqueado
 'proxyblocksuccess' => 'Hecho.',
 'sorbsreason' => 'Su dirección IP está listada como proxy abierto en DNSBL.',
 'sorbs_create_account_reason' => 'Su dirección IP está listada como proxy abierto en DNSBL. No puede crear una cuenta',
-'cant-block-while-blocked' => 'No puedes bloquear a otros usuarios mientras estás bloqueado.',
+'cant-block-while-blocked' => 'No puedes bloquear a otros usuarios mientras estás bloquead{{GENDER:|o|a}}.',
 'cant-see-hidden-user' => 'El usuario que está intentando bloquear ya ha sido bloqueado y oculto. Puesto que usted no tiene el derecho hideuser, usted no puede ver o editar los bloqueos del usuario.',
 'ipbblocked' => 'No puedes bloquear o desbloquear a otros usuarios porque estás bloqueado',
 'ipbnounblockself' => 'No puedes desbloquearte',
@@ -2819,18 +2824,18 @@ Sin embargo, está bloqueada como parte del rango $2, que puede ser desbloqueado
 # Move page
 'move-page' => 'Trasladar $1',
 'move-page-legend' => 'Renombrar página',
-'movepagetext' => "Usando el siguiente formulario se renombrará una página, trasladando todo su historial al nuevo nombre.
-El título anterior se convertirá en una redirección al nuevo título.
-Los enlaces al antiguo título de la página no se cambiarán.
-Asegúrate de no dejar [[Special:DoubleRedirects|redirecciones dobles]] o [[Special:BrokenRedirects|rotas]].
-Tú eres responsable de hacer que los enlaces sigan apuntando a donde se supone que deberían hacerlo.
-
-Recuerda que la página '''no''' será renombrada si ya existe una página con el nuevo título, a no ser que sea una página vacía o una redirección sin historial.
-Esto significa que podrás renombrar una página a su título original si has cometido un error, pero que no podrás sobrescribir una página existente.
-
-'''¡Aviso!'''
-Este puede ser un cambio drástico e inesperado para una página popular;
-por favor, asegúrate de entender las consecuencias del procedimiento antes de seguir adelante.",
+'movepagetext' => "Mediante el siguiente formulario puedes renombrar una página, moviendo todo su historial al nombre nuevo.
+El título anterior redirigirá al nuevo.
+Puedes actualizar automáticamente las redirecciones que apuntan al título original.
+Si eliges no hacerlo, asegúrate de revisar posibles redirecciones [[Special:DoubleRedirects|dobles]] o [[Special:BrokenRedirects|rotas]].
+Tú eres responsable de asegurar que los enlaces continúen funcionando correctamente.
+
+Nota que la página '''no''' se moverá si ya hay una página con el título nuevo, a menos de que ésta sea una redirección y no tenga historial de ediciones pasadas.
+Esto significa que puedes deshacer el renombrado en caso de un error, y que no puedes sobreescribir una página existente.
+
+'''Aviso'''
+Esto puede representar un cambio drástico e inesperado para una página popular;
+asegúrate de entender las consecuencias de esta acción antes de proceder.",
 'movepagetext-noredirectfixer' => "Usando el siguiente formulario se renombrará una página, trasladando todo su historial al nuevo nombre.
 El título anterior se convertirá en una redirección al nuevo título.
 Asegúrate de no dejar [[Special:DoubleRedirects|redirecciones dobles]] o [[Special:BrokenRedirects|rotas]].
@@ -3180,6 +3185,7 @@ Esto podría estar causado por un enlace a un sitio externo incluido en la lista
 'pageinfo-robot-noindex' => 'No indexable',
 'pageinfo-views' => 'Número de vistas',
 'pageinfo-watchers' => 'Número de usuarios que vigilan la página',
+'pageinfo-few-watchers' => 'Menos de $1 {{PLURAL:$1|vigilante|vigilantes}}',
 'pageinfo-redirects-name' => 'Redirecciones a esta página',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Subpáginas de esta página',
@@ -3195,6 +3201,7 @@ Esto podría estar causado por un enlace a un sitio externo incluido en la lista
 'pageinfo-magic-words' => '{{PLURAL:$1|Palabra mágica|Palabras mágicas}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoría oculta|Categorías ocultas}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Plantilla incluida|Plantillas incluidas}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Página incluida|Páginas incluidas}} ($1)',
 'pageinfo-toolboxlink' => 'Información de la página',
 'pageinfo-redirectsto' => 'Redirige a',
 'pageinfo-redirectsto-info' => 'Información',
@@ -3299,6 +3306,8 @@ Ejecutarlo podría comprometer la seguridad de su equipo.",
 'minutes' => '{{PLURAL:$1|un minuto|$1 minutos}}',
 'hours' => '{{PLURAL:$1|una hora|$1 horas}}',
 'days' => '{{PLURAL:$1|un día|$1 días}}',
+'months' => '{{PLURAL:$1|$1 mes|$1 meses}}',
+'years' => '{{PLURAL:$1|$1 año|$1 años}}',
 'ago' => 'hace $1',
 'just-now' => 'Ahora mismo',
 
@@ -3953,7 +3962,7 @@ Las imágenes se muestran en resolución máxima, otros tipos de archivo se inic
 'specialpages-group-highuse' => 'Páginas sobre usos',
 'specialpages-group-pages' => 'Listas de páginas',
 'specialpages-group-pagetools' => 'Herramientas de páginas',
-'specialpages-group-wiki' => 'Herramientas y datos del wiki',
+'specialpages-group-wiki' => 'Herramientas y datos',
 'specialpages-group-redirects' => 'Búsquedas y redirecciones',
 'specialpages-group-spam' => 'Herramientas anti-SPAM',
 
@@ -4051,8 +4060,8 @@ Este sitio está experimentando dificultades técnicas.',
 'logentry-newusers-newusers' => 'Se ha creado la cuenta de usuario $1',
 'logentry-newusers-create' => 'Se ha creado la cuenta de usuario $1',
 'logentry-newusers-create2' => '$1 ha creado la cuenta de usuario $3',
+'logentry-newusers-byemail' => '$1 creó la cuenta de usuario $3 y la contraseña se envió por correo electrónico',
 'logentry-newusers-autocreate' => 'La cuenta $1 fue creada automáticamente',
-'newuserlog-byemail' => 'contraseña enviada por correo electrónico',
 'logentry-rights-rights' => '$1 modificó los grupos a los que pertenece $3: de $4 a $5',
 'logentry-rights-rights-legacy' => '$1 ha cambiado la pertenencia a grupos de $3',
 'logentry-rights-autopromote' => '$1 fue promocionado automáticamente de $4 a $5',
@@ -4111,6 +4120,7 @@ En otro caso, puedes usar el siguiente formulario. Tu comentario será añadido
 'api-error-ok-but-empty' => 'Error interno: No hay respuesta del servidor.',
 'api-error-overwrite' => 'No se permite sobrescribir un archivo existente.',
 'api-error-stashfailed' => 'Error interno: El servidor no pudo almacenar el archivo temporal.',
+'api-error-publishfailed' => 'Error interno: el servidor no pudo publicar el archivo temporal.',
 'api-error-timeout' => 'El servidor no respondió en el plazo previsto.',
 'api-error-unclassified' => 'Ocurrió un error desconocido.',
 'api-error-unknown-code' => 'Error desconocido: «$1»',
index 847affb..d914a18 100644 (file)
@@ -425,7 +425,7 @@ $messages = array(
 'moredotdotdot' => 'Veel...',
 'mypage' => 'Minu lehekülg',
 'mytalk' => 'Arutelu',
-'anontalk' => 'Arutelu selle IP jaoks',
+'anontalk' => 'Selle IP-aadressi artuelu',
 'navigation' => 'Navigeerimine',
 'and' => '&#32;ja',
 
@@ -701,7 +701,7 @@ Võid jätkata {{GRAMMAR:genitive|{{SITENAME}}}} kasutamist anonüümselt, aga k
 Pane tähele, et seni kuni sa pole oma võrgulehitseja puhvrit tühjendanud, võidakse mõni lehekülg endiselt nii kuvada nagu oleksid ikka sisse logitud.",
 'welcomeuser' => 'Tere tulemast, $1!',
 'welcomecreation-msg' => 'Sinu konto on loodud.
-Ära unusta seada oma {{GRAMMAR:genitive|{{SITENAME}}}} [[Eri:Eelistused|eelistusi]].',
+Ära unusta seada oma {{GRAMMAR:genitive|{{SITENAME}}}} [[Special:Preferences|eelistusi]].',
 'yourname' => 'Kasutajanimi:',
 'yourpassword' => 'Parool:',
 'yourpasswordagain' => 'Sisesta parool uuesti:',
@@ -724,7 +724,7 @@ Pane tähele, et seni kuni sa pole oma võrgulehitseja puhvrit tühjendanud, võ
 'gotaccount' => "Kui sul on juba konto, '''$1'''.",
 'gotaccountlink' => 'logi sisse',
 'userlogin-resetlink' => 'Kas oled unustanud oma sisselogimisandmed?',
-'createaccountmail' => 'E-posti teel',
+'createaccountmail' => 'Kasuta juhuslikku parooli ja saada see allpool määratud e-posti aadressile',
 'createaccountreason' => 'Põhjus:',
 'badretype' => 'Sisestatud paroolid ei lange kokku.',
 'userexists' => 'Sisestatud kasutajanimi on juba kasutusel.
@@ -744,7 +744,7 @@ Kontrollige kirjapilti või [[Special:UserLogin/signup|looge uus kasutajakonto]]
 'nosuchusershort' => 'Kasutajat nimega "$1" ei ole olemas. Kontrollige kirjapilti.',
 'nouserspecified' => 'Kasutajanimi puudub.',
 'login-userblocked' => 'See kasutaja on blokeeritud. Sisselogimine pole lubatud.',
-'wrongpassword' => 'Vale parool. Proovige uuesti.',
+'wrongpassword' => 'Vale parool. Proovi uuesti.',
 'wrongpasswordempty' => 'Parool jäi sisestamata. Palun proovi uuesti.',
 'passwordtooshort' => 'Parool peab koosnema vähemalt {{PLURAL:$1|ühest|$1}} tähemärgist.',
 'password-name-match' => 'Parool peab kasutajanimest erinema.',
@@ -1699,7 +1699,7 @@ Faili lisamiseks artiklile kasuta linki ühel kujul järgnevatest.
 'ignorewarning' => 'Ignoreeri hoiatust ja salvesta fail hoiatusest hoolimata',
 'ignorewarnings' => 'Ignoreeri hoiatusi',
 'minlength1' => 'Faili nimes peab olema vähemalt üks kirjamärk.',
-'illegalfilename' => 'Faili "$1" nimi sisaldab sümboleid, mis pole pealkirjades lubatud. Palun nimetage fail ümber ja proovige uuesti.',
+'illegalfilename' => 'Failinimi "$1" sisaldab märke, mis pole pealkirjades lubatud. Palun nimeta fail ümber ja proovi uuesti.',
 'filename-toolong' => 'Failinimed ei või olla pikemad kui 240 baiti.',
 'badfilename' => 'Pildi nimi on muudetud. Uus nimi on "$1".',
 'filetype-mime-mismatch' => 'Faililaiend ".$1" ei vasta faili ($2) MIME tüübile.',
@@ -2180,7 +2180,7 @@ Vaata ka [[Special:WantedCategories|puuduvaid kategooriaid]].',
 'linksearch-ok' => 'Otsi',
 'linksearch-text' => 'Metamärgina võib kasutada tärni, näiteks "*.wikipedia.org".
 Otsingus peab olema vähemalt tipptaseme domeen, näiteks "*.org".<br />
-Toetatud protokollid: <code>$1</code> (määramata protokolli korral vaikimisi http://).',
+Toetatud {{PLURAL:$2|protokoll|protokollid}}: <code>$1</code> (määramata protokolli korral vaikimisi http://).',
 'linksearch-line' => '$1 on lingitud leheküljelt $2',
 'linksearch-error' => 'Metamärk võib olla ainult internetiaadressi alguses.',
 
@@ -2193,7 +2193,7 @@ Toetatud protokollid: <code>$1</code> (määramata protokolli korral vaikimisi h
 # Special:ActiveUsers
 'activeusers' => 'Aktiivsete kasutajate nimekiri',
 'activeusers-intro' => 'See on loetelu kasutajatest, kes on viimase $1 {{PLURAL:$1|päev|päeva}} jooksul midagi teinud.',
-'activeusers-count' => '$1 {{PLURAL:$1|muudatus|muudatust}} viimase {{PLURAL:$3|päeva|$3 päeva}} jooksul',
+'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',
@@ -2419,9 +2419,9 @@ Allpool on toodud lehekülje '''$1''' hetkel kehtivad seaded:",
 'protect-cascadeon' => 'See lehekülg on kaitstud, kuna ta on kasutusel {{PLURAL:$1|järgmisel leheküljel|järgmistel lehekülgedel}}, mis on omakorda kaskaadkaitse all.
 Sa saad muuta selle lehekülje kaitse staatust, kuid see ei mõjuta kaskaadkaitset.',
 'protect-default' => 'Luba kõigile kasutajatele',
-'protect-fallback' => 'Nõuab "$1" õiguseid',
-'protect-level-autoconfirmed' => 'Blokeeri uued ja registreerimata kasutajad',
-'protect-level-sysop' => 'Ainult administraatorid',
+'protect-fallback' => 'Lubatud vaid kasutajatele õigusega "$1"',
+'protect-level-autoconfirmed' => 'Lubatud vaid automaatselt kinnitatud kasutajatele',
+'protect-level-sysop' => 'Lubatud vaid administraatoritele',
 'protect-summary-cascade' => 'kaskaad',
 'protect-expiring' => 'aegub $1 (UTC)',
 'protect-expiring-local' => 'aegub $1',
@@ -2724,7 +2724,7 @@ Saad senisele pealkirjale viitavad ümbersuunamised automaatselt parandada.
 Kui sa seda ei tee, kontrolli, et teisaldamise tõttu ei jää maha [[Special:DoubleRedirects|kahekordseid]] ega [[Special:BrokenRedirects|katkiseid ümbersuunamisi]].
 Sinu kohus on hoolitseda selle eest, et kõik jääks toimima, nagu ette nähtud.
 
-Pane tähele, et lehekülge '''ei teisaldata''' juhul, kui uue pealkirjaga lehekülg on juba olemas. Erandiks on juhud, kui olemasolev lehekülg on tühi või redigeerimisajaloota ümbersuunamislehekülg.
+Pane tähele, et lehekülge '''ei teisaldata''' juhul, kui uue pealkirjaga lehekülg on juba olemas. Erandiks on juhud, kui viimane on redigeerimisajaloota ümbersuunamislehekülg.
 See tähendab, et kogemata ei saa üle kirjutada juba olemasolevat lehekülge, kuid saab ebaõnnestunud ümbernimetamise tagasi pöörata.
 
 '''Hoiatus!'''
@@ -3049,6 +3049,7 @@ See on ilmselt põhjustatud linkimisest mustas nimekirjas olevasse välisvõrguk
 'pageinfo-robot-noindex' => 'Indekseerimatu',
 'pageinfo-views' => 'Vaatamiste arv',
 'pageinfo-watchers' => 'Lehekülje jälgijate arv',
+'pageinfo-few-watchers' => 'Alla {{PLURAL:$1|ühe jälgija|$1 jälgija}}',
 'pageinfo-redirects-name' => 'Ümbersuunamisi sellele leheküljele',
 'pageinfo-subpages-name' => 'Selle lehekülje alamlehekülgi',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|ümbersuunamine|ümbersuunamist}}; $3 {{PLURAL:$3|mitteümbersuunamine|mitteümbersuunamist}})',
@@ -3071,6 +3072,10 @@ See on ilmselt põhjustatud linkimisest mustas nimekirjas olevasse välisvõrguk
 'pageinfo-protect-cascading' => 'Siit lähtub kaskaadkaitse',
 'pageinfo-protect-cascading-yes' => 'Jah',
 'pageinfo-protect-cascading-from' => 'Kaskaadkaitse lähtub lehekülgedelt',
+'pageinfo-category-info' => 'Kategooria teave',
+'pageinfo-category-pages' => 'Lehekülgede arv',
+'pageinfo-category-subcats' => 'Alamkategooriate arv',
+'pageinfo-category-files' => 'Failide arv',
 
 # Skin names
 'skinname-standard' => 'Algeline',
@@ -3778,7 +3783,7 @@ Pilt kuvatakse algupärases suuruses, muu fail avatakse koheselt seostuva progra
 'specialpages-group-highuse' => 'Tihti kasutatud leheküljed',
 'specialpages-group-pages' => 'Lehekülgede loendid',
 'specialpages-group-pagetools' => 'Töö lehekülgedega',
-'specialpages-group-wiki' => 'Viki andmed ja tööriistad',
+'specialpages-group-wiki' => 'Andmed ja tööriistad',
 'specialpages-group-redirects' => 'Ümbersuunavad erilehed',
 'specialpages-group-spam' => 'Töö spämmiga',
 
@@ -3876,7 +3881,6 @@ Pilt kuvatakse algupärases suuruses, muu fail avatakse koheselt seostuva progra
 'logentry-newusers-create' => 'Loodud kasutajakonto $1',
 'logentry-newusers-create2' => '$1 lõi kasutajakonto $3',
 'logentry-newusers-autocreate' => 'Konto $1 loodi automaatselt',
-'newuserlog-byemail' => 'parool saadetud e-postiga',
 'rightsnone' => '(puudub)',
 
 # Feedback
index 56cb1f4..e7fbd65 100644 (file)
@@ -244,9 +244,9 @@ $messages = array(
 'hidden-category-category' => 'Kategoria ezkutuak',
 'category-subcat-count' => '{{PLURAL:$2|Kategoria honek beste honako azpikategoria baino ez du.|Kategoria honek honako {{PLURAL:$1|azpikategoria du|$1 azpikategoriak ditu}}, guztira dauden $2tik.}}',
 'category-subcat-count-limited' => 'Kategoria honek {{PLURAL:$1|azpikategoria hau du|$1 azpikategoria hauek ditu}}.',
-'category-article-count' => '{{PLURAL:$2|Kategoria honek ondorengo orri hau baino ez du.|Ondorengo {{PLURAL:$1|orria kategoria honetan dago|$1 orriak kategoria honetan daude}}; eta kategoria honetan, guztira, $2 orri daude.}}',
+'category-article-count' => '{{PLURAL:$2|Kategoria honek honako orrialdea baino ez du.|Honako {{PLURAL:$1|orrialdea kategoria honetan dago|$1 orrialdeak kategoria hauetan daude}}, guztira dauden $2 (e)tik.}}',
 'category-article-count-limited' => 'Ondorengo {{PLURAL:$1|orri hau kategoria honetan dago.|$1 orri hauek kategoria honetan daude.}}',
-'category-file-count' => '{{PLURAL:$2|Kategoria honek fitxategi hau baino ez du.|Ondorengo {{PLURAL:$1|fitxategia kategoria honetan dago|$1 fitxategiak kategoria honetan daude}}. Eta kategoria honetan, guztira, $2 fitxategi daude.}}',
+'category-file-count' => '{{PLURAL:$2|Kategoria honek fitxategi hau baino ez du.|Honako {{PLURAL:$1|fitxategia kategoria honetan dago|$1 fitxategiak kategoria honetan daude}} guztira dauden $2 (e)tik.}}',
 'category-file-count-limited' => 'Ondorengo {{PLURAL:$1|fitxategia kategoria honetan dago.|$1 fitxategiak kategoria honetan daude.}}',
 'listingcontinuesabbrev' => 'jarr.',
 'index-category' => 'Indexatutako orrialdeak',
@@ -258,6 +258,7 @@ $messages = array(
 'newwindow' => '(leiho berrian irekitzen da)',
 'cancel' => 'Utzi',
 'moredotdotdot' => 'Gehiago...',
+'morenotlisted' => 'Zerrendatu gabeko gehiago...',
 'mypage' => 'Orrialdea',
 'mytalk' => 'Eztabaida',
 'anontalk' => 'IP honen eztabaida',
@@ -388,6 +389,9 @@ $1',
 'youhavenewmessages' => '$1 dauzkazu ($2).',
 'newmessageslink' => 'Mezu berriak',
 'newmessagesdifflink' => 'azken aldaketa ikusi',
+'youhavenewmessagesfromusers' => '{{PLURAL:$3|Beste erabiltzaile baten|$3 erabiltzaileren}} $1 ($2).',
+'youhavenewmessagesmanyusers' => 'Hainbat erabiltzaileren $1 ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|Mezu berri bat duzu|Mezu berriak dituzu}}',
 'newmessagesdifflinkplural' => 'azken {{PLURAL:$1|aldaketa|aldaketak}}',
 'youhavenewmessagesmulti' => 'Mezu berriak dituzu $1(e)n',
 'editsection' => 'aldatu',
@@ -482,6 +486,8 @@ Mesedez, bidali gertakar hau administradore bati, URLaren izena jarriz.',
 'cannotdelete' => 'Ezin izan da «$1» orria edo fitxategia ezabatu.
 Baliteke beste norbaitek ezabatu izana.',
 'cannotdelete-title' => 'Ezin da "$1" orrialdea ezabatu',
+'delete-hook-aborted' => 'Ezabatzea hook batek gelditu du.
+Ez du arrazoirik eman.',
 'badtitle' => 'Izenburu ezegokia',
 'badtitletext' => 'Eskatutako orrialde izenburua ez da baliozkoa, hutsik dago, edo gaizki lotutako hizkuntzen arteko lotura da. Baliteke izenburuetan erabili ezin den karaktereren bat izatea.',
 'perfcached' => 'Hurrengo datuak katxean gordeta daude eta litekeena da guztiz eguneratuta ez egotea. Gehienez {{PLURAL:$1|emaitza 1 dago|$1 emaitza daude}} eskuragarri katxean.',
@@ -507,9 +513,16 @@ Itzulpenetarako, erabil ezazu [//translatewiki.net/ translatewiki.net], MediaWik
 'cascadeprotected' => "Orrialde hau aldaketen aurka babestua dago, ''kaskada'' aukerarekin babestu {{PLURAL:$1|duten orrialde honetan|dituzten orrialde hauetan}} txertaturik dagoelako:
 $2",
 'namespaceprotected' => "Ez daukazu '''$1''' izen-tarteko orrialdeak aldatzeko baimenik.",
+'customcssprotected' => 'Ez duzu baimenik CSS orrialde hau aldatzeko beste erabiltzaile baten hobespen pertsonalak dituelako.',
+'customjsprotected' => 'Ez duzu baimenik JavaScript orrialde hau aldatzeko beste erabiltzaile baten hobespen pertsonalak dituelako.',
 'ns-specialprotected' => 'Ezin dira {{ns:special}} izen-tarteko orrialdeak editatu.',
 'titleprotected' => "[[User:$1|$1]]ek izenburu hau sortzea ekidin zuen.
 Emandako arrazoia ''$2'' izan zen.",
+'filereadonlyerror' => 'Ezin izan da "$1" fitxategia aldatu, "$2" fitxategi bilduma irakrutzeko-bakarrik moduan dagoelako.
+
+Blokeoa ezarri zuen administratzaileak honako arrazoia eman zuen: "$3".',
+'invalidtitle-knownnamespace' => 'Izenburua gaizki dago "$2" izen eremuan eta "$3" testuan',
+'invalidtitle-unknownnamespace' => 'Izenburua gaizki dago "$1" izen eremuan ezezagunean eta "$2" testuan',
 'exception-nologin' => 'Saioa hasi gabe',
 
 # Virus scanner
@@ -544,7 +557,7 @@ Kontuan izan orrialde batzuk saioa hasita bazenu bezala ikus ditzakezula nabigat
 'gotaccount' => "Baduzu erabiltzaile kontua? '''$1'''.",
 'gotaccountlink' => 'Saioa hasi',
 'userlogin-resetlink' => 'Saioa hasteko datuak ahaztu dituzu?',
-'createaccountmail' => 'e-postaz',
+'createaccountmail' => 'Erabili behin-behineko pasahitz ausazko bat eta bidali behean agertzeko den e-posta helbidera',
 'createaccountreason' => 'Arrazoia:',
 'badretype' => 'Idatzitako pasahitzak ez dira berdinak.',
 'userexists' => 'Aukeratutako erabiltzaile izena hartuta dago.
@@ -800,9 +813,10 @@ Era berean, bidaltzen ari zaren edukia zuk zeuk idatzitakoa dela edo jabetza pub
 '''EZ BIDALI BAIMENIK GABEKO COPYRIGHTDUN EDUKIRIK!'''",
 'longpageerror' => "'''Errorea: Bidali duzun testuak {{PLURAL:$1|kilobyte 1eko|$1 kilobyteko}} luzera du, eta {{PLURAL:$2|kilobyte 1eko|$2 kilobyteko}} maximoa baino luzeagoa da.'''
 Ezin da gorde.",
-'readonlywarning' => "'''OHARRA: Datu-basea blokeatu egin da mantenu lanak burutzeko, beraz ezingo dituzu orain zure aldaketak gorde. Testua fitxategi baten kopiatu dezakezu, eta beranduago erabiltzeko gorde.
+'readonlywarning' => "'''Oharra: Datu-basea blokeatu egin da mantenu lanak burutzeko, beraz ezingo dituzu orain zure aldaketak gorde.'''
+Testua fitxategi baten kopiatu dezakezu, eta beranduago erabiltzeko gorde.
 
-Blokeatu zuen administratzaileak honako azalpena eman zuen: $1'''",
+Blokeatu zuen administratzaileak honako azalpena eman zuen: $1",
 'protectedpagewarning' => "'''Oharra:  Orri hau blokeatua dago administratzaileek soilik eraldatu ahal dezaten.'''
 Azken erregistroa ondoren ikusgai dago erreferentzia gisa:",
 'semiprotectedpagewarning' => "'''Oharra''': Orrialde hau erregistratutako erabiltzaileek bakarrik aldatzeko babestuta dago.
@@ -1189,9 +1203,9 @@ Saia zaitez zure eskeraren aurretik ''all:'' jartzen eduki guztien artean bilatz
 'prefs-emailconfirm-label' => 'E-posta baieztapena:',
 'prefs-textboxsize' => 'Editatze lehioaren tamaina',
 'youremail' => 'E-posta:',
-'username' => 'Erabiltzaile izena:',
-'uid' => 'Erabiltzaile zenbakia:',
-'prefs-memberingroups' => '{{PLURAL:$1|Taldeko|taldeetako}} kidea:',
+'username' => '{{GENDER:$1|Erabiltzaile izena}}:',
+'uid' => '{{GENDER:$1|Erabiltzaile}} zenbakia:',
+'prefs-memberingroups' => '{{PLURAL:$1|Taldeko|taldeetako}} {{GENDER:$2|kidea}}:',
 'prefs-registration' => 'Erregistratzeko unea:',
 'yourrealname' => 'Benetako izena:',
 'yourlanguage' => 'Hizkuntza:',
@@ -1863,7 +1877,7 @@ Baimendutako protokoloak: <code>$1</code> (protokoloa zehazten ez bada http:// h
 
 # Special:ActiveUsers
 'activeusers' => 'Lankide aktiboen zerrenda',
-'activeusers-count' => '{{PLURAL:$1|Aldaketa berri bat|$1 aldaketa berri}} azken {{PLURAL:$3|egunean|$3 egunetan}}',
+'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',
@@ -1920,7 +1934,7 @@ Badago [[{{MediaWiki:Listgrouprights-helppage}}|informazio osagarria]] banakako
 'usermessage-editor' => 'Sistemako mezularia',
 
 # Watchlist
-'watchlist' => 'Nire jarraipen zerrenda',
+'watchlist' => 'Jarraipen zerrenda',
 'mywatchlist' => 'Jarraipen zerrenda',
 'watchlistfor2' => '$1 ($2)',
 'nowatchlist' => 'Zure jarraipen zerrenda hutsik dago.',
@@ -2166,7 +2180,7 @@ $1',
 'blanknamespace' => '(Nagusia)',
 
 # Contributions
-'contributions' => 'Lankidearen ekarpenak',
+'contributions' => '{{GENDER:$1|Lankidearen}} ekarpenak',
 'contributions-title' => '$1(r)entzat lankidearen ekarpenak',
 'mycontris' => 'Ekarpenak',
 'contribsub2' => '$1 ($2)',
@@ -2194,7 +2208,7 @@ Blokeo erregistroa azken sarrera ematen da azpian erreferentziarako:',
 # What links here
 'whatlinkshere' => 'Honanzko lotura duten orriak',
 'whatlinkshere-title' => '$1(e)ra lotura duten orriak',
-'whatlinkshere-page' => 'Orrialdea:',
+'whatlinkshere-page' => 'Orria:',
 'linkshere' => "Hauek dute '''[[:$1]]''' orrialderako lotura:",
 'nolinkshere' => "Ez dago '''[[:$1]]''' lotura duen orrialderik.",
 'nolinkshere-ns' => "Hautatutako izen-tartean ez dago '''[[:$1]]''' orrialderako lotura duenik.",
@@ -2349,7 +2363,6 @@ Konturatu zaitez orrialdea '''ez''' dela mugituko izenburu berria duen orrialde
 Horrek esan nahi du hanka sartzekotan orrialde baten jatorrizko izenburua berreskuratu daitekeela, baina ezin dela jada existitzen den orrialde baten gainean idatzi.
 
 '''Oharra!'''
-
 Aldaketa hau drastikoa eta ustekabekoa izan daiteke orrialde oso ezagunetan;
 mesedez, egiazta ezazu honen ondorioak ulertzen dituzula, jarraitu baino lehen.",
 'movepagetalktext' => "Dagokion eztabaida orrialdea berarekin batera mugitu da, honako kasu hauetan '''ezik:'''
@@ -2715,6 +2728,10 @@ Zure sisteman exekutatzea arriskutsua izan liteke.",
 'seconds-abbrev' => '$1s',
 'minutes-abbrev' => '$1m',
 'hours-abbrev' => '$1o',
+'seconds' => '{{PLURAL:$1|segundu $1|$1 segundu}}',
+'minutes' => '{{PLURAL:$1|minutu $1|$1 minutu}}',
+'hours' => '{{PLURAL:$1|ordu $1|$1 ordu}}',
+'days' => '{{PLURAL:$1|egun $1|$1 egun}}',
 'ago' => 'Duela $1',
 
 # Bad image list
@@ -2859,9 +2876,22 @@ Zerrenda elementuak (hasieran * duten lerroak) baino ez dira kontuan hartzen. Le
 'exif-gpsdifferential' => 'GPSaren zuzenketa diferentziala',
 'exif-jpegfilecomment' => 'JPEG fitxategiaren iruzkina',
 'exif-keywords' => 'Hitz gakoak',
+'exif-worldregioncreated' => 'Munduko zein eskualdetan egin den argazki hau',
+'exif-countrycreated' => 'Argazkia egin den herrialdea',
+'exif-countrycodecreated' => 'Argazkia egin deneko herrialdearen kodea',
+'exif-provinceorstatecreated' => 'Argazkia egin deneko probintzia edo estatua',
+'exif-citycreated' => 'Argazkia egin deneko hiria',
+'exif-sublocationcreated' => 'Argazkia egin deneko hiriaren azpieremua',
+'exif-worldregiondest' => 'Munduko eskualdea erakusten da',
 'exif-countrydest' => 'Erakutsitako herrialdea',
+'exif-countrycodedest' => 'Herrialdearen kodea erakusten da',
+'exif-provinceorstatedest' => 'Pronbitzia edo estatua erakusten da',
+'exif-citydest' => 'Hiria erakusten da',
+'exif-sublocationdest' => 'Hiriaren azpikokapena erakusten da',
 'exif-objectname' => 'Izenburua laburra',
+'exif-specialinstructions' => 'Agindu bereziak',
 'exif-headline' => 'Goiburua',
+'exif-credit' => 'Kreditua/Emalea',
 'exif-source' => 'Jatorria',
 'exif-urgency' => 'Larrialdia',
 'exif-writer' => 'Idazlea',
@@ -3261,7 +3291,7 @@ Irudiak bereizmen handienean daude, bestelako fitxategi motak beraiei esleitutak
 'specialpages-group-highuse' => 'Erabilera handiko orrialdeak',
 'specialpages-group-pages' => 'Orrialdeen zerrendak',
 'specialpages-group-pagetools' => 'Orrialde tresnak',
-'specialpages-group-wiki' => 'Wiki datuak eta tresnak',
+'specialpages-group-wiki' => 'Datuak eta tresnak',
 'specialpages-group-redirects' => 'Berbideraketa-orri bereziak',
 'specialpages-group-spam' => 'Spam tresnak',
 
@@ -3330,10 +3360,9 @@ Irudiak bereizmen handienean daude, bestelako fitxategi motak beraiei esleitutak
 'logentry-move-move-noredirect' => '$1 wikilariak «$3» orria «$4» izenera aldatu du, birzuzenketarik utzi gabe',
 'logentry-move-move_redir' => '$1 wikilariak «$3» orria «$4» izenera aldatu du, birzuzenketaren gainetik',
 'logentry-move-move_redir-noredirect' => '$1 wikilariak «$3» orria «$4» izenera aldatu du, birzuzenketa bat gainidatzita, birzuzenketarik utzi gabe',
-'logentry-newusers-newusers' => '$1 wikilariak erabiltzaile kontu bat sortu du',
-'logentry-newusers-create' => '$1 wikilariak erabiltzaile kontu bat sortu du',
-'logentry-newusers-create2' => '$1 wikilariak $3 erabiltzaile kontu bat sortu du',
-'newuserlog-byemail' => 'pasahitza e-postaz bidali da',
+'logentry-newusers-newusers' => '$1 erabiltzaile kontua sortu da',
+'logentry-newusers-create' => '$1 erabiltzaile kontua sortu da',
+'logentry-newusers-create2' => '$1 wikilariak $3 erabiltzaile kontua sortu du',
 'rightsnone' => '(bat ere ez)',
 
 # Feedback
index 2d52418..bc0f2ea 100644 (file)
@@ -2404,7 +2404,6 @@ Las imahin se muestran a resolución compreta; las demas crasis d'archivu s'ehec
 # New logging system
 'revdelete-restricted' => 'las restricionis a los çahorilis án siu apricás',
 'revdelete-unrestricted' => 'las restricionis a los çahorilis án siu esborrás',
-'newuserlog-byemail' => 'consínia enviá pol e-mail',
 'rightsnone' => '(dengunu)',
 
 );
index bb0931b..41654e5 100644 (file)
@@ -873,7 +873,7 @@ $2',
 'gotaccount' => 'حساب کاربری دارید؟ $1.',
 'gotaccountlink' => 'به سامانه وارد شوید',
 'userlogin-resetlink' => 'جزئیات ورود را فراموش کرده‌اید؟',
-'createaccountmail' => 'با Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87',
+'createaccountmail' => 'استÙ\81ادÙ\87 Ø§Ø² Ø±Ù\85ز Ø¹Ø¨Ù\88ر Ù\85Ù\88Ù\82ت ØªØµØ§Ø¯Ù\81Û\8c Ù\88 Ø§Ø±Ø³Ø§Ù\84 Ø¢Ù\86 Ø¨Ù\87 Ø¢Ø¯Ø±Ø³ Ø§Û\8cÙ\85Û\8cÙ\84 Ù\85شخص Ø´Ø¯Ù\87 Ø¯Ø± Ø²Û\8cر',
 'createaccountreason' => 'دلیل:',
 'badretype' => 'گذرواژه‌هایی که وارد کرده‌اید یکسان نیستند.',
 'userexists' => 'نام کاربری‌ای که وارد کردید قبلاً استفاده شده‌است.
@@ -1491,7 +1491,7 @@ $1",
 'search-interwiki-default' => '$1 نتیجه:',
 'search-interwiki-more' => '(بیشتر)',
 'search-relatedarticle' => 'مرتبط',
-'mwsuggest-disable' => 'پیشنهادهای مبتنی بر AJAX را غیرفعال کن',
+'mwsuggest-disable' => 'پیشنهادهای مبتنی بر جستجو را غیرفعال کن',
 'searcheverything-enable' => 'جستجو در تمام فضاهای نام',
 'searchrelated' => 'مرتبط',
 'searchall' => 'همه',
@@ -2404,7 +2404,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
 # Special:ActiveUsers
 'activeusers' => 'فهرست کاربران فعال',
 'activeusers-intro' => 'در زیر فهرستی از کاربرانی را می‌بینید که در $1 {{PLURAL:$1|روز|روز}} گذشته فعالیتی داشته‌اند.',
-'activeusers-count' => '$1 {{PLURAL:$1|Ù\88Û\8cراÛ\8cØ´|Ù\88Û\8cراÛ\8cØ´}} در {{PLURAL:$3|روز|$3 روز}} اخیر',
+'activeusers-count' => '$1 {{PLURAL:$1|Ù\81عاÙ\84Û\8cت|Ù\81عاÙ\84Û\8cت}} در {{PLURAL:$3|روز|$3 روز}} اخیر',
 'activeusers-from' => 'نمایش کاربران با آغاز از:',
 'activeusers-hidebots' => 'نهفتن ربات‌ها',
 'activeusers-hidesysops' => 'نهفتن مدیران',
@@ -2467,7 +2467,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
 'usermessage-editor' => 'پیغام رسان سامانه',
 
 # Watchlist
-'watchlist' => 'فهرست پی‌گیری‌های من',
+'watchlist' => 'فهرست پی‌گیری',
 'mywatchlist' => 'فهرست پی‌گیری‌ها',
 'watchlistfor2' => 'برای $1 $2',
 'nowatchlist' => 'در فهرست پی‌گیری‌های شما هیچ موردی نیست.',
@@ -2946,7 +2946,7 @@ $1',
 '''شما''' مسئول اطمینان از این هستید که پیوندها هنوز به همان‌جایی که قرار است بروند.
 
 توجه کنید که اگر از قبل صفحه‌ای در عنوان جدید وجود داشته باشد صفحه منتقل '''نخواهد شد'''،
-مگر این که صفحه خالی یا تغییرمسیر باشد و تاریخچهٔ ویرایشی نداشته باشد.
+مگر این آخرین ویرایش تغییرمسیر باشد و در  تاریخچهٔ ویرایشی نداشته باشد.
 این یعنی اگر اشتباه کردید می‌توانید صفحه را به همان جایی که از آن منتقل شده بود برگردانید، و این که نمی‌توانید روی صفحه‌ها موجود بنویسید.
 
 '''هشدار!'''
@@ -3271,6 +3271,7 @@ $1',
 'pageinfo-robot-noindex' => 'عدم فهرست‌پذیری',
 'pageinfo-views' => 'شمار بازدیدها',
 'pageinfo-watchers' => 'شمار پی‌گیری‌کنندگان صفحه',
+'pageinfo-few-watchers' => 'کمتر از  $1 {{PLURAL:$1| پی‌گیر|پی‌گیر}}',
 'pageinfo-redirects-name' => 'تغییرمسیرها به این صفحه',
 'pageinfo-subpages-name' => 'زیرصفحه‌های این صفحه',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|تغییرمسیر|تغییرمسیر}}; $3 {{PLURAL:$3|غیرتغییرمسیر|غیرتغییرمسیر}})',
@@ -4107,7 +4108,7 @@ $5
 'specialpages-group-highuse' => 'صفحه‌های پربازدید',
 'specialpages-group-pages' => 'فهرست‌های صفحه‌ها',
 'specialpages-group-pagetools' => 'ابزارهای صفحه‌ها',
-'specialpages-group-wiki' => 'اطÙ\84اعات Ù\88 Ø§Ø¨Ø²Ø§Ø±Ù\87اÛ\8c Ù\88Û\8cÚ©Û\8c',
+'specialpages-group-wiki' => 'دادÙ\87 Ù\88 Ø§Ø¨Ø²Ø§Ø±Ù\87ا',
 'specialpages-group-redirects' => 'صفحه‌های ویژهٔ تغییرمسیر دهنده',
 'specialpages-group-spam' => 'ابزارهای هرزنگاری',
 
@@ -4205,8 +4206,8 @@ $5
 'logentry-newusers-newusers' => 'حساب کاربری $1 ایجاد شد',
 'logentry-newusers-create' => 'حساب کاربری $1 ایجاد شد',
 'logentry-newusers-create2' => 'حساب کاربری $3 توسط $1 ایجاد شد',
+'logentry-newusers-byemail' => 'حساب کاربری  $3  توسط $1 ایجاد شد و رمز عبور به وسیلهٔ ایمیل ارسال شد',
 'logentry-newusers-autocreate' => 'حساب $1  به شکل خودکار ساخته شد',
-'newuserlog-byemail' => 'گذرواژه بوسیله رایانامه ارسال شد',
 'logentry-rights-rights' => '$1 عضویت $3 را از گروه $4 به $5 تغییر داد',
 'logentry-rights-rights-legacy' => '$1 گروه عضویت $3 را تغییر داد',
 'logentry-rights-autopromote' => '$1 به طور خودکار از $4 به $5 ارتقا یافت',
@@ -4263,6 +4264,7 @@ $5
 'api-error-ok-but-empty' => 'خطای داخلی : پاسخی از سرور دریافت نشد.',
 'api-error-overwrite' => 'جای نوشتن یک پرونده موجود مجاز نیست.',
 'api-error-stashfailed' => 'خطای داخلی: کارساز نمی‌تواند پرونده موقت را ذخیره کند.',
+'api-error-publishfailed' => 'خطای داخلی: کارساز نمی‌تواند پرونده موقت را ذخیره کند.',
 'api-error-timeout' => 'کارساز در زمان انتظار هیچ پاسخی نداد.',
 'api-error-unclassified' => 'یک خطای ناشناخته رخ داد.',
 'api-error-unknown-code' => 'خطای ناشناخته: " $1 "',
index 1791338..314959c 100644 (file)
@@ -109,6 +109,7 @@ $specialPageAliases = array(
        'MIMEsearch'                => array( 'MIME-haku' ),
        'Mostcategories'            => array( 'Luokitelluimmat_sivut' ),
        'Mostimages'                => array( 'Viitatuimmat_tiedostot' ),
+       'Mostinterwikis'            => array( 'Eniten_kielilinkkejä' ),
        'Mostlinked'                => array( 'Viitatuimmat_sivut' ),
        'Mostlinkedcategories'      => array( 'Viitatuimmat_luokat' ),
        'Mostlinkedtemplates'       => array( 'Viitatuimmat_mallineet' ),
@@ -445,6 +446,7 @@ $messages = array(
 'newwindow' => '(avautuu uuteen ikkunaan)',
 'cancel' => 'Peruuta',
 'moredotdotdot' => 'Lisää...',
+'morenotlisted' => 'Lisää...',
 'mypage' => 'Käyttäjäsivu',
 'mytalk' => 'Keskustelusivu',
 'anontalk' => 'Keskustele tämän IP:n kanssa',
@@ -740,7 +742,7 @@ Huomaa, että jotkut sivut saattavat näkyä edelleen kuin olisit kirjautunut si
 'gotaccount' => "Jos sinulla on jo tunnus, voit '''$1'''.",
 'gotaccountlink' => 'kirjautua sisään',
 'userlogin-resetlink' => 'Unohditko salasanasi?',
-'createaccountmail' => 'sähköpostitse',
+'createaccountmail' => 'Käytä satunnaista väliaikaissalasanaa ja lähetä se alla määritettyyn sähköpostiosoitteeseen',
 'createaccountreason' => 'Syy',
 'badretype' => 'Syöttämäsi salasanat ovat erilaiset.',
 'userexists' => 'Pyytämäsi käyttäjänimi on jo käytössä. Valitse toinen käyttäjänimi.',
@@ -799,6 +801,7 @@ Odota ennen kuin yrität uudelleen.',
 # E-mail sending
 'php-mail-error-unknown' => 'Tuntematon virhe PHP:n mail()-funktiossa',
 'user-mail-no-addy' => 'Yritit lähettää sähköpostia ilman sähköpostiosoitetta.',
+'user-mail-no-body' => 'Sähköpostin sisältö ei ole tarpeeksi pitkä.',
 
 # Change password dialog
 'resetpass' => 'Muuta salasana',
@@ -1049,6 +1052,7 @@ Se on ilmeisesti poistettu.',
 'edit-already-exists' => 'Uuden sivun luominen ei onnistunut.
 Se on jo olemassa.',
 'defaultmessagetext' => 'Viestin oletusteksti',
+'content-failed-to-parse' => 'Sisältö tyypiltään $2 ei jäsenny tyypiksi $1: $3',
 'invalid-content-data' => 'Virheellinen sisältö',
 'content-not-allowed-here' => 'Sivun [[$2]] sisältö ei voi olla tyyppiä $1.',
 
@@ -1183,18 +1187,18 @@ Muut ylläpitäjät {{GRAMMAR:inessive|{{SITENAME}}}} voivat silti tarkastella p
 'revdelete-radio-set' => 'Kyllä',
 'revdelete-radio-unset' => 'Ei',
 'revdelete-suppress' => 'Häivytä tiedot myös ylläpitäjien näkyviltä samalla kun piilotat ne muilta käyttäjiltä',
-'revdelete-unsuppress' => 'Poista rajoitukset palautetuilta versiolta',
+'revdelete-unsuppress' => 'Poista rajoitukset palautetuilta versioilta',
 'revdelete-log' => 'Syy',
 'revdelete-submit' => 'Toteuta {{PLURAL:$1|valittuun versioon|valittuihin versioihin}}',
 'revdelete-success' => "'''Version näkyvyys päivitetty.'''",
 'revdelete-failure' => "'''Version näkyvyyttä ei voitu päivittää:'''
 $1",
-'logdelete-success' => 'Tapahtuman näkyvyys asetettu.',
+'logdelete-success' => "'''Lokitapahtuman näkyvyyttä on muutettu.'''",
 'logdelete-failure' => "'''Lokin näkyvyyttä ei voitu asettaa:'''
 $1",
 'revdel-restore' => 'muuta näkyvyyttä',
-'revdel-restore-deleted' => 'poistetut muutokset',
-'revdel-restore-visible' => 'näkyvät muutokset',
+'revdel-restore-deleted' => 'poistetut versiot',
+'revdel-restore-visible' => 'näkyvät versiot',
 'pagehist' => 'Sivun muutoshistoria',
 'deletedhist' => 'Poistettujen versioiden historia',
 'revdelete-hide-current' => 'Virhe tapahtui $2, $1 päivätyn kohteen piilottamisessa: tämä on nykyinen versio. Sitä ei voi piilottaa.',
@@ -1202,7 +1206,7 @@ $1",
 Sinulla ei ole oikeutta siihen.',
 'revdelete-modify-no-access' => 'Virhe tapahtui $2, $1 kohteen muokkauksessa: tämä kohde on merkitty "rajoitetuksi". Sinulla ei ole oikeuksia sen muokkaukseen.',
 'revdelete-modify-missing' => 'Virhe muuttaessa kohdetta, jonka tunnus on $1: Se puuttuu tietokannasta.',
-'revdelete-no-change' => "'''Varoitus:''' kohdalle $2 kello $1 on asetettu valmiiksi näkyvyysasetuksia.",
+'revdelete-no-change' => "'''Varoitus:''' kohteessa $2 kello $1 on jo valmiiksi haluamasi näkyvyysasetukset.",
 'revdelete-concurrent-change' => 'Virhe $2, $1 päivätyn kohteen muokkauksessa: sen tilan on näköjään muuttanut joku sillä aikaa kun yritit muokata sitä. Ole hyvä ja tarkista lokit.',
 'revdelete-only-restricted' => 'Virhe piilotettaessa $1 kello $2 päivättyä kohdetta: Et voi poistaa kohteita ylläpitäjien näkyviltä valitsematta myös jotain muuta näkyvyysasetusta.',
 'revdelete-reason-dropdown' => '*Yleiset poistosyyt
@@ -1309,7 +1313,7 @@ $1 {{int:pipe-separator}} $2',
 'search-interwiki-default' => 'Tulokset osoitteesta $1:',
 'search-interwiki-more' => '(lisää)',
 'search-relatedarticle' => 'Hae samankaltaisia sivuja',
-'mwsuggest-disable' => 'Älä näytä ehdotuksia AJAXilla',
+'mwsuggest-disable' => 'Älä näytä hakuehdotuksia',
 'searcheverything-enable' => 'Hae kaikista nimiavaruuksista',
 'searchrelated' => 'samankaltainen',
 'searchall' => 'kaikki',
@@ -2197,7 +2201,7 @@ Vaaditaan vähintään ylätason verkkotunnus, esimerkiksi "*.org".<br />
 # Special:ActiveUsers
 '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|muokkaus|muokkausta}} viimeisen {{PLURAL:$3|päivän|$3 päivän}} aikana',
+'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',
@@ -2295,7 +2299,7 @@ Tulevaisuudessa sivuun ja sen keskustelusivuun tehtävät muutokset listataan t
 'watcherrortext' => 'Sivun ”$1” tarkkailulista-asetusten muutoksissa tapahtui virhe.',
 
 'enotif_mailer' => '{{GRAMMAR:genitive|{{SITENAME}}}} sivu on muuttunut -ilmoitus',
-'enotif_reset' => 'Merkitse kaikki sivut kerralla nähdyiksi',
+'enotif_reset' => 'Merkitse kaikki sivut nähdyiksi',
 'enotif_impersonal_salutation' => '{{GRAMMAR:genitive|{{SITENAME}}}} käyttäjä',
 'enotif_subject_deleted' => '{{GENDER:$2|$2}} poisti {{GRAMMAR:elative|{{SITENAME}}}} sivun $1',
 'enotif_subject_created' => '{{GENDER:$2|$2}} loi {{GRAMMAR:illative|{{SITENAME}}}} sivun $1',
@@ -2401,6 +2405,8 @@ Viimeisimmän muokkauksen on tehnyt käyttäjä [[User:$3|$3]] ([[User talk:$3|k
 'prot_1movedto2' => 'siirsi sivun [[$1]] uudelle nimelle [[$2]]',
 'protect-badnamespace-title' => 'Nimiavaruus ei suojattavissa',
 'protect-badnamespace-text' => 'Tämän nimiavaruuden sivuja ei voi suojata.',
+'protect-norestrictiontypes-text' => 'Tätä sivua ei voi suojata, koska mitään rajoitusvaihtoehtoja ei ole käytettävissä.',
+'protect-norestrictiontypes-title' => 'Ei suojattavissa oleva sivu',
 'protect-legend' => 'Suojaukset',
 'protectcomment' => 'Syy',
 'protectexpiry' => 'Vanhentuu',
@@ -2413,9 +2419,9 @@ Viimeisimmän muokkauksen on tehnyt käyttäjä [[User:$3|$3]] ([[User talk:$3|k
 'protect-locked-access' => "Sinulla ei ole tarvittavia oikeuksia sivujen suojauksen muuttamiseen. Alla on sivun ”'''$1'''” nykyiset suojaukset:",
 'protect-cascadeon' => 'Tämä sivu on suojauksen kohteena, koska se on sisällytetty alla {{PLURAL:$1|olevaan laajennetusti suojattuun sivuun|oleviin laajennetusti suojattuihin sivuihin}}. Voit muuttaa tämän sivun suojaustasoa, mutta se ei vaikuta laajennettuun suojaukseen.',
 'protect-default' => 'Salli kaikki käyttäjät',
-'protect-fallback' => 'Vaadi $1-oikeus',
-'protect-level-autoconfirmed' => 'Estä uudet ja kirjautumattomat käyttäjät',
-'protect-level-sysop' => 'Vain ylläpitäjät',
+'protect-fallback' => 'Salli vain käyttäjät, joilla on oikeus $1',
+'protect-level-autoconfirmed' => 'Vain hyväksytyt käyttäjät',
+'protect-level-sysop' => 'Salli vain ylläpitäjät',
 'protect-summary-cascade' => 'laajennettu',
 'protect-expiring' => 'vanhentuu $1 (UTC)',
 'protect-expiring-local' => 'vanhentuu $1',
@@ -2705,7 +2711,7 @@ Voit päivittää sivuun viittaavat ohjaukset automaattisesti ohjaamaan uudelle
 Jos et halua tätä tehtävän automaattisesti, muista tehdä tarkistukset [[Special:DoubleRedirects|kaksinkertaisten]] tai [[Special:BrokenRedirects|rikkinäisten]] ohjausten varalta.
 Olet vastuussa siitä, että linkit osoittavat sinne, mihin niiden on tarkoituskin osoittaa.
 
-Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi milloin kyseessä on tyhjä sivu tai ohjaus, jolla ei ole muokkaushistoriaa.
+Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi jos jälkimmäinen on ohjaus, jolla ei ole muokkaushistoriaa.
 Tämä tarkoittaa sitä, että voit siirtää sivun takaisin vanhalle nimelleen mikäli teit virheen, mutta et voi kirjoittaa olemassa olevan sivun päälle.
 
 Tämä saattaa olla suuri ja odottamaton muutos suositulle sivulle. Varmista, että tiedät seuraukset ennen kuin siirrät sivun.",
@@ -2713,7 +2719,8 @@ Tämä saattaa olla suuri ja odottamaton muutos suositulle sivulle. Varmista, et
 
 Tarkasta sivuun viittaavat ohjaukset [[Special:DoubleRedirects|kaksinkertaisten]] tai [[Special:BrokenRedirects|rikkinäisten]] ohjausten varalta. Olet vastuussa siitä, että linkit osoittavat sinne, mihin niiden on tarkoituskin osoittaa.
 
-Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi milloin kyseessä on tyhjä sivu tai ohjaus, jolla ei ole muokkaushistoriaa. Tämä tarkoittaa sitä, että voit siirtää sivun takaisin vanhalle nimelleen mikäli teit virheen, mutta et voi kirjoittaa olemassa olevan sivun päälle.
+Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi jos jälkimmäinen on ohjaus, jolla ei ole muokkaushistoriaa.
+Tämä tarkoittaa sitä, että voit siirtää sivun takaisin vanhalle nimelleen mikäli teit virheen, mutta et voi kirjoittaa olemassa olevan sivun päälle.
 
 Tämä saattaa olla suuri ja odottamaton muutos suositulle sivulle. Varmista, että tiedät seuraukset ennen kuin siirrät sivun.",
 'movepagetalktext' => "Sivuun mahdollisesti kytketty keskustelusivu siirretään automaattisesti, '''paitsi jos''':
@@ -3058,12 +3065,17 @@ Tallenna tiedot koneellesi ja tuo ne tällä sivulla.',
 'pageinfo-magic-words' => '{{PLURAL:$1|Taikasana|Taikasanat}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Piilotettu luokka|Piilotetut luokat}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Sisällytetty malline|Sisällytetyt mallineet}} ($1)',
+'pageinfo-transclusions' => 'Sisällytetty {{PLURAL:$1|sivulle|sivuille}} ($1)',
 'pageinfo-toolboxlink' => 'Sivun tiedot',
 'pageinfo-redirectsto' => 'Ohjaus sivulle',
 'pageinfo-redirectsto-info' => 'tiedot',
 'pageinfo-contentpage' => 'Lasketaan sisältösivuksi',
 'pageinfo-contentpage-yes' => 'Kyllä',
 'pageinfo-protect-cascading-yes' => 'Kyllä',
+'pageinfo-category-info' => 'Luokkatiedot',
+'pageinfo-category-pages' => 'Sivujen määrä',
+'pageinfo-category-subcats' => 'Alaluokkien määrä',
+'pageinfo-category-files' => 'Tiedostojen määrä',
 
 # Skin names
 'skinname-standard' => 'Perus',
@@ -3150,6 +3162,8 @@ Suorittamalla sen järjestelmäsi voi muuttua epäluotettavaksi.",
 'minutes' => '{{PLURAL:$1|$1 minuutti|$1 minuuttia}}',
 'hours' => '{{PLURAL:$1|$1 tunti|$1 tuntia}}',
 'days' => '{{PLURAL:$1|$1 päivä|$1 päivää}}',
+'months' => '{{PLURAL:$1|$1 kuukausi|$1 kuukautta}}',
+'years' => '{{PLURAL:$1|$1 vuosi|$1 vuotta}}',
 'ago' => '$1 sitten',
 'just-now' => 'juuri nyt',
 
@@ -3802,7 +3816,7 @@ Kuvat näytetään täysikokoisina. Muut tiedostot avataan niille määritetyss
 'specialpages-group-highuse' => 'Sivujen käyttöaste',
 'specialpages-group-pages' => 'Sivulistaukset',
 'specialpages-group-pagetools' => 'Sivutyökalut',
-'specialpages-group-wiki' => 'Wikitiedot ja työkalut',
+'specialpages-group-wiki' => 'Tiedot ja työkalut',
 'specialpages-group-redirects' => 'Ohjaavat toimintosivut',
 'specialpages-group-spam' => 'Mainostenpoistotyökalut',
 
@@ -3899,9 +3913,10 @@ Kuvat näytetään täysikokoisina. Muut tiedostot avataan niille määritetyss
 'logentry-newusers-newusers' => 'Käyttäjätunnus $1 luotiin',
 'logentry-newusers-create' => 'Käyttäjätunnus $1 luotiin',
 'logentry-newusers-create2' => '$1 loi käyttäjätunnuksen $3',
+'logentry-newusers-byemail' => '$1 loi käyttäjätunnuksen $3 ja salasana lähetettiin sähköpostitse',
 'logentry-newusers-autocreate' => 'Käyttäjätunnus $1 luotiin automaattisesti',
-'newuserlog-byemail' => 'salasana lähetetty sähköpostitse',
 'logentry-rights-rights' => '$1 muutti käyttäjän $3 oikeudet ryhmistä $4 ryhmiin $5',
+'logentry-rights-rights-legacy' => '$1 muutti käyttäjän $3 jäsenyyttä ryhmässä',
 'logentry-rights-autopromote' => '$1 ylennettiin automaattisesti ryhmistä $4 ryhmiin $5',
 'rightsnone' => '(ei oikeuksia)',
 
@@ -3956,7 +3971,8 @@ Muussa tapauksessa voit käyttää alla olevaa helpompaa lomaketta. Kommenttisi
 'api-error-nomodule' => 'Sisäinen virhe: tallennusmoduulia ei ole asetettu.',
 'api-error-ok-but-empty' => 'Sisäinen virhe: palvelimelta ei saatu vastausta.',
 'api-error-overwrite' => 'Olemassa olevan tiedoston korvaaminen ei ole sallittua.',
-'api-error-stashfailed' => 'Sisäinen virhe: välikaikaisen tiedoston tallentaminen epäonnistui.',
+'api-error-stashfailed' => 'Sisäinen virhe: Väliaikaisen tiedoston tallentaminen epäonnistui.',
+'api-error-publishfailed' => 'Sisäinen virhe: Väliaikaisen tiedoston julkaiseminen epäonnistui.',
 'api-error-timeout' => 'Palvelin ei vastannut odotetun ajan kuluessa.',
 'api-error-unclassified' => 'Tapahtui tuntematon virhe.',
 'api-error-unknown-code' => 'Tuntematon virhe: $1',
index b6eeb76..f2dd97f 100644 (file)
@@ -133,6 +133,7 @@ $specialPageAliases = array(
        'Booksources'               => array( 'Ouvrages_de_référence', 'Ouvrages_de_reference', 'Ouvragesderéférence', 'Ouvragesdereference', 'Recherche_ISBN', 'Recherche_isbn', 'RechercheISBN', 'Rechercheisbn' ),
        'BrokenRedirects'           => array( 'Redirections_cassées', 'RedirectionCassées', 'Redirections_cassees', 'RedirectionsCassees' ),
        'Categories'                => array( 'Catégories' ),
+       'ChangeEmail'               => array( 'ChangerCouriel', 'Changer_courrielw' ),
        'ChangePassword'            => array( 'Changement_du_mot_de_passe', 'ChangementDuMotDePasse' ),
        'Confirmemail'              => array( 'Confirmer_l\'adresse_de_contact', 'Confirmer_le_courriel', 'ConfirmerLeCourriel' ),
        'CreateAccount'             => array( 'Créer_un_compte', 'CréerUnCompte', 'CréerCompte' ),
@@ -140,6 +141,7 @@ $specialPageAliases = array(
        'DeletedContributions'      => array( 'Contributions_supprimées', 'ContributionsSupprimées', 'ContributionSupprimees' ),
        'Disambiguations'           => array( 'Homonymies', 'Homonymie', 'Pages_d\'homonymie' ),
        'DoubleRedirects'           => array( 'Doubles_redirections', 'DoublesRedirections', 'Redirections_doubles', 'RedirectionsDoubles' ),
+       'EditWatchlist'             => array( 'Éditer_Liste_de_suivi', 'ÉditerListeDeSuivi' ),
        'Emailuser'                 => array( 'Envoyer_un_courriel', 'EnvoyerUnCourriel', 'Courriel', 'Envoyer_un_e-mail', 'EnvoyerUnEMail', 'E-mail', 'EMail' ),
        'Export'                    => array( 'Exporter', 'Exportation' ),
        'Fewestrevisions'           => array( 'Pages_les_moins_modifiées', 'PagesLesMoinsModifiées', 'Pages_les_moins_modifiees', 'PagesLesMoinsModifiees', 'Les_moins_modifiés', 'LesMoinsModifiés', 'Les_moins_modifies', 'LesMoinsModifies' ),
@@ -254,6 +256,7 @@ $magicWords = array(
        'pagenamee'                 => array( '1', 'NOMPAGEX', 'PAGENAMEE' ),
        'namespace'                 => array( '1', 'ESPACENOMMAGE', 'NAMESPACE' ),
        'namespacee'                => array( '1', 'ESPACENOMMAGEX', 'NAMESPACEE' ),
+       'namespacenumber'           => array( '1', 'NOMBREESPACENOMMAGE', 'NAMESPACENUMBER' ),
        'talkspace'                 => array( '1', 'ESPACEDISCUSSION', 'TALKSPACE' ),
        'talkspacee'                => array( '1', 'ESPACEDISCUSSIONX', 'TALKSPACEE' ),
        'subjectspace'              => array( '1', 'ESPACESUJET', 'ESPACEARTICLE', 'SUBJECTSPACE', 'ARTICLESPACE' ),
@@ -351,6 +354,8 @@ $magicWords = array(
        'protectionlevel'           => array( '1', 'NIVEAUDEPROTECTION', 'PROTECTIONLEVEL' ),
        'url_path'                  => array( '0', 'CHEMIN', 'PATH' ),
        'url_query'                 => array( '0', 'QUESTION', 'QUERY' ),
+       'pagesincategory_all'       => array( '0', 'tous', 'all' ),
+       'pagesincategory_files'     => array( '0', 'fichier', 'files' ),
 );
 
 $bookstoreList = array(
@@ -490,7 +495,7 @@ $messages = array(
 'dec' => 'déc',
 
 # Categories related messages
-'pagecategories' => 'Catégorie{{PLURAL:$1||s}}',
+'pagecategories' => '{{PLURAL:$1|Catégorie|Catégories}}',
 'category_header' => 'Pages dans la catégorie « $1 »',
 'subcategories' => 'Sous-catégories',
 'category-media-header' => 'Fichiers multimédias dans la catégorie « $1 »',
@@ -815,7 +820,7 @@ N'oubliez pas de modifier [[Special:Preferences|vos préférences pour {{SITENAM
 'gotaccount' => "Vous avez déjà un compte ? '''$1'''.",
 'gotaccountlink' => 'Connectez-vous',
 'userlogin-resetlink' => 'Vous avez oublié vos détails de connexion ?',
-'createaccountmail' => 'par courriel',
+'createaccountmail' => 'Utiliser un mot de passe aléatoire temporaire et l’envoyer à l’adresse de courriel spécifiée ci-dessous',
 'createaccountreason' => 'Motif :',
 'badretype' => 'Les mots de passe que vous avez saisis ne correspondent pas.',
 'userexists' => "Nom d'utilisateur entré déjà utilisé.
@@ -1106,9 +1111,9 @@ Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l'av
 'longpageerror' => "'''Erreur: Le texte que vous avez soumis fait {{PLURAL:$1|un Kio|$1 Kio}}, ce qui dépasse la limite fixée à {{PLURAL:$2|un Kio|$2 Kio}}.'''
 Il ne peut pas être sauvegardé.",
 'readonlywarning' => "'''AVERTISSEMENT : la base de données a été verrouillée pour des opérations de maintenance. Vous ne pouvez donc pas publier vos modifications pour l'instant.'''
-Vous pouvez copier le texte dans un fichier texte et le conserver pour plus tard.
+Vous pouvez copier et coller votre texte dans un fichier texte et l’enregistrer pour plus tard.
 
-L'administrateur ayant verrouillé la base de données a donné l'explication suivante : $1",
+L'administrateur ayant verrouillé la base de données a donné l'explication suivante: $1",
 'protectedpagewarning' => "'''AVERTISSEMENT : cette page est protégée. Seuls les utilisateurs ayant le statut d'administrateur peuvent la modifier.'''<br />
 La dernière entrée du journal est affichée ci-dessous pour référence :",
 'semiprotectedpagewarning' => "'''Note :''' Cette page a été protégée de telle façon que seuls les contributeurs enregistrés puissent la modifier. La dernière entrée du journal est affichée ci-dessous pour référence :",
@@ -1403,7 +1408,7 @@ Vous pouvez trouver des détails dans le [{{fullurl:{{#Special:Log}}/delete|page
 'search-interwiki-default' => 'Résultats sur $1 :',
 'search-interwiki-more' => '(plus)',
 'search-relatedarticle' => 'Relaté',
-'mwsuggest-disable' => 'Désactiver les suggestions AJAX',
+'mwsuggest-disable' => 'Désactiver les suggestions de recherche',
 'searcheverything-enable' => 'Rechercher dans tous les espaces de noms',
 'searchrelated' => 'relaté',
 'searchall' => 'tout',
@@ -2312,7 +2317,7 @@ Ils nécessitent au moins un domaine de niveau supérieur, par exemple « *.org
 # Special:ActiveUsers
 'activeusers' => 'Liste des utilisateurs actifs',
 '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|modification|modifications}} dans {{PLURAL:$3|le dernier jour|les $3 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',
@@ -2846,7 +2851,7 @@ Pour bloquer ou débloquer la base de données, il doit être accessible par le
 'move-page-legend' => 'Renommer une page',
 'movepagetext' => "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom. L'ancien titre deviendra une page de redirection vers le nouveau titre. Vous pouvez mettre à jour automatiquement les redirections actuelles qui pointent vers le titre original. Si vous choisissez de ne pas le faire, assurez-vous de vérifier toute [[Special:DoubleRedirects|double redirection]] ou [[Special:BrokenRedirects|redirection cassée]]. Vous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.
 
-Notez que la page ne sera '''pas''' renommée s'il existe déjà une page avec le nouveau titre, sauf si cette dernière a un historique de modifications vierge et est une simple redirection. Ceci permet de renommer une page vers sa position d'origine si le déplacement s'avère erroné.
+Notez que la page ne sera '''pas''' renommée s'il existe déjà une page avec le nouveau titre, sauf si cette dernière est une simple redirection avec un historique de modifications vierge. Ceci permet de renommer une page vers sa position d'origine si le déplacement s'avère erroné.
 
 '''Attention !'''
 Ceci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d'en avoir compris les conséquences avant de continuer.",
@@ -3197,6 +3202,7 @@ Permet de rétablir la version précédente et d'ajouter un motif dans la boîte
 'pageinfo-robot-noindex' => 'Non indexable',
 'pageinfo-views' => 'Nombre de vues',
 'pageinfo-watchers' => 'Nombre de contributeurs ayant la page dans leur liste de suivi',
+'pageinfo-few-watchers' => 'Moins de $1 {{PLURAL:$1|observateur|observateurs}}',
 'pageinfo-redirects-name' => 'Redirections vers cette page',
 'pageinfo-subpages-name' => 'Sous-pages de cette page',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirection|redirections}}; $3 {{PLURAL:$3|non-redirection|non-redirections}})',
@@ -4051,7 +4057,7 @@ Les images sont montrées dans leur pleine résolution, les autres fichiers sont
 'specialpages-group-highuse' => "Pages d'utilisation intensive",
 'specialpages-group-pages' => 'Listes de pages',
 'specialpages-group-pagetools' => 'Outils pour les pages',
-'specialpages-group-wiki' => 'Données du wiki et outils',
+'specialpages-group-wiki' => 'Données et outils',
 'specialpages-group-redirects' => 'Pages spéciales redirigées',
 'specialpages-group-spam' => 'Outils anti-pourriel',
 
@@ -4148,8 +4154,8 @@ Les images sont montrées dans leur pleine résolution, les autres fichiers sont
 'logentry-newusers-newusers' => 'Le compte utilisateur $1 a été créé',
 'logentry-newusers-create' => 'Le compte utilisateur $1 a été créé',
 'logentry-newusers-create2' => 'Le compte utilisateur $3 a été créé par $1',
+'logentry-newusers-byemail' => 'Le compte utilisateur $3 a été créé par $1 et le mot de passe a été envoyé par courriel',
 'logentry-newusers-autocreate' => 'Le compte $1 a été créé automatiquement',
-'newuserlog-byemail' => 'mot de passe envoyé par courriel',
 'logentry-rights-rights' => "$1 a modifié l'appartenance au groupe pour $3 de $4 à $5",
 'logentry-rights-rights-legacy' => "$1 a modifié l'appartenance au groupe pour $3",
 'logentry-rights-autopromote' => '$1 a été promu automatiquement de $4 à $5',
@@ -4207,6 +4213,7 @@ Sinon, vous pouvez utiliser le formulaire simplifié ci-dessous. Votre commentai
 'api-error-ok-but-empty' => "Erreur interne : Le serveur n'a pas répondu.",
 'api-error-overwrite' => "Écraser un fichier existant n'est pas autorisé.",
 'api-error-stashfailed' => "Erreur interne : le serveur n'a pas pu enregistrer le fichier temporaire.",
+'api-error-publishfailed' => 'Erreur interne: Le serveur n’a pas pu publier le fichier temporaire.',
 'api-error-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 »',
index 461b83e..0cfc7d4 100644 (file)
@@ -315,15 +315,15 @@ $messages = array(
 'tog-hidepatrolled' => 'Cachiér los changements gouardâs dedens los dèrriérs changements',
 'tog-newpageshidepatrolled' => 'Cachiér les pâges gouardâyes entre-mié la lista de les pâges novèles',
 'tog-extendwatchlist' => 'Ètendre la lista de siuvu por montrar tôs los changements et pas ren que los ples novéls',
-'tog-usenewrc' => 'Rassemblar los changements per pâge dedens los dèrriérs changements et la lista de siuvu (at fôta de JavaScript)',
+'tog-usenewrc' => 'Rassemblar los changements per pâge dedens los dèrriérs changements et la lista de siuvu (il at fôta de JavaScript)',
 'tog-numberheadings' => 'Numerotar ôtomaticament los titros de sèccion',
-'tog-showtoolbar' => 'Montrar la bârra d’outils de changement (at fôta de JavaScript)',
-'tog-editondblclick' => 'Changiér des pâges sur doblo-clic (at fôta de JavaScript)',
+'tog-showtoolbar' => 'Montrar la bârra d’outils de changement (il at fôta de JavaScript)',
+'tog-editondblclick' => 'Changiér des pâges sur doblo-clic (il at fôta de JavaScript)',
 'tog-editsection' => 'Activar lo changement de sèccions avouéc los lims « [changiér] »',
-'tog-editsectiononrightclick' => 'Activar lo changement de sèccions per clic drêt sur lors titros (at fôta de JavaScript)',
+'tog-editsectiononrightclick' => 'Activar lo changement de sèccions per clic drêt sur lors titros (il at fôta de JavaScript)',
 'tog-showtoc' => 'Montrar la trâbla de les matiéres (por les pâges qu’ont més de 3 sèccions)',
 'tog-rememberpassword' => 'Sè rapelar de mon contresegno sur ceti navigator (por lo més $1 jorn{{PLURAL:$1||s}})',
-'tog-watchcreations' => 'Apondre les pâges que fé et pués los fichiérs que tèlècharjo a ma lista de siuvu',
+'tog-watchcreations' => 'Apondre les pâges que fé et pués los fichiérs que tèlèchârjo a ma lista de siuvu',
 'tog-watchdefault' => 'Apondre les pâges et los fichiérs que chanjo a ma lista de siuvu',
 'tog-watchmoves' => 'Apondre les pâges et los fichiérs que dèplaço a ma lista de siuvu',
 'tog-watchdeletion' => 'Apondre les pâges et los fichiérs que suprimo a ma lista de siuvu',
@@ -331,18 +331,18 @@ $messages = array(
 'tog-previewontop' => 'Montrar l’apèrçu d’amont la zona de changement',
 'tog-previewonfirst' => 'Montrar l’apèrçu pendent lo premiér changement',
 'tog-nocache' => 'Dèsactivar lo cacho de les pâges per lo navigator',
-'tog-enotifwatchlistpages' => 'Mè mandar un mèssâjo quand na pâge ou ben un fichiér de ma lista de siuvu est changiê(e)',
+'tog-enotifwatchlistpages' => 'Mè mandar un mèssâjo quand na pâge un fichiér de ma lista de siuvu est changiê(e)',
 'tog-enotifusertalkpages' => 'Mè mandar un mèssâjo quand ma pâge de discussion est changiêe',
 'tog-enotifminoredits' => 'Mè mandar un mèssâjo mémo en câs de petiôts changements de les pâges et des fichiérs',
 'tog-enotifrevealaddr' => 'Rèvèlar mon adrèce èlèctronica dedens los mèssâjos de notificacion',
 'tog-shownumberswatching' => 'Montrar lo nombro d’utilisators que siuvont na pâge',
 'tog-oldsig' => 'Signatura ègzistenta :',
 'tog-fancysig' => 'Trètar la signatura coment de vouiquitèxto (sen lim ôtomatico)',
-'tog-externaleditor' => 'Empleyér per dèfôt un changior de tèxto de defôr (solament por los utilisators avanciês, at fôta d’una configuracion spèciâla sur voutron ordenator. [//www.mediawiki.org/wiki/Manual:External_editors Més d’enformacions.])',
-'tog-externaldiff' => 'Empleyér per dèfôt un comparator de defôr (solament por los utilisators avanciês, at fôta d’una configuracion spèciâla sur voutron ordenator. [//www.mediawiki.org/wiki/Manual:External_editors Més d’enformacions.])',
+'tog-externaleditor' => 'Empleyér per dèfôt un changior de tèxto de defôr (solament por los utilisators avanciês, il at fôta d’una configuracion spèciâla sur voutron ordenator. [//www.mediawiki.org/wiki/Manual:External_editors Més d’enformacions.])',
+'tog-externaldiff' => 'Empleyér per dèfôt un comparator de defôr (solament por los utilisators avanciês, il at fôta d’una configuracion spèciâla sur voutron ordenator. [//www.mediawiki.org/wiki/Manual:External_editors Més d’enformacions.])',
 'tog-showjumplinks' => 'Activar los lims d’accèssibilitât « {{int:jumpto}} »',
-'tog-uselivepreview' => 'Empleyér l’apèrçu rapido (at fôta de JavaScript) (èxpèrimentâl)',
-'tog-forceeditsummary' => 'M’avèrtir quand j’é pas buchiê de rèsumâ de changement',
+'tog-uselivepreview' => 'Empleyér l’apèrçu rapido (il at fôta de JavaScript) (èxpèrimentâl)',
+'tog-forceeditsummary' => 'Mè balyér na semonce quand j’é pas buchiê de rèsumâ de changement',
 'tog-watchlisthideown' => 'Cachiér los mins changements dedens la lista de siuvu',
 'tog-watchlisthidebots' => 'Cachiér los changements fêts per des robots dedens la lista de siuvu',
 'tog-watchlisthideminor' => 'Cachiér los petiôts changements dedens la lista de siuvu',
@@ -357,7 +357,7 @@ $messages = array(
 
 'underline-always' => 'Tojorn',
 'underline-never' => 'Jamés',
-'underline-default' => 'Valor de l’habelyâjo ou ben du navigator per dèfôt',
+'underline-default' => 'Valor de l’habelyâjo du navigator per dèfôt',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Stilo de police de la zona de changement :',
@@ -423,7 +423,7 @@ $messages = array(
 'category_header' => 'Pâges dedens la catègorie « $1 »',
 'subcategories' => 'Sot-catègories',
 'category-media-header' => 'Fichiérs mèdia dedens la catègorie « $1 »',
-'category-empty' => "''Ora ceta catègorie contint gins de pâge ou ben de fichiér mèdia.''",
+'category-empty' => "''Ora ceta catègorie contint gins de pâge de fichiér mèdia.''",
 'hidden-categories' => '{{PLURAL:$1|Catègorie cachiêe|Catègories cachiêes}}',
 'hidden-category-category' => 'Catègories cachiêes',
 'category-subcat-count' => 'Cela catègorie-que at {{PLURAL:$2|ren que ceta sot-catègorie.|{{PLURAL:$1|ceta sot-catègorie|cetes $1 sot-catègories}}, sur na soma de $2.}}',
@@ -498,8 +498,8 @@ $messages = array(
 'create-this-page' => 'Fâre cela pâge',
 'delete' => 'Suprimar',
 'deletethispage' => 'Suprimar ceta pâge',
-'undelete_short' => 'Refâre {{PLURAL:$1|yon changement|$1 changements}}',
-'viewdeleted_short' => 'Vêre {{PLURAL:$1|yon changement suprimâ|$1 changements suprimâs}}',
+'undelete_short' => 'Refâre {{PLURAL:$1|un changement|$1 changements}}',
+'viewdeleted_short' => 'Vêre {{PLURAL:$1|un changement suprimâ|$1 changements suprimâs}}',
 'protect' => 'Protègiér',
 'protect_change' => 'changiér',
 'protectthispage' => 'Protègiér ceta pâge',
@@ -527,14 +527,14 @@ $messages = array(
 'redirectedfrom' => '(Redirigiêe dês $1)',
 'redirectpagesub' => 'Pâge de redirèccion',
 'lastmodifiedat' => 'Dèrriér changement de ceta pâge lo $1 a $2.',
-'viewcount' => 'Ceta pâge est étâye vua {{PLURAL:$1|yon côp|$1 côps}}.',
+'viewcount' => 'Ceta pâge est étâye vua {{PLURAL:$1|un côp|$1 côps}}.',
 'protectedpage' => 'Pâge protègiêe',
-'jumpto' => 'Alar a :',
+'jumpto' => 'Alar vers :',
 'jumptonavigation' => 'navigacion',
 'jumptosearch' => 'rechèrche',
 'view-pool-error' => 'Dèconsolâ, los sèrviors sont lapidâs d’ôvra cetos temps.
-Trop d’utilisators tâchont de vêre ceta pâge.
-Volyéd atendre un moment devant que tornar tâchiér d’arrevar a ceta pâge.
+Trop d’utilisators èprôvont de vêre ceta pâge.
+Se vos plét, atende un moment devant que tornar èprovar d’arrevar a ceta pâge.
 
 $1',
 'pool-timeout' => 'Dèlê dèpassâ pendent l’atenta du vèrroly',
@@ -548,8 +548,8 @@ $1',
 'copyrightpage' => '{{ns:project}}:Drêts d’ôtor',
 'currentevents' => 'Novèles',
 'currentevents-url' => 'Project:Novèles',
-'disclaimers' => 'Avèrtissements',
-'disclaimerpage' => 'Project:Avèrtissements g·ènèrals',
+'disclaimers' => 'Semonces',
+'disclaimerpage' => 'Project:Semonces g·ènèrales',
 'edithelp' => 'Éde',
 'edithelppage' => 'Help:Coment changiér na pâge',
 'helppage' => 'Help:Somèro',
@@ -571,14 +571,14 @@ Vêde la [[Special:Version|pâge de les vèrsions]].',
 
 'ok' => 'D’acôrd',
 'retrievedfrom' => 'Rècupèrâye de « $1 »',
-'youhavenewmessages' => 'Vos avéd de $1 ($2).',
+'youhavenewmessages' => 'Vos éd de $1 ($2).',
 'newmessageslink' => 'mèssâjos novéls',
 'newmessagesdifflink' => 'dèrriér changement',
-'youhavenewmessagesfromusers' => 'Vos avéd $1 {{PLURAL:$3|d’un ôtr’utilisator|de $3 ôtros utilisators}} ($2).',
-'youhavenewmessagesmanyusers' => 'Vos avéd $1 d’un mouél d’utilisators ($2).',
+'youhavenewmessagesfromusers' => 'Vos éd $1 {{PLURAL:$3|d’un ôtr’utilisator|de $3 ôtros utilisators}} ($2).',
+'youhavenewmessagesmanyusers' => 'Vos éd $1 d’un mouél d’utilisators ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|un mèssâjo novél|de mèssâjos novéls}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|dèrriér changement|dèrriérs changements}}',
-'youhavenewmessagesmulti' => 'Vos avéd de mèssâjos novéls sur $1',
+'youhavenewmessagesmulti' => 'Vos éd de mèssâjos novéls sur $1',
 'editsection' => 'changiér',
 'editold' => 'changiér',
 'viewsourceold' => 'vêre lo tèxto sôrsa',
@@ -590,9 +590,9 @@ Vêde la [[Special:Version|pâge de les vèrsions]].',
 'hidetoc' => 'cachiér',
 'collapsible-collapse' => 'repleyér',
 'collapsible-expand' => 'dèpleyér',
-'thisisdeleted' => 'Voléd-vos vêre ou ben refâre $1 ?',
-'viewdeleted' => 'Vêre $1 ?',
-'restorelink' => '{{PLURAL:$1|yon changement suprimâ|$1 changements suprimâs}}',
+'thisisdeleted' => 'Est-o que vos voléd vêre ou ben refâre $1 ?',
+'viewdeleted' => 'Est-o que vos voléd vêre $1 ?',
+'restorelink' => '{{PLURAL:$1|un changement suprimâ|$1 changements suprimâs}}',
 'feedlinks' => 'Flux :',
 'feed-invalid' => 'Tipo d’abonement du flux pas justo.',
 'feed-unavailable' => 'Los flux de sindicacion sont pas disponiblos',
@@ -620,7 +620,7 @@ Vêde la [[Special:Version|pâge de les vèrsions]].',
 'nosuchaction' => 'Accion encognua',
 'nosuchactiontext' => 'L’accion spècifiâye dens l’URL est pas justa.
 Pôt-étre vos éd mâl-buchiê l’URL ou ben siuvu un lim fôx.
-Pôt asse-ben étre quèstion d’una cofierie dedens la programeria empleyêe per {{SITENAME}}.',
+Pôt asse-ben étre na cofierie dedens la programeria empleyêe per {{SITENAME}}.',
 'nosuchspecialpage' => 'Pâge spèciâla pas ègzistenta',
 'nospecialpagetext' => '<strong>Vos éd demandâ na pâge spèciâla qu’ègziste pas.</strong>
 
@@ -648,36 +648,36 @@ La bâsa de donâs at retornâ la fôta « $3 : $4 ».',
 L’administrator que l’at vèrrolyê at balyê cet’èxplicacion : $1',
 'missing-article' => 'La bâsa de donâs at pas trovâ lo tèxto d’una pâge qu’el arêt diu trovar, apelâye « $1 » $2.
 
-En g·ènèral cen arreve en siuvent un lim d’una dif ou ben d’un historico dèpassâ(ye) de vers na pâge qu’est étâye suprimâye.
+En g·ènèral cen arreve en siuvent un lim d’una dif d’un historico dèpassâ(ye) de vers na pâge qu’est étâye suprimâye.
 
-S’o est pas lo câs, pôt étre quèstion d’una cofierie dedens la programeria.
-La volyéd signalar a un [[Special:ListUsers/sysop|administrator]] sen oubliar de lui endicar l’URL du lim.',
+S’o est pas lo câs, pôt étre na cofierie dedens la programeria.
+Se vos plét, signalâd-la a un [[Special:ListUsers/sysop|administrator]] sen oubliar de lui endicar l’URL du lim.',
 'missingarticle-rev' => '(numerô de vèrsion : $1)',
 'missingarticle-diff' => '(dif : $1, $2)',
 'readonly_lag' => 'La bâsa de donâs est étâye vèrrolyêe ôtomaticament pendent que los sèrviors secondèros ratrapont lor retârd sur lo sèrvior principâl.',
 'internalerror' => 'Fôta de dedens',
 'internalerror_info' => 'Fôta de dedens : $1',
-'fileappenderrorread' => 'Empossiblo de liére « $1 » pendent l’aponsa.',
-'fileappenderror' => 'Empossiblo d’apondre « $1 » a « $2 ».',
-'filecopyerror' => 'Empossiblo de copiyér lo fichiér « $1 » vers « $2 ».',
-'filerenameerror' => 'Empossiblo de renomar lo fichiér « $1 » en « $2 ».',
-'filedeleteerror' => 'Empossiblo de suprimar lo fichiér « $1 ».',
-'directorycreateerror' => 'Empossiblo de fâre lo dossiér « $1 ».',
-'filenotfound' => 'Empossiblo de trovar lo fichiér « $1 ».',
-'fileexistserror' => 'Empossiblo d’ècrire lo fichiér « $1 » : lo fichiér ègziste.',
+'fileappenderrorread' => 'Y at pas moyen de liére « $1 » pendent l’aponsa.',
+'fileappenderror' => 'Y at pas moyen d’apondre « $1 » a « $2 ».',
+'filecopyerror' => 'Y at pas moyen de copiyér lo fichiér « $1 » vers « $2 ».',
+'filerenameerror' => 'Y at pas moyen de renomar lo fichiér « $1 » en « $2 ».',
+'filedeleteerror' => 'Y at pas moyen de suprimar lo fichiér « $1 ».',
+'directorycreateerror' => 'Y at pas moyen de fâre lo rèpèrtouèro « $1 ».',
+'filenotfound' => 'Y at pas moyen de trovar lo fichiér « $1 ».',
+'fileexistserror' => 'Y at pas moyen d’ècrire lo fichiér « $1 » : lo fichiér ègziste.',
 'unexpected' => 'Valor emprèvua : « $1 » = « $2 ».',
-'formerror' => 'Fôta : empossiblo de sometre lo formulèro.',
+'formerror' => 'Fôta : y at pas moyen de mandar lo formulèro.',
 'badarticleerror' => 'Cel’accion pôt pas étre fêta sur ceta pâge.',
-'cannotdelete' => 'Empossiblo de suprimar la pâge ou ben lo fichiér « $1 ».
-Pôt-étre la suprèssion est ja étâye fêta per quârqu’un d’ôtro.',
-'cannotdelete-title' => 'Empossiblo de suprimar la pâge « $1 »',
+'cannotdelete' => 'Y at pas moyen de suprimar la pâge lo fichiér « $1 ».
+Pôt-étre la suprèssion est ja étâye fêta per un ôtro.',
+'cannotdelete-title' => 'Y at pas moyen de suprimar la pâge « $1 »',
 'delete-hook-aborted' => 'Suprèssion anulâye per un grèfon.
 Nion’èxplicacion est étâye balyêe.',
 'badtitle' => 'Crouyo titro',
 'badtitletext' => 'Lo titro de la pâge demandâye est pas justo, vouedo ou ben o est un titro entèrlengoua ou entèrvouiqui mâl-liyê.
-Contint sûrament yon ou ben un mouél de caractèros que pôvont pas étre empleyês dedens los titros.',
-'perfcached' => 'Cetes donâs sont en cacho et pôvont pas étre a jorn. Por lo més {{PLURAL:$1|yon rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.',
-'perfcachedts' => 'Cetes donâs sont en cacho et sont étâyes betâyes a jorn por lo dèrriér côp a $1. Por lo més {{PLURAL:$1|yon rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.',
+Contint de sûr yon ou ben un mouél de caractèros que pôvont pas étre empleyês dedens los titros.',
+'perfcached' => 'Cetes donâs sont en cacho et pôvont pas étre a jorn. Por lo més {{PLURAL:$1|un rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.',
+'perfcachedts' => 'Cetes donâs sont en cacho et sont étâyes betâyes a jorn por lo dèrriér côp a $1. Por lo més {{PLURAL:$1|un rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.',
 'querypage-no-updates' => 'Ora les mises a jorn por ceta pâge sont dèsactivâyes.
 Les donâs ique seront pas betâyes a jorn.',
 'wrong_wfQuery_params' => 'Paramètros fôx dessus wfQuery()<br />
@@ -687,31 +687,31 @@ Demanda : $2',
 'viewsource-title' => 'Vêre lo tèxto sôrsa de $1',
 'actionthrottled' => 'Accion limitâye',
 'actionthrottledtext' => 'Por combatre lo spame, l’usâjo de cel’accion est limitâ a doux-três côps dens un moment prod côrt. S’acomplét que vos éd dèpassâ ceta limita.
-Volyéd tornar èprovar dens un tôrn.',
+Se vos plét, tornâd èprovar dens un tôrn.',
 'protectedpagetext' => 'Ceta pâge est étâye protègiêe por empachiér son changement ou ben d’ôtres accions.',
-'viewsourcetext' => 'Vos pouede vêre et pués copiyér lo tèxto sôrsa de ceta pâge :',
-'viewyourtext' => "Vos pouede vêre et pués copiyér lo tèxto sôrsa de '''voutros changements''' a ceta pâge :",
-'protectedinterface' => 'Cela pâge-que balye de tèxto d’entèrface por la programeria sur ceti vouiqui, et est vêr protègiêe por èvitar los abus.
-Por apondre ou ben changiér des traduccions sur tôs los vouiquis, volyéd empleyér [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.',
+'viewsourcetext' => 'Vos pouede vêre et copiyér lo tèxto sôrsa de ceta pâge :',
+'viewyourtext' => "Vos pouede vêre et copiyér lo tèxto sôrsa de '''voutros changements''' a ceta pâge :",
+'protectedinterface' => 'Cela pâge-que balye de tèxto d’entèrface por la programeria sur ceti vouiqui, et el est vêr protègiêe por èvitar los abus.
+Por apondre ou ben changiér des traduccions sur tôs los vouiquis, se vos plét empleyéd [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.',
 'editinginterface' => "'''Atencion :''' vos éte aprés changiér na pâge empleyêe por fâre lo tèxto d’entèrface de la programeria.
 Los changements sè cognetront sur l’aparence de l’entèrface utilisator por los ôtros utilisators de ceti vouiqui.
-Por apondre ou ben changiér des traduccions sur tôs los vouiquis, volyéd empleyér [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.",
+Por apondre ou ben changiér des traduccions sur tôs los vouiquis, se vos plét empleyéd [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.",
 'sqlhidden' => '(Demanda SQL cachiêe)',
-'cascadeprotected' => 'Cela pâge-que est protègiêe perce qu’el est entrebetâye dedens {{PLURAL:$1|ceta pâge, qu’est étâye protègiêe|cetes pâges, que sont étâyes protègiêes}} avouéc lo chouèx « protèccion en cascâda » activâ :
+'cascadeprotected' => 'Cela pâge-que est protègiêe, el est entrebetâye dedens {{PLURAL:$1|ceta pâge qu’est étâye protègiêe|cetes pâges que sont étâyes protègiêes}} avouéc lo chouèx « protèccion en cascâda » activâ :
 $2',
-'namespaceprotected' => "Vos avéd pas la pèrmission de changiér les pâges de l’èspâço de noms « '''$1''' ».",
-'customcssprotected' => 'Vos avéd pas la pèrmission de changiér cela pâge CSS perce que contint la configuracion a sè d’un ôtr’utilisator.',
-'customjsprotected' => 'Vos avéd pas la pèrmission de changiér cela pâge JavaScript perce que contint la configuracion a sè d’un ôtr’utilisator.',
+'namespaceprotected' => "Vos éd pas la pèrmission de changiér les pâges de l’èspâço de noms « '''$1''' ».",
+'customcssprotected' => 'Vos éd pas la pèrmission de changiér cela pâge CSS, contint la configuracion a sè d’un ôtr’utilisator.',
+'customjsprotected' => 'Vos éd pas la pèrmission de changiér cela pâge JavaScript, contint la configuracion a sè d’un ôtr’utilisator.',
 'ns-specialprotected' => 'Les pâges spèciâles pôvont pas étre changiêes.',
 'titleprotected' => "Cél titro est étâ protègiê a la crèacion per [[User:$1|$1]].
 La rêson balyêe est « ''$2'' ».",
-'filereadonlyerror' => 'Empossiblo de changiér lo fichiér « $1 » perce que lo dèpôt de fichiérs « $2 » est en lèctura solèta.
+'filereadonlyerror' => 'Y at pas moyen de changiér lo fichiér « $1 » perce que lo dèpôt de fichiérs « $2 » est justo en lèctura.
 
 L’administrator que l’at vèrrolyê at balyê cet’èxplicacion : « $3 ».',
 'invalidtitle-knownnamespace' => 'Titro pas justo avouéc l’èspâço de noms « $2 » et lo tèxto « $3 »',
 'invalidtitle-unknownnamespace' => 'Titro pas justo avouéc lo numerô d’èspâço de noms encognu $1 et lo tèxto « $2 »',
 'exception-nologin' => 'Pas branchiê',
-'exception-nologin-text' => 'Cela pâge ou ben cel’accion at fôta d’étre branchiê sur ceti vouiqui.',
+'exception-nologin-text' => 'Cela pâge cel’accion at fôta d’étre branchiê sur ceti vouiqui.',
 
 # Virus scanner
 'virus-badscanner' => "Crouye configuracion : scanor de virus encognu : ''$1''",
@@ -742,25 +742,25 @@ Oubliâd pas de changiér voutres [[Special:Preferences|prèferences dessus {{SI
 'logout' => 'Sè dèbranchiér',
 'userlogout' => 'Dèbranchement',
 'notloggedin' => 'Pas branchiê',
-'nologin' => "Vos avéd p’oncor un compto ? '''$1.'''",
+'nologin' => "Vos éd p’oncor un compto ? '''$1.'''",
 'nologinlink' => 'Féte un compto',
 'createaccount' => 'Fâre un compto',
-'gotaccount' => "Vos avéd ja un compto ? '''$1.'''",
+'gotaccount' => "Vos éd ja un compto ? '''$1.'''",
 'gotaccountlink' => 'Branchiéd-vos',
 'userlogin-resetlink' => 'Vos éd oubliâ voutros dètalys de branchement ?',
-'createaccountmail' => 'per mèssageria èlèctronica',
+'createaccountmail' => 'Empleyér un contresegno temporèro fêt per hasârd et lo mandar a l’adrèce èlèctronica spècifiâye ce-desot',
 'createaccountreason' => 'Rêson :',
 'badretype' => 'Los contresegnos que vos éd buchiês sont pas pariérs.',
 'userexists' => 'Lo nom d’utilisator buchiê est ja empleyê.
-Nen volyéd chouèsir un ôtro.',
+Se vos plét, chouèsésséd-nen un ôtro.',
 'loginerror' => 'Fôta de branchement',
-'createaccounterror' => 'Empossiblo de fâre lo compto : $1',
+'createaccounterror' => 'Y at pas moyen de fâre lo compto : $1',
 'nocookiesnew' => "Lo compto utilisator est étâ fêt, mas vos éte pas branchiê{{GENDER:||e|(e)}}.
 {{SITENAME}} emplèye des tèmouens (''cookies'') por lo branchement mas vos los éd dèsactivâs.
-Los volyéd activar et pués vos tornar branchiér avouéc lo mémo nom et lo mémo contresegno.",
+Se vos plét, activâd-los et pués tornâd-vos branchiér avouéc voutron novél nom d’utilisator et voutron contresegno.",
 'nocookieslogin' => "{{SITENAME}} emplèye des tèmouens (''cookies'') por lo branchement mas vos los éd dèsactivâs.
-Los volyéd activar et pués tornar èprovar.",
-'nocookiesfornew' => "Lo compto utilisator est pas étâ fêt, perce que nos ens pas possu confirmar la sina sôrsa.
+Se vos plét, activâd-los et pués tornâd èprovar.",
+'nocookiesfornew' => "Lo compto utilisator est pas étâ fêt, nos ens pas possu confirmar la sina sôrsa.
 Controlâd que vos éd activâ los tèmouens (''cookies''), rechargiéd la pâge et pués tornâd èprovar.",
 'noname' => 'Vos éd pas spècifiâ un nom d’utilisator justo.',
 'loginsuccesstitle' => 'Branchement reussi',
@@ -768,24 +768,24 @@ Controlâd que vos éd activâ los tèmouens (''cookies''), rechargiéd la pâge
 'nosuchuser' => 'L’utilisator « $1 » ègziste pas.
 Los noms d’utilisator sont sensiblos a la câssa.
 Controlâd l’ortografia ou ben [[Special:UserLogin/signup|féte un compto novél]].',
-'nosuchusershort' => 'Y at gins d’utilisator avouéc lo nom « $1 ».
-Volyéd controlar l’ortografia.',
+'nosuchusershort' => 'Y at pas un utilisator avouéc lo nom « $1 ».
+Se vos plét, controlâd l’ortografia.',
 'nouserspecified' => 'Vos dête spècifiar un nom d’utilisator.',
 'login-userblocked' => 'Cet’utilisator est blocâ. Branchement pas ôtorisâ.',
 'wrongpassword' => 'Lo contresegno buchiê est fôx.
-Volyéd tornar èprovar.',
+Se vos plét, tornâd èprovar.',
 'wrongpasswordempty' => 'Vos éd pas buchiê de contresegno.
-Volyéd tornar èprovar.',
-'passwordtooshort' => 'Voutron contresegno dêt contegnir u muens $1 caractèro{{PLURAL:$1||s}}.',
+Se vos plét, tornâd èprovar.',
+'passwordtooshort' => 'Voutron contresegno dêt contegnir por lo muens $1 caractèro{{PLURAL:$1||s}}.',
 'password-name-match' => 'Voutron contresegno dêt étre difèrent de voutron nom d’utilisator.',
 'password-login-forbidden' => 'L’usâjo de cél nom d’utilisator et de cél contresegno est étâ dèfendu.',
 'mailmypassword' => 'Recêvre un contresegno novél per mèssageria èlèctronica',
 'passwordremindertitle' => 'Contresegno temporèro novél por {{SITENAME}}',
-'passwordremindertext' => 'Quârqu’un (probâblament vos, dês l’adrèce IP $1) at demandâ un contresegno
+'passwordremindertext' => 'Yon (probâblament vos, dês l’adrèce IP $1) at demandâ un contresegno
 novél por {{SITENAME}} ($4). Un contresegno temporèro est étâ fêt por
-l’utilisator « $2 » et est « $3 ». S’o ére voutra entencion, vos vos devréd
+l’utilisator « $2 » et il est « $3 ». S’o ére voutra entencion, vos vos devréd
 branchiér et pués chouèsir un contresegno novél.
-Voutron contresegno temporèro èxpirerat dens {{PLURAL:$5|yon jorn|$5 jorns}}.
+Voutron contresegno temporèro èxpirerat dens {{PLURAL:$5|un jorn|$5 jorns}}.
 
 Se cela demanda vint pas de vos ou ben que vos vos éte rapelâ
 de voutron contresegno et que vos souhètâd pas més lo changiér, vos
@@ -793,42 +793,42 @@ pouede ignorar ceti mèssâjo et continuar a empleyér voutron viely contresegno
 'noemail' => 'Nion’adrèce èlèctronica est étâye encartâye por l’utilisator « $1 ».',
 'noemailcreate' => 'Vos dête balyér n’adrèce èlèctronica justa',
 'passwordsent' => 'Un contresegno novél est étâ mandâ a l’adrèce èlèctronica de l’utilisator « $1 ».
-Vos volyéd tornar branchiér aprés l’avêr reçu.',
+Se vos plét, tornâd-vos branchiér aprés l’avêr reçu.',
 'blocked-mailpassword' => 'Voutron adrèce IP est blocâye en ècritura, la fonccion de sovegnence du contresegno est vêr dèsactivâye por èvitar los abus.',
 'eauthentsent' => 'Un mèssâjo de confirmacion est étâ mandâ a l’adrèce èlèctronica endicâye.
 Devant qu’un ôtro mèssâjo seye mandâ a ceti compto, vos devréd siuvre les enstruccions du mèssâjo et pués confirmar que lo compto est franc lo voutro.',
 'throttled-mailpassword' => 'Un mèssâjo de sovegnence de voutron contresegno est ja étâ mandâ pendent {{PLURAL:$1|l’hora passâye|les $1 hores passâyes}}.
-Por èvitar los abus, ren que yon mèssâjo de sovegnence serat mandâ per {{PLURAL:$1|hora|entèrvalo de $1 hores}}.',
+Por èvitar los abus, ren que yon serat mandâ per {{PLURAL:$1|hora|entèrvalo de $1 hores}}.',
 'mailerror' => 'Fôta pendent l’èxpèdicion du mèssâjo : $1',
-'acct_creation_throttle_hit' => 'Quârqu’un qu’emplèye voutron adrèce IP at fêt {{PLURAL:$1|yon compto|$1 comptos}} pendent les 24 hores passâyes, cen qu’est la limita ôtorisâye dens ceti temps.
-Du côp la crèacion de compto est étâye dèsactivâye temporèrament por cel’adrèce IP.',
+'acct_creation_throttle_hit' => 'Des visitors de cél vouiqui-que qu’emplèyont voutron adrèce IP ont fêt $1 compto{{PLURAL:$1||s}} pendent lo jorn passâ, cen qu’est lo més ôtorisâ dens ceti temps.
+Du côp los visitors qu’emplèyont cel’adrèce IP pôvont fâre gins de compto por lo moment.',
 'emailauthenticated' => 'Voutron adrèce èlèctronica est étâye ôtentifiâye lo $2 a $3.',
 'emailnotauthenticated' => 'Voutron adrèce èlèctronica est p’oncor ôtentifiâye.
 Nion mèssâjo serat mandâ por châcuna de cetes fonccionalitâts.',
 'noemailprefs' => 'Spècifiâd n’adrèce èlèctronica dens voutres prèferences por empleyér cetes fonccionalitâts.',
 'emailconfirmlink' => 'Confirmâd voutron adrèce èlèctronica',
-'invalidemailaddress' => 'Cet’adrèce èlèctronica pôt pas étre accèptâye perce que semble avêr un format pas justo.
-Volyéd buchiér n’adrèce bien formatâye ou ben lèssiér cél champ vouedo.',
+'invalidemailaddress' => 'Cet’adrèce èlèctronica pôt pas étre accèptâye, semble avêr un format pas justo.
+Se vos plét, buchiéd n’adrèce bien formatâye ou ben lèssiéd cél champ vouedo.',
 'cannotchangeemail' => 'Les adrèces èlèctroniques des comptos pôvont pas étre changiêes sur ceti vouiqui.',
 'emaildisabled' => 'Ceti seto pôt pas mandar des mèssâjos.',
 'accountcreated' => 'Compto fêt',
 'accountcreatedtext' => 'Lo compto utilisator por $1 est étâ fêt.',
 'createaccount-title' => 'Crèacion d’un compto por {{SITENAME}}',
-'createaccount-text' => 'Quârqu’un at fêt un compto por voutron adrèce èlèctronica dessus {{SITENAME}} ($4) apelâ « $2 », avouéc lo contresegno « $3 ».
+'createaccount-text' => 'Yon at fêt un compto por voutron adrèce èlèctronica dessus {{SITENAME}} ($4) apelâ « $2 », avouéc lo contresegno « $3 ».
 Vos vos devriâd branchiér et pués changiér dês ora voutron contresegno.
 
 Ignorâd ceti mèssâjo se cél compto est étâ fêt per fôta.',
 'usernamehasherror' => 'Lo nom d’utilisator pôt pas contegnir des caractèros de chaplâjo',
 'login-throttled' => 'Dês pou vos éd èprovâ un mouél de branchements.
-Volyéd atendre devant que tornar èprovar.',
+Se vos plét, atende devant que tornar èprovar.',
 'login-abort-generic' => 'Voutra tentativa de branchement at pas reussi - Anulâye',
 'loginlanguagelabel' => 'Lengoua : $1',
-'suspicious-userlogout' => 'Voutra demanda de dèbranchement est étâye refusâye perce que semble qu’el est étâye mandâye per un navigator câsso ou ben la misa en cacho d’un proxi.',
+'suspicious-userlogout' => 'Voutra demanda de dèbranchement est étâye refusâye, semble qu’el est étâye mandâye per un navigator câsso ou ben la misa en cacho d’un proxi.',
 
 # E-mail sending
 'php-mail-error-unknown' => 'Fôta encognua dens la fonccion mail() de PHP.',
-'user-mail-no-addy' => 'At tâchiê de mandar un mèssâjo sen adrèce èlèctronica.',
-'user-mail-no-body' => 'At tâchiê de mandar un mèssâjo avouéc un côrp vouedo ou ben dèrêsonâblament côrt.',
+'user-mail-no-addy' => 'Il at èprovâ de mandar un mèssâjo sen adrèce èlèctronica.',
+'user-mail-no-body' => 'Il at èprovâ de mandar un mèssâjo avouéc un côrp vouedo ou ben dèrêsonâblament côrt.',
 
 # Change password dialog
 'resetpass' => 'Changiér lo contresegno',
@@ -841,7 +841,7 @@ Por chavonar lo branchement, vos dête buchiér un contresegno novél ique :',
 'retypenew' => 'Confirmar lo contresegno novél :',
 'resetpass_submit' => 'Changiér lo contresegno et pués sè branchiér',
 'resetpass_success' => 'Voutron contresegno est étâ changiê avouéc reusséta !
-Branchement en cors...',
+Branchement en côrs...',
 'resetpass_forbidden' => 'Los contresegnos pôvont pas étre changiês',
 'resetpass-no-info' => 'Vos dête étre branchiê por arrevar tot drêt a cela pâge.',
 'resetpass-submit-loggedin' => 'Changiér lo contresegno',
@@ -858,17 +858,17 @@ Pôt-étre vos éd ja changiê voutron contresegno avouéc reusséta ou ben dema
 'passwordreset-pretext' => '{{PLURAL:$1||Buchiéd yona de les piéces de donâs ce-desot}}',
 'passwordreset-username' => 'Nom d’utilisator :',
 'passwordreset-domain' => 'Domêno :',
-'passwordreset-capture' => 'Vêre lo mèssâjo que rèsulte ?',
+'passwordreset-capture' => 'Est-o que vos voléd vêre lo mèssâjo que rèsulte ?',
 'passwordreset-capture-help' => 'Se vos pouentâd cela câsa, lo mèssâjo (avouéc lo contresegno temporèro) vos serat montrâ quand serat mandâ a l’utilisator.',
 'passwordreset-email' => 'Adrèce èlèctronica :',
 'passwordreset-emailtitle' => 'Dètalys du compto dessus {{SITENAME}}',
-'passwordreset-emailtext-ip' => 'Quârqu’un (probâblament vos, dês l’adrèce IP $1) at demandâ na sovegnence des dètalys
+'passwordreset-emailtext-ip' => 'Yon (probâblament vos, dês l’adrèce IP $1) at demandâ na sovegnence des dètalys
 de voutron compto por {{SITENAME}} ($4). {{PLURAL:$3|Ceti compto utilisator est associyê|Cetos comptos utilisators sont associyês}}
 a cel’adrèce èlèctronica :
 
 $2
 
-{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|yon jorn|$5 jorns}}.
+{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|un jorn|$5 jorns}}.
 Ora vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos
 ou ben que vos vos éte rapelâ de voutron contresegno originâl et que vos souhètâd pas més lo changiér,
 vos pouede ignorar ceti mèssâjo et continuar a empleyér voutron viely contresegno.',
@@ -878,7 +878,7 @@ a cel’adrèce èlèctronica :
 
 $2
 
-{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|yon jorn|$5 jorns}}.
+{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|un jorn|$5 jorns}}.
 Ora vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos
 ou ben que vos vos éte rapelâ de voutron contresegno originâl et que vos souhètâd pas més lo changiér,
 vos pouede ignorar ceti mèssâjo et continuar a empleyér voutron viely contresegno.',
@@ -895,7 +895,7 @@ Contresegno temporèro : $2',
 '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 :',
-'changeemail-none' => '(niona)',
+'changeemail-none' => '(pas yona)',
 'changeemail-password' => 'Voutron contresegno dessus {{SITENAME}} :',
 'changeemail-submit' => 'Changiér l’adrèce èlèctronica',
 'changeemail-cancel' => 'Anular',
@@ -917,7 +917,7 @@ Contresegno temporèro : $2',
 'image_tip' => 'Fichiér apondu',
 'media_sample' => 'Ègzemplo.ogg',
 'media_tip' => 'Lim de vers un fichiér',
-'sig_tip' => 'Voutra signatura avouéc la dâta et hora',
+'sig_tip' => 'Voutra signatura avouéc l’horodatâjo',
 'hr_tip' => 'Legne plana (pas nen abusar)',
 
 # Edit pages
@@ -935,13 +935,13 @@ Voutron adrèce IP serat encartâye dedens l’historico des changements de ceta
 'anonpreviewwarning' => "''Vos éte pas branchiê(e). Sôvar encarterat voutron adrèce IP dedens l’historico des changements de ceta pâge.''",
 'missingsummary' => "'''Sovegnence :''' vos éd balyê gins de rèsumâ de changement.
 Se vos tornâd clicar sur lo boton « {{int:savearticle}} », voutron changement serat encartâ sen rèsumâ.",
-'missingcommenttext' => 'Volyéd buchiér un comentèro ce-desot.',
+'missingcommenttext' => 'Se vos plét, buchiéd un comentèro ce-desot.',
 'missingcommentheader' => "'''Sovegnence :''' vos éd balyê gins de chousa / titro a ceti comentèro.
 Se vos tornâd clicar sur lo boton « {{int:savearticle}} », voutron changement serat encartâ sen chousa / titro.",
 'summary-preview' => 'Apèrçu du rèsumâ :',
 'subject-preview' => 'Apèrçu de la chousa / du titro :',
 'blockedtitle' => 'L’utilisator est blocâ',
-'blockedtext' => "'''Voutron nom d’utilisator ou ben voutron adrèce IP est étâ(ye) blocâ(ye).'''
+'blockedtext' => "'''Voutron nom d’utilisator voutron adrèce IP est étâ(ye) blocâ(ye).'''
 
 Lo blocâjo est étâ fêt per $1.
 La rêson balyêe est ''$2''.
@@ -951,10 +951,10 @@ La rêson balyêe est ''$2''.
 * Compto blocâ : $7
 
 Vos vos pouede veriér vers $1 ou ben un ôtr’[[{{MediaWiki:Grouppage-sysop}}|administrator]] por nen discutar.
-Vos pouede pas empleyér la fonccionalitât « Lui mandar un mèssâjo » a muens qu’un’adrèce èlèctronica justa est spècifiâye dens voutres [[Special:Preferences|prèferences]] et que vos éte pas étâ blocâ de l’empleyér.
+Vos pouede pas empleyér la fonccionalitât « Lui mandar un mèssâjo » du muens qu’un’adrèce èlèctronica justa seye spècifiâye dens voutres [[Special:Preferences|prèferences]] et que vos seyâd pas étâ blocâ de l’empleyér.
 Voutron adrèce IP d’ora est $3, et l’identifient de blocâjo est $5.
-Volyéd entrebetar tôs los dètalys ce-dessus dedens na sé-quinta demanda que vos faréd.",
-'autoblockedtext' => "Voutron adrèce IP est étâye blocâye ôtomaticament perce qu’el est étâye empleyêe per un ôtr’utilisator, lui-mémo blocâ per $1.
+Se vos plét, entrebetâd tôs los dètalys ce-dessus dedens na demanda la quinta que seye que vos faréd.",
+'autoblockedtext' => "Voutron adrèce IP est étâye blocâye ôtomaticamentel est étâye empleyêe per un ôtr’utilisator, lui-mémo blocâ per $1.
 La rêson balyêe est :
 
 :''$2''
@@ -965,16 +965,16 @@ La rêson balyêe est :
 
 Vos vos pouede veriér vers $1 ou ben yon des ôtros [[{{MediaWiki:Grouppage-sysop}}|administrators]] por nen discutar.
 
-Notâd que vos porréd pas empleyér la fonccionalitât « Lui mandar un mèssâjo » a muens que vos avéd n’adrèce èlèctronica justa encartâye dens voutres [[Special:Preferences|prèferences]] et que vos éte pas étâ blocâ de l’empleyér.
+Notâd que vos porréd pas empleyér la fonccionalitât « Lui mandar un mèssâjo » du muens que vos èyâd n’adrèce èlèctronica justa encartâye dens voutres [[Special:Preferences|prèferences]] et que vos seyâd pas étâ blocâ de l’empleyér.
 
 Voutron adrèce IP d’ora est $3, et l’identifient de blocâjo est $5.
-Volyéd entrebetar tôs los dètalys ce-dessus dedens na sé-quinta demanda que vos faréd.",
+Se vos plét, entrebetâd tôs los dètalys ce-dessus dedens na demanda la quinta que seye que vos faréd.",
 'blockednoreason' => 'niona rêson balyêe',
 'whitelistedittext' => 'Vos vos dête $1 por povêr changiér les pâges.',
 'confirmedittext' => 'Vos dête confirmar voutron adrèce èlèctronica devant que changiér les pâges.
-Volyéd buchiér et pués validar voutron adrèce èlèctronica dens voutres [[Special:Preferences|prèferences]].',
-'nosuchsectiontitle' => 'Empossiblo de trovar la sèccion',
-'nosuchsectiontext' => 'Vos éd tâchiê de changiér na sèccion qu’ègziste pas.
+Se vos plét, buchiéd et pués validâd voutron adrèce èlèctronica dens voutres [[Special:Preferences|prèferences]].',
+'nosuchsectiontitle' => 'Y at pas moyen de trovar la sèccion',
+'nosuchsectiontext' => 'Vos éd èprovâ de changiér na sèccion qu’ègziste pas.
 Pôt-étre el est étâye dèplaciêe ou ben ôtâye dês que vos éd liesu cela pâge.',
 'loginreqtitle' => 'Branchement nècèssèro',
 'loginreqlink' => 'branchiér',
@@ -988,21 +988,21 @@ Lo contresegno por cél compto novél pôt étre changiê sur la pâge de ''[[Sp
 Por fâre cela pâge, buchiéd voutron tèxto dedens la bouèta ce-desot (vêde la [[{{MediaWiki:Helppage}}|pâge d’éde]] por més d’enformacions).
 Se vos éte arrevâ{{GENDER:||ye|(ye)}} ice per fôta, clicâd sur lo boton '''Devant''' de voutron navigator.",
 'anontalkpagetext' => "----''O est la pâge de discussion d’un utilisator anonimo qu’at p’oncor fêt un compto ou ben que nen emplèye pas.
-Por cen nos devens empleyér la sin’adrèce IP numerica por l’identifiar.
-N’adrèce IP pôt étre partagiêe per un mouél d’utilisators.
-Se vos éte {{GENDER:|un utilisator|n’utilisatrice|un utilisator}} anonim{{GENDER:|o|a|o}} et pués se vos constatâd que des comentèros que vos regârdont pas vos sont étâs adrèciês, volyéd [[Special:UserLogin/signup|fâre un compto]] ou ben [[Special:UserLogin|vos branchiér]] por èvitar tota confusion a vegnir avouéc d’ôtros utilisators anonimos.''",
+Por cen nos devens empleyér la sin’adrèce IP numerica por lo recognetre.
+N’adrèce IP d’ense pôt étre partagiêe per un mouél d’utilisators.
+Se vos éte {{GENDER:|un utilisator|n’utilisatrice|un utilisator}} anonim{{GENDER:|o|a|o}} et pués se vos constatâd que des comentèros que vos regârdont pas vos sont étâs adrèciês, se vos plét [[Special:UserLogin/signup|féte un compto]] ou ben [[Special:UserLogin|branchiéd-vos]] por èvitar tota confusion que vint avouéc d’ôtros utilisators anonimos.''",
 'noarticletext' => 'Ora y at gins de tèxto dedens cela pâge.
 Vos pouede [[Special:Search/{{PAGENAME}}|fâre na rechèrche sur cél titro]] dedens les ôtres pâges,
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechèrchiér dedens los jornals liyês]
 ou ben [{{fullurl:{{FULLPAGENAME}}|action=edit}} fâre cela pâge]</span>.',
 'noarticletext-nopermission' => 'Ora y at gins de tèxto dedens cela pâge.
-Vos pouede [[Special:Search/{{PAGENAME}}|fâre na rechèrche sur cél titro]] dedens les ôtres pâges ou ben <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechèrchiér dedens los jornals liyês]</span>, mas vos avéd pas la pèrmission de fâre cela pâge.',
+Vos pouede [[Special:Search/{{PAGENAME}}|fâre na rechèrche sur cél titro]] dedens les ôtres pâges ou ben <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechèrchiér dedens los jornals liyês]</span>, mas vos éd pas la pèrmission de fâre cela pâge.',
 'missing-revision' => 'La vèrsion numerô $1 de la pâge apelâye « {{PAGENAME}} » ègziste pas.
 
 En g·ènèral cen arreve en siuvent un lim d’un historico dèpassâ de vers na pâge qu’est étâye suprimâye.
 Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} jornal de les suprèssions].',
 'userpage-userdoesnotexist' => 'Lo compto utilisator « $1 » est pas encartâ.
-Volyéd controlar que vos voléd fâre ou ben changiér cela pâge.',
+Se vos plét, controlâd que vos voléd fâre / changiér cela pâge.',
 'userpage-userdoesnotexist-view' => 'Lo compto utilisator « $1 » est pas encartâ.',
 'blocked-notice-logextract' => '{{GENDER:$1|Cél utilisator|Cel’utilisatrice|Cél utilisator}} est ora blocâ{{GENDER:$1||ye|}}.
 La dèrriére entrâ du jornal des blocâjos est disponibla ce-desot :',
@@ -1027,18 +1027,18 @@ Rapelâd-vos que les pâges a sè avouéc èxtensions .css et .js emplèyont des
 'note' => "'''Nota :'''",
 'previewnote' => "'''Rapelâd-vos qu’o est ren qu’un apèrçu.'''
 Voutros changements sont p’oncor étâs encartâs !",
-'continue-editing' => 'Alar a la zona de changement',
+'continue-editing' => 'Alar vers la zona de changement',
 'previewconflict' => 'Cet’apèrçu fât vêre lo tèxto de la zona de changement de d’amont coment aparêtrat se vos chouèsésséd de l’encartar.',
 'session_fail_preview' => "'''Dèconsolâ ! Nos povens pas encartar voutron changement a côsa d’una pèrta d’enformacions sur voutra sèance.'''
-Volyéd tornar èprovar.
-Se cen tôrne pas reussir, vos volyéd [[Special:UserLogout|dèbranchiér]] et pués vos tornar branchiér.",
+Se vos plét, tornâd èprovar.
+Se cen tôrne pas reussir, [[Special:UserLogout|dèbranchiéd-vos]] et pués tornâd-vos branchiér.",
 'session_fail_preview_html' => "'''Dèconsolâ ! Nos povens pas encartar voutron changement a côsa d’una pèrta d’enformacions sur voutra sèance.'''
 
 ''Perce que {{SITENAME}} at activâ l’HTML bruto, l’apèrçu est étâ cachiê por prèvegnir les ataques per JavaScript.''
 
-'''Se la tentativa de changement ére lèg·itima, volyéd tornar èprovar.'''
-Se cen tôrne pas reussir, vos volyéd [[Special:UserLogout|dèbranchiér]] et pués vos tornar branchiér.",
-'token_suffix_mismatch' => "'''Voutron changement est pas étâ accèptâ perce que voutron cliant at mècllâ los caractèros de ponctuacion dedens lo jeton de changement.'''
+'''Se la tentativa de changement ére lèg·itima, se vos plét tornâd èprovar.'''
+Se cen tôrne pas reussir, [[Special:UserLogout|dèbranchiéd-vos]] et pués tornâd-vos branchiér.",
+'token_suffix_mismatch' => "'''Voutron changement est pas étâ accèptâ, voutron cliant at mècllâ los caractèros de ponctuacion dedens lo jeton de changement.'''
 Lo changement est étâ refusâ por empachiér la corrupcion du tèxto de la pâge.
 Des côps ceti problèmo arreve quand vos empleyéd un sèrviço de proxi Vouèbe anonimo qu’est pas de sûr.",
 'edit_form_incomplete' => "'''Quârques parties du formulèro de changement ont pas avengiê lo sèrvior ; controlâd que voutros changements sont entiérs et pués tornâd èprovar.'''",
@@ -1047,7 +1047,7 @@ Des côps ceti problèmo arreve quand vos empleyéd un sèrviço de proxi Vouèb
 'editingsection' => 'Changement de $1 (sèccion)',
 'editingcomment' => 'Changement de $1 (novèla sèccion)',
 'editconflict' => 'Conflit de changement : $1',
-'explainconflict' => "Quârqu’un d’ôtro at changiê ceta pâge aprés que vos vos seyâd betâ a la changiér.
+'explainconflict' => "Un ôtro at changiê ceta pâge aprés que vos vos seyâd betâ a la changiér.
 La zona de changement de d’amont contint lo tèxto de la pâge coment ègziste orendrêt.
 Voutros changements aparèssont dedens la zona de changement de desot.
 Vos voléd devêr fusionar voutros changements dedens lo tèxto ègzistent.
@@ -1059,27 +1059,27 @@ Na solucion de rechanjo est étâye trovâye por vos pèrmetre de changiér en t
 'editingold' => "'''Atencion : vos éte aprés changiér na vèrsion dèpassâye de cela pâge.'''
 Se vos l’encartâd, tôs los changements fêts dês ceta vèrsion seront pèrdus.",
 'yourdiff' => 'Difèrences',
-'copyrightwarning' => "Volyéd notar que totes les contribucions a {{SITENAME}} sont considèrâyes coment publeyêes desot los tèrmos de la $2 (vêde $1 por més de dètalys).
-Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion et pués rebalyês a volontât, adonc los volyéd pas sometre ique.<br />
-Vos nos assurâd asse-ben que vos éd cen ècrit vos-mémo ou ben que vos l’éd copiyê d’una sôrsa que vint du domêno publico ou ben d’un’ôtra ressôrsa libra.
+'copyrightwarning' => "Se vos plét, notâd que totes les contribucions a {{SITENAME}} sont considèrâyes coment publeyêes desot los tèrmos de la $2 (vêde $1 por més de dètalys).
+Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion et rebalyês a volontât, adonc mandâd-los pas ique.<br />
+Vos nos assurâd asse-ben que vos éd cen ècrit vos-mémo ou ben que vos l’éd copiyê d’una sôrsa que vint du domêno publico ou d’un’ôtra ressôrsa libra.
 '''Empleyéd gins d’ôvra desot drêt d’ôtor sen pèrmission èxprèssa !'''",
-'copyrightwarning2' => "Volyéd notar que totes les contribucions a {{SITENAME}} pôvont étre changiêes ou ben enlevâyes per d’ôtros contributors.
-Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion, adonc los volyéd pas sometre ique.<br />
-Vos nos assurâd asse-ben que vos éd cen ècrit vos-mémo ou ben que vos l’éd copiyê d’una sôrsa que vint du domêno publico ou ben d’un’ôtra ressôrsa libra (vêde $1 por més de dètalys).
+'copyrightwarning2' => "Se vos plét, notâd que totes les contribucions a {{SITENAME}} pôvont étre changiêes ou ben enlevâyes per d’ôtros contributors.
+Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion, adonc mandâd-los pas ique.<br />
+Vos nos assurâd asse-ben que vos éd cen ècrit vos-mémo ou ben que vos l’éd copiyê d’una sôrsa que vint du domêno publico ou d’un’ôtra ressôrsa libra (vêde $1 por més de dètalys).
 '''Empleyéd gins d’ôvra desot drêt d’ôtor sen pèrmission èxprèssa !'''",
-'longpageerror' => "'''Fôta : lo tèxto que vos éd somês fât {{PLURAL:$1|yon Kio|$1 Kio}}, cen que dèpâsse la limita fixâye a {{PLURAL:$2|yon Kio|$2 Kio}}.'''
+'longpageerror' => "'''Fôta : lo tèxto que vos éd mandâ fât {{PLURAL:$1|un Kio|$1 Kio}}, cen que dèpâsse la limita fixâye a {{PLURAL:$2|un Kio|$2 Kio}}.'''
 Pôt pas étre encartâ.",
 'readonlywarning' => "'''Atencion : la bâsa de donâs est étâye vèrrolyêe por mantegnence, vos porréd vêr pas encartar voutros changements d’abôrd.'''
-Vos pouede copiyér lo tèxto dedens un fichiér tèxto et pués l’encartar por ples târd.
+Vos pouede copiyér et côlar voutron tèxto dedens un fichiér tèxto et pués l’encartar por ples târd.
 
 L’administrator qu’at vèrrolyê la bâsa de donâs at balyê cet’èxplicacion : $1",
 'protectedpagewarning' => "'''Atencion : ceta pâge est étâye protègiêe de façon que solament los utilisators qu’ont lo statut d’administrator la pouessont changiér.'''
-La dèrriére entrâ du jornal est montrâye ce-desot por refèrence :",
+Por refèrence, la dèrriére entrâ du jornal est balyêe ce-desot :",
 'semiprotectedpagewarning' => "'''Nota :''' ceta pâge est étâye protègiêe de façon que solament los utilisators encartâs la pouessont changiér.
-La dèrriére entrâ du jornal est montrâye ce-desot por refèrence :",
+Por refèrence, la dèrriére entrâ du jornal est balyêe ce-desot :",
 'cascadeprotectedwarning' => "'''Atencion :''' cela pâge-que est étâye protègiêe de façon que solament los utilisators qu’ont lo statut d’administrator la pouessont changiér, perce qu’el est entrebetâye dedens {{PLURAL:$1|ceta pâge protègiêe|cetes pâges protègiêes}} avouéc la « protèccion en cascâda » activâye :",
 'titleprotectedwarning' => "'''Atencion : ceta pâge est étâye protègiêe de façon que des [[Special:ListGroupRights|drêts spècificos]] sont nècèssèros por la povêr fâre.'''
-La dèrriére entrâ du jornal est montrâye ce-desot por refèrence :",
+Por refèrence, la dèrriére entrâ du jornal est balyêe ce-desot :",
 'templatesused' => '{{PLURAL:$1|Modèlo empleyê|Modèlos empleyês}} per ceta pâge :',
 'templatesusedpreview' => '{{PLURAL:$1|Modèlo empleyê|Modèlos empleyês}} dedens cet’apèrçu :',
 'templatesusedsection' => '{{PLURAL:$1|Modèlo empleyê|Modèlos empleyês}} dedens ceta sèccion :',
@@ -1089,26 +1089,26 @@ La dèrriére entrâ du jornal est montrâye ce-desot por refèrence :",
 'edittools' => '<!-- Tot tèxto buchiê ique serat montrâ desot les bouètes d’èdicion ou ben los formulèros de tèlèchargement de fichiér. -->',
 'nocreatetext' => '{{SITENAME}} at rètrent la possibilitât de fâre de pâges novèles.
 Vos pouede tornar arriér et pués changiér na pâge ègzistenta ou ben [[Special:UserLogin|vos branchiér ou fâre un compto]].',
-'nocreate-loggedin' => 'Vos avéd pas la pèrmission de fâre de pâges novèles.',
+'nocreate-loggedin' => 'Vos éd pas la pèrmission de fâre de pâges novèles.',
 'sectioneditnotsupported-title' => 'Changement de sèccion pas recognu',
 'sectioneditnotsupported-text' => 'Lo changement d’una sèccion est pas recognu dens cela pâge.',
 'permissionserrors' => 'Fôta de pèrmissions',
-'permissionserrorstext' => 'Vos avéd pas la pèrmission de fâre l’accion demandâye por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
-'permissionserrorstext-withaction' => 'Vos avéd pas la pèrmission de $2 por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
+'permissionserrorstext' => 'Vos éd pas la pèrmission de fâre l’accion demandâye por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
+'permissionserrorstext-withaction' => 'Vos éd pas la pèrmission de $2 por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
 'recreate-moveddeleted-warn' => "'''Atencion : vos éte aprés refâre na pâge qu’est étâye suprimâye dês devant.'''
 
 Demandâd-vos se fôt franc continuar son changement.
-Por comoditât, lo jornal de les suprèssions et des dèplacements de cela pâge est montrâ ce-desot :",
+Por comoditât, lo jornal de les suprèssions et des dèplacements de cela pâge est balyê ce-desot :",
 'moveddeleted-notice' => 'Ceta pâge est étâye suprimâye.
-Por refèrence, lo jornal de les suprèssions et des dèplacements de cela pâge est montrâ ce-desot.',
+Por refèrence, lo jornal de les suprèssions et des dèplacements de cela pâge est balyê ce-desot.',
 'log-fulllog' => 'Vêre lo jornal complèt',
 'edit-hook-aborted' => 'Changement anulâ per un grèfon.
 Nion’èxplicacion est étâye balyêe.',
-'edit-gone-missing' => 'Empossiblo de betar a jorn la pâge.
+'edit-gone-missing' => 'Y at pas moyen de betar a jorn la pâge.
 Semble que seye étâye suprimâye.',
 'edit-conflict' => 'Conflit de changement.',
-'edit-no-change' => 'Voutron changement est étâ ignorâ perce que nion changement est étâ fêt u tèxto.',
-'edit-already-exists' => 'Empossiblo de fâre na pâge novèla.
+'edit-no-change' => 'Voutron changement est étâ ignorâ, nion changement est étâ fêt u tèxto.',
+'edit-already-exists' => 'Y at pas moyen de fâre na pâge novèla.
 Ègziste ja.',
 'defaultmessagetext' => 'Mèssâjo per dèfôt',
 'content-failed-to-parse' => 'Falyita de l’analisa du contegnu de $2 por lo modèlo $1 : $3',
@@ -1129,7 +1129,7 @@ Y devrêt avêr muens de $2 apèl{{PLURAL:$2||s}}, pendent qu’y en at ora $1."
 'post-expand-template-inclusion-warning' => "'''Atencion :''' la talye des modèlos entrebetâs est trop grôssa.
 Quârques modèlos seront pas entrebetâs.",
 'post-expand-template-inclusion-category' => 'Pâges yô que la talye des modèlos entrebetâs est dèpassâye',
-'post-expand-template-argument-warning' => "'''Atencion :''' cela pâge contint u muens yon argument de modèlo qu’at na talye d’èxpension trop grôssa.
+'post-expand-template-argument-warning' => "'''Atencion :''' cela pâge contint por lo muens un argument de modèlo qu’at na talye d’èxpension trop grôssa.
 Celos arguments sont pas étâs betâs.",
 'post-expand-template-argument-category' => 'Pâges que contegnont des arguments de modèlo pas betâs',
 'parser-template-loop-warning' => 'Modèlo en boclla dècelâ : [[$1]]',
@@ -1145,13 +1145,13 @@ Celos arguments sont pas étâs betâs.",
 
 # "Undo" feature
 'undo-success' => 'Lo changement pôt étre dèfêt.
-Volyéd controlar la comparèson ce-desot por vos assurar qu’o est franc cen que vos voléd fâre et pués encartar los changements ce-desot por chavonar la sina dèfêta.',
+Se vos plét, controlâd la comparèson ce-desot por vos assurar qu’o est franc cen que vos voléd fâre et pués encartâd los changements ce-desot por chavonar la sina dèfêta.',
 'undo-failure' => 'Lo changement at pas possu étre dèfêt a côsa d’un conflit avouéc des changements entèrmèdièros.',
 'undo-norev' => 'Lo changement at pas possu étre dèfêt perce qu’il est pas ègzistent ou ben qu’il est étâ suprimâ.',
 'undo-summary' => 'Dèfêta du changement $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discutar]])',
 
 # Account creation failure
-'cantcreateaccounttitle' => 'Empossiblo de fâre lo compto',
+'cantcreateaccounttitle' => 'Y at pas moyen de fâre lo compto',
 'cantcreateaccount-text' => "La crèacion de compto dês cet’adrèce IP ('''$1''') est étâye blocâye per [[User:$3|$3]].
 
 La rêson balyêe per $3 ére ''$2''.",
@@ -1186,7 +1186,7 @@ Lègenda : '''({{int:cur}})''' = difèrence avouéc la vèrsion d’ora, '''({{i
 'history-feed-item-nocomment' => '$1 lo $3 a $4',
 'history-feed-empty' => 'La pâge demandâye ègziste pas.
 Pôt-étre el est étâye suprimâye du vouiqui ou ben renomâye.
-Tâchiéd de [[Special:Search|rechèrchiér sur lo vouiqui]] por trovar des pâges novèles que vont avouéc.',
+Èprovâd de [[Special:Search|rechèrchiér sur lo vouiqui]] por trovar des pâges novèles que vont avouéc.',
 
 # Revision deletion
 'rev-deleted-comment' => '(rèsumâ de changement enlevâ)',
@@ -1207,7 +1207,7 @@ Vos la pouede vêre ; y pôt avêr més de dètalys dedens lo [{{fullurl:{{#Spec
 Vos la pouede vêre ; y pôt avêr més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} jornal de les rèprèssions].",
 'rev-deleted-no-diff' => "Vos pouede pas vêre ceta dif perce que yona de les vèrsions est étâye '''suprimâye'''.
 Y pôt avêr més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} jornal de les suprèssions].",
-'rev-suppressed-no-diff' => "Vos pouede pas vêre ceta dif perce que yona de les vèrsions est étâye '''suprimâye'''.",
+'rev-suppressed-no-diff' => "Vos pouede pas vêre ceta dif, yona de les vèrsions est étâye '''suprimâye'''.",
 'rev-deleted-unhide-diff' => "Yona de les vèrsions de ceta dif est étâye '''suprimâye'''.
 Y pôt avêr més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} jornal de les suprèssions].
 Vos pouede adés [$1 vêre cela dif] se vos o voléd.",
@@ -1222,24 +1222,24 @@ Vos pouede vêre ceta dif ; y pôt avêr més de dètalys dedens lo [{{fullurl:{
 'rev-showdeleted' => 'montrar',
 'revisiondelete' => 'Suprimar / refâre des vèrsions',
 'revdelete-nooldid-title' => 'Vèrsion ciba pas justa',
-'revdelete-nooldid-text' => 'Vos éd pas spècifiâ na vèrsion ciba (ou ben des vèrsions cibes) por fâre cela
-fonccion, la vèrsion spècifiâye ègziste pas ou ben vos tâchiéd de cachiér la vèrsion d’ora.',
+'revdelete-nooldid-text' => 'Vos éd pas spècifiâ na vèrsion ciba (des vèrsions cibes) por fâre cela
+fonccion, la vèrsion spècifiâye ègziste pas ou ben vos èprovâd de cachiér la vèrsion d’ora.',
 'revdelete-nologtype-title' => 'Nion tipo de jornal balyê',
 'revdelete-nologtype-text' => 'Vos éd pas spècifiâ un tipo de jornal por fâre cel’accion.',
 'revdelete-nologid-title' => 'Entrâ du jornal pas justa',
 'revdelete-nologid-text' => 'Ou ben vos éd pas spècifiâ un èvènement du jornal ciba por fâre cela fonccion ou ben l’entrâ spècifiâye ègziste pas.',
 'revdelete-no-file' => 'Lo fichiér spècifiâ ègziste pas.',
-'revdelete-show-file-confirm' => 'Éte-vos de sûr de volêr vêre na vèrsion suprimâye du fichiér « <nowiki>$1</nowiki> » du $2 a $3 ?',
+'revdelete-show-file-confirm' => 'Est-o que vos éte de sûr de volêr vêre na vèrsion suprimâye du fichiér « <nowiki>$1</nowiki> » du $2 a $3 ?',
 'revdelete-show-file-submit' => 'Ouè',
 'revdelete-selected' => "'''{{PLURAL:$2|Vèrsion chouèsia|Vèrsions chouèsies}} de [[:$1]] :'''",
 'logdelete-selected' => "'''{{PLURAL:$1|Èvènement du jornal chouèsi|Èvènements du jornal chouèsis}} :'''",
 'revdelete-text' => "'''Les vèrsions et los èvènements suprimâ(ye)s aparètront adés dedens l’historico de la pâge et pués dedens los jornals, mas quârques parties de lor contegnu seront inaccèssibles u publico.'''
-Los ôtros administrators de {{SITENAME}} porront tojorn arrevar u contegnu cachiê et lo refâre per cela mém’entèrface, a muens que des rèstriccions de ples seyont pas dèfenies.",
-'revdelete-confirm' => 'Volyéd confirmar qu’o est franc cen que vos voléd fâre, que vos en compregnéd les consèquences et pués que vos o féte en acôrd avouéc les [[{{MediaWiki:Policy-url}}|règlles de dedens]].',
+Los ôtros administrators de {{SITENAME}} porront tojorn arrevar u contegnu cachiê et lo refâre per cela mém’entèrface, du muens que des rèstriccions de ples seyont pas dèfenies.",
+'revdelete-confirm' => 'Se vos plét, confirmâd qu’o est franc cen que vos voléd fâre, que vos en compregnéd les consèquences et pués que vos o féte en acôrd avouéc les [[{{MediaWiki:Policy-url}}|règlles de dedens]].',
 'revdelete-suppress-text' => "La rèprèssion dêt étre empleyêe '''ren que''' dens cetos câs :
 * Enformacions que pôvont étre difamatouères
 * Enformacions a sè que vont pas avouéc
-*: ''adrèces et numerôs de tèlèfono, numerôs de sècuritât sociâla, ...''",
+*: ''adrèces et numerôs de tèlèfono, numerôs de sècuritât sociâla, et tot cen que vat avouéc''",
 'revdelete-legend' => 'Dèfenir des rèstriccions de visibilitât',
 'revdelete-hide-text' => 'Cachiér lo tèxto de la vèrsion',
 'revdelete-hide-image' => 'Cachiér lo contegnu du fichiér',
@@ -1268,13 +1268,13 @@ $1",
 'revdelete-hide-current' => 'Fôta en cachient la piéce datâye du $1 a $2 : o est la vèrsion d’ora.
 Pôt pas étre cachiêe.',
 'revdelete-show-no-access' => 'Fôta en montrent la piéce datâye du $1 a $2 : el est marcâye coment « rètrenta ».
-Vos y avéd pas accès.',
+Vos y éd pas accès.',
 'revdelete-modify-no-access' => 'Fôta en changient la piéce datâye du $1 a $2 : el est marcâye coment « rètrenta ».
-Vos y avéd pas accès.',
+Vos y éd pas accès.',
 'revdelete-modify-missing' => 'Fôta en changient la piéce avouéc l’identifient $1 : el est manquenta dedens la bâsa de donâs !',
 'revdelete-no-change' => "'''Atencion :''' la piéce datâye du $1 a $2 at ja la configuracion de visibilitât demandâye.",
-'revdelete-concurrent-change' => 'Fôta en changient la piéce datâye du $1 a $2 : lo sin statut semble étre étâ changiê per quârqu’un d’ôtro justo que vos tâchiêvâd d’o changiér.
-Volyéd controlar los jornals.',
+'revdelete-concurrent-change' => 'Fôta en changient la piéce datâye du $1 a $2 : lo sin statut semble étre étâ changiê per un ôtro justo que vos èprovâvâd d’o changiér.
+Se vos plét, controlâd los jornals.',
 'revdelete-only-restricted' => 'Fôta en cachient la piéce datâye du $1 a $2 : vos pouede pas rèprimar celes piéces de la vua ux administrators sen chouèsir avouéc des ôtros chouèx de visibilitât.',
 'revdelete-reason-dropdown' => '*Rêsons corentes de suprèssion
 ** Violacion du drêt d’ôtor
@@ -1306,7 +1306,7 @@ Notâd que l’usâjo des lims de navigacion remetrat a zérô cela colona.',
 'mergehistory-submit' => 'Fusionar les vèrsions',
 'mergehistory-empty' => 'Niona vèrsion pôt étre fusionâye.',
 'mergehistory-success' => '$3 vèrsion{{PLURAL:$3||s}} de [[:$1]] fusionâye{{PLURAL:$3||s}} avouéc reusséta dedens [[:$2]].',
-'mergehistory-fail' => 'Empossiblo de fâre la fusion des historicos, volyéd tornar chouèsir la pâge et pués los paramètros de dâta.',
+'mergehistory-fail' => 'Y at pas moyen de fâre la fusion des historicos, se vos plét tornâd chouèsir la pâge et pués los paramètros de dâta.',
 'mergehistory-no-source' => 'La pâge d’origina $1 ègziste pas.',
 'mergehistory-no-destination' => 'La pâge de dèstinacion $1 ègziste pas.',
 'mergehistory-invalid-source' => 'La pâge d’origina dêt avêr un titro justo.',
@@ -1331,9 +1331,9 @@ Notâd que l’usâjo des lims de navigacion remetrat a zérô cela colona.',
 'compareselectedversions' => 'Comparar les vèrsions chouèsies',
 'showhideselectedversions' => 'Montrar / cachiér les vèrsions chouèsies',
 'editundo' => 'dèfâre',
-'diff-multi' => '({{PLURAL:$1|Yona vèrsion entèrmèdièra|$1 vèrsions entèrmèdières}} per {{PLURAL:$2|yon utilisator|$2 utilisators}} {{PLURAL:$1|est pas montrâye|sont pas montrâyes}})',
-'diff-multi-manyusers' => '({{PLURAL:$1|Yona vèrsion entèrmèdièra|$1 vèrsions entèrmèdières}} per més de $2 utilisator{{PLURAL:$2||s}} {{PLURAL:$1|est pas montrâye|sont pas montrâyes}})',
-'difference-missing-revision' => '{{PLURAL:$2|Yona vèrsion|$2 vèrsions}} de cela difèrence ($1) {{PLURAL:$2|est pas étâye trovâye|sont pas étâyes trovâyes}}.
+'diff-multi' => '({{PLURAL:$1|Na vèrsion entèrmèdièra|$1 vèrsions entèrmèdières}} per {{PLURAL:$2|un utilisator|$2 utilisators}} {{PLURAL:$1|est pas montrâye|sont pas montrâyes}})',
+'diff-multi-manyusers' => '({{PLURAL:$1|Na vèrsion entèrmèdièra|$1 vèrsions entèrmèdières}} per més de $2 utilisator{{PLURAL:$2||s}} {{PLURAL:$1|est pas montrâye|sont pas montrâyes}})',
+'difference-missing-revision' => '{{PLURAL:$2|Na vèrsion|$2 vèrsions}} de cela difèrence ($1) {{PLURAL:$2|est pas étâye trovâye|sont pas étâyes trovâyes}}.
 
 En g·ènèral cen arreve en siuvent un lim d’una dif dèpassâye de vers na pâge qu’est étâye suprimâye.
 Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} jornal de les suprèssions].',
@@ -1344,7 +1344,7 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'searchresulttext' => 'Por més d’enformacions sur la rechèrche dedens {{SITENAME}}, vêde [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => "Vos éd rechèrchiê « '''[[:$1]]''' » ([[Special:Prefixindex/$1|totes les pâges que començont per « $1 »]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|totes les pâges qu’ont un lim de vers « $1 »]])",
 'searchsubtitleinvalid' => "Vos éd rechèrchiê « '''$1''' »",
-'toomanymatches' => 'Un mouél de corrèspondances est étâ retornâ, volyéd èprovar na rechèrche difèrenta.',
+'toomanymatches' => 'Un mouél de corrèspondances est étâ retornâ, se vos plét èprovâd na rechèrche difèrenta',
 'titlematches' => 'Corrèspondances dedens los titros de les pâges',
 'notitlematches' => 'Niona corrèspondance dedens los titros de les pâges',
 'textmatches' => 'Corrèspondances dedens lo tèxto de les pâges',
@@ -1380,7 +1380,7 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'search-interwiki-default' => 'Rèsultats dessus $1 :',
 'search-interwiki-more' => '(més)',
 'search-relatedarticle' => 'Aparentâ',
-'mwsuggest-disable' => 'Dèsactivar les idês AJAX',
+'mwsuggest-disable' => 'Dèsactivar les idês de rechèrche',
 'searcheverything-enable' => 'Rechèrchiér dedens tôs los èspâços de noms',
 'searchrelated' => 'aparentâ',
 'searchall' => 'tot',
@@ -1388,7 +1388,7 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'showingresultsnum' => "Vua de '''$3''' rèsultat{{PLURAL:$3||s}} dês lo numerô '''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Rèsultat '''$1'''|Rèsultats '''$1 - $2'''}} de '''$3''' por '''$4'''",
 'nonefound' => "'''Nota :''' solament quârques èspâços de noms sont rechèrchiês per dèfôt.
-Èprovâd en empleyent lo prèfixo ''all:'' por rechèrchiér dedens tot lo contegnu (les pâges de discussion, los modèlos, ... avouéc) ou ben empleyéd l’èspâço de noms volu coment prèfixo.",
+Èprovâd en empleyent lo prèfixo ''all:'' por rechèrchiér dedens tot lo contegnu (les pâges de discussion, los modèlos, et tot cen que vat avouéc) ou ben empleyéd l’èspâço de noms volu coment prèfixo.",
 'search-nonefound' => 'Y at gins de rèsultat que corrèspond a la rechèrche.',
 'powersearch' => 'Rechèrche avanciêe',
 'powersearch-legend' => 'Rechèrche avanciêe',
@@ -1396,8 +1396,8 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'powersearch-redir' => 'Listar les redirèccions',
 'powersearch-field' => 'Rechèrchiér',
 'powersearch-togglelabel' => 'Chouèsir :',
-'powersearch-toggleall' => 'Tot',
-'powersearch-togglenone' => 'Nion',
+'powersearch-toggleall' => 'Tôs',
+'powersearch-togglenone' => 'Pas yon',
 'search-external' => 'Rechèrche de defôr',
 'searchdisabled' => 'La rechèrche dessus {{SITENAME}} est dèsactivâye.
 Pendent cél temps, vos pouede fâre na rechèrche avouéc Google.
@@ -1405,7 +1405,7 @@ Notâd que lor endèxacion du contegnu de {{SITENAME}} pôt pas étre a jorn.',
 
 # Quickbar
 'qbsettings' => 'Bârra rapida',
-'qbsettings-none' => 'Niona',
+'qbsettings-none' => 'Pas yona',
 'qbsettings-fixedleft' => 'Fixa a gôche',
 'qbsettings-fixedright' => 'Fixa a drêta',
 'qbsettings-floatingleft' => 'Fllotenta a gôche',
@@ -1454,7 +1454,7 @@ Notâd que lor endèxacion du contegnu de {{SITENAME}} pôt pas étre a jorn.',
 'recentchangesdays' => 'Nombro de jorns a montrar dedens los dèrriérs changements :',
 'recentchangesdays-max' => 'Por lo més $1 jorn{{PLURAL:$1||s}}',
 'recentchangescount' => 'Nombro de changements a montrar per dèfôt :',
-'prefs-help-recentchangescount' => 'Los dèrriérs changements, los historicos de pâges et pués los jornals avouéc.',
+'prefs-help-recentchangescount' => 'Los dèrriérs changements, los historicos de pâges et los jornals avouéc.',
 'prefs-help-watchlist-token' => 'Rempléd ceti champ avouéc na cllâf secrèta et pués un flux RSS serat fêt por voutra lista de siuvu.
 Tôs celos que cognessont cela cllâf porront liére voutra lista de siuvu, chouèsésséd vêr na valor sècurisâye.
 Vê-que na valor fêta per hasârd que vos pouede empleyér : $1',
@@ -1497,9 +1497,9 @@ Cen pôt pas étre dèfêt.',
 'yourrealname' => 'Veré nom :',
 'yourlanguage' => 'Lengoua :',
 'yourvariant' => 'Varianta de la lengoua du contegnu :',
-'prefs-help-variant' => 'Voutra varianta ou ben ortografia prèferâye por fâre vêre les pâges de contegnu de ceti vouiqui.',
+'prefs-help-variant' => 'Voutra varianta voutron ortografia prèferâye por fâre vêre les pâges de contegnu de ceti vouiqui.',
 'yournick' => 'Signatura novèla :',
-'prefs-help-signature' => 'Los comentèros sur les pâges de discussion dêvont étre signês avouéc « <nowiki>~~~~</nowiki> » que serat convèrti per voutra signatura avouéc la dâta et hora.',
+'prefs-help-signature' => 'Los comentèros sur les pâges de discussion dêvont étre signês avouéc « <nowiki>~~~~</nowiki> » que serat convèrti per voutra signatura et un horodatâjo.',
 'badsig' => 'Signatura bruta pas justa.
 Controlâd les balises HTML.',
 'badsiglength' => 'Voutra signatura est trop longe.
@@ -1546,10 +1546,10 @@ Cel’enformacion serat publica.',
 'userrights-groupsmember-auto' => '{{GENDER:$2|Membro tacito|Membra tacita}} de :',
 'userrights-groups-help' => 'Vos pouede changiér les tropes a lesquintes est cet’utilisat{{GENDER:$1|or|rice}} :
 * Na câsa pouentâye vôt dére que l’utilisat{{GENDER:$1|or|rice}} sè trôve dedens cela tropa.
-* Na câsa pas pouentâye vôt dére que s’y trôve pas.
+* Na câsa pas pouentâye vôt dére qu’y sè trôve pas.
 * Na petiôt’ètêla (*) endique que vos pouede pas enlevar cela tropa setout que vos l’éd apondua ou ben l’una l’ôtra.',
 'userrights-reason' => 'Rêson :',
-'userrights-no-interwiki' => 'Vos avéd pas la pèrmission de changiér des drêts d’utilisator dessus d’ôtros vouiquis.',
+'userrights-no-interwiki' => 'Vos éd pas la pèrmission de changiér des drêts d’utilisator dessus d’ôtros vouiquis.',
 'userrights-nodatabase' => 'La bâsa de donâs « $1 » ègziste pas ou ben el est pas locala.',
 'userrights-nologin' => 'Vos vos dête [[Special:UserLogin|branchiér]] avouéc un compto d’administrator por balyér des drêts d’utilisator.',
 'userrights-notallowed' => 'Voutron compto at pas la pèrmission de balyér ou ben enlevar des drêts d’utilisator.',
@@ -1608,7 +1608,7 @@ Cel’enformacion serat publica.',
 'right-deletelogentry' => 'Suprimar et refâre n’entrâ spècifica du jornal',
 'right-deleterevision' => 'Suprimar et refâre na vèrsion spècifica d’una pâge',
 'right-deletedhistory' => 'Vêre les entrâs suprimâyes de l’historico sen lor tèxto',
-'right-deletedtext' => 'Vêre lo tèxto suprimâ et pués los changements entre les vèrsions suprimâyes',
+'right-deletedtext' => 'Vêre lo tèxto suprimâ et los changements entre les vèrsions suprimâyes',
 'right-browsearchive' => 'Rechèrchiér des pâges suprimâyes',
 'right-undelete' => 'Refâre na pâge',
 'right-suppressrevision' => 'Revêre et refâre les vèrsions cachiêes ux administrators',
@@ -1616,7 +1616,7 @@ Cel’enformacion serat publica.',
 'right-block' => 'Blocar en ècritura d’ôtros utilisators',
 'right-blockemail' => 'Empachiér un utilisator de mandar des mèssâjos',
 'right-hideuser' => 'Blocar un utilisator en cachient son nom u publico',
-'right-ipblock-exempt' => 'Èvitar los blocâjos d’adrèces IP, los blocâjos ôtomaticos et pués los blocâjos de plages d’adrèces IP',
+'right-ipblock-exempt' => 'Èvitar los blocâjos d’adrèces IP, los blocâjos ôtomaticos et los blocâjos de plages d’adrèces IP',
 'right-proxyunbannable' => 'Èvitar los blocâjos ôtomaticos de proxis',
 'right-unblockself' => 'Sè dèblocar lor-mémos',
 'right-protect' => 'Changiér lo nivél de protèccion et pués changiér les pâges protègiêes',
@@ -1719,142 +1719,142 @@ Cel’enformacion serat publica.',
 'rc_categories_any' => 'Totes',
 'rc-change-size-new' => '$1 octèt{{PLURAL:$1||s}} aprés changement',
 'newsectionsummary' => '/* $1 */ novèla sèccion',
-'rc-enhanced-expand' => 'Montrar los dètalys (at fôta de JavaScript)',
+'rc-enhanced-expand' => 'Montrar los dètalys (il at fôta de JavaScript)',
 'rc-enhanced-hide' => 'Cachiér los dètalys',
-'rc-old-title' => 'fêt avouéc lo titro « $1 »',
+'rc-old-title' => 'fêta avouéc lo titro originâl « $1 »',
 
 # Recent changes linked
-'recentchangeslinked' => 'Changements de les pâges liyês',
-'recentchangeslinked-feed' => 'Changements de les pâges liyês',
-'recentchangeslinked-toolbox' => 'Changements de les pâges liyês',
-'recentchangeslinked-title' => 'Changements de les pâges liyês a « $1 »',
-'recentchangeslinked-noresult' => 'Y at gins de changement sur les pâges liyês pendent lo temps chouèsi.',
-'recentchangeslinked-summary' => "Ceta pâge spèciâla montre los dèrriérs changements sur les pâges que sont liyês.
-Les pâges de voutra [[Special:Watchlist|lista de survelyence]] sont '''en grâs'''.",
+'recentchangeslinked' => 'Changements liyês',
+'recentchangeslinked-feed' => 'Changements liyês',
+'recentchangeslinked-toolbox' => 'Changements liyês',
+'recentchangeslinked-title' => 'Changements liyês a « $1 »',
+'recentchangeslinked-noresult' => 'Y at gins de changement sur les pâges liyêes pendent lo temps chouèsi.',
+'recentchangeslinked-summary' => "O est na lista des dèrriérs changements sur les pâges liyêes a na pâge spècifiâye (sur los membros d’una catègorie spècifiâye).
+Les pâges de voutra [[Special:Watchlist|lista de siuvu]] sont en '''grâs'''.",
 'recentchangeslinked-page' => 'Nom de la pâge :',
-'recentchangeslinked-to' => 'Fâre vêre los changements de les pâges qu’ont un lim de vers la pâge balyê pletout que l’envèrsa',
+'recentchangeslinked-to' => 'Montrar pletout los changements sur les pâges liyêes a la pâge balyêe',
 
 # Upload
 'upload' => 'Tèlèchargiér un fichiér',
 'uploadbtn' => 'Tèlèchargiér lo fichiér',
-'reuploaddesc' => 'Anular lo tèlèchargement et tornar u formulèro de tèlèchargement.',
+'reuploaddesc' => 'Anular lo tèlèchargement et pués tornar u formulèro de tèlèchargement',
 'upload-tryagain' => 'Mandar la dèscripcion du fichiér changiê',
-'uploadnologin' => 'Pas branchiê',
-'uploadnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê]] por tèlèchargiér des fichiérs sur lo sèrvor.',
-'upload_directory_missing' => 'Lo rèpèrtouèro de tèlèchargement ($1) est entrovâblo et pués at pas possu étre fêt per lo sèrvor vouèbe.',
-'upload_directory_read_only' => 'Lo rèpèrtouèro de tèlèchargement ($1) est pas accèssiblo en ècritura dês lo sèrvor vouèbe.',
-'uploaderror' => 'Èrror pendent lo tèlèchargement',
-'upload-recreate-warning' => "'''Atencion : un fichiér avouéc cél nom at étâ suprimâ ou ben dèplaciê.'''
-
-Los jornals de les suprèssions et des changements de nom de cela pâge sont montrâs ce-desot :",
+'uploadnologin' => 'Pas branchiê(ye)',
+'uploadnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê(ye)]] por povêr tèlèchargiér des fichiérs.',
+'upload_directory_missing' => 'Lo rèpèrtouèro de tèlèchargement ($1) est manquent et il at pas possu étre fêt per lo sèrvior Vouèbe.',
+'upload_directory_read_only' => 'Lo rèpèrtouèro de tèlèchargement ($1) est pas accèssiblo en ècritura dês lo sèrvior Vouèbe.',
+'uploaderror' => 'Fôta pendent lo tèlèchargement',
+'upload-recreate-warning' => "'''Atencion : un fichiér avouéc cél nom est étâ suprimâ ou ben dèplaciê.'''
+
+Por comoditât, lo jornal de les suprèssions et des dèplacements de cela pâge est balyê ce-desot :",
 'uploadtext' => "Empleyéd lo formulèro ce-desot por tèlèchargiér des fichiérs.
-Por vêre ou ben rechèrchiér des fichiérs tèlèchargiês dês devant, vêde la [[Special:FileList|lista des fichiérs tèlèchargiês]]. Los tèlèchargements sont asse-ben encartâs dedens lo [[Special:Log/upload|jornal des tèlèchargements]], et pués les suprèssions dedens lo [[Special:Log/delete|jornal de les suprèssions]].
+Por vêre ou ben rechèrchiér des fichiérs tèlèchargiês dês devant, vêde la [[Special:FileList|lista des fichiérs tèlèchargiês]]. Los (re-)tèlèchargements sont asse-ben encartâs dedens lo [[Special:Log/upload|jornal des tèlèchargements]], et les suprèssions dedens lo [[Special:Log/delete|jornal de les suprèssions]].
 
 Por entrebetar un fichiér dedens na pâge, empleyéd un lim de yona de cetes fôrmes :
 * '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Fichiér.jpg]]</nowiki></code>''' por empleyér la vèrsion en plêna largior du fichiér
 * '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Fichiér.png|200px|thumb|left|tèxto dèscriptif]]</nowiki></code>''' por empleyér na figura de 200 pixèls de lârjo dedens na bouèta a gôche avouéc « tèxto dèscriptif » coment dèscripcion
 * '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Fichiér.ogg]]</nowiki></code>''' por liyér tot drêt vers lo fichiér sen lo fâre vêre",
-'upload-permitted' => 'Formats de fichiérs ôtorisâs : $1.',
-'upload-preferred' => 'Formats de fichiérs prèferâs : $1.',
-'upload-prohibited' => 'Formats de fichiérs dèfendus : $1.',
-'uploadlog' => 'Jornal des tèlèchargements',
+'upload-permitted' => 'Tipos de fichiérs ôtorisâs : $1.',
+'upload-preferred' => 'Tipos de fichiérs prèferâs : $1.',
+'upload-prohibited' => 'Tipos de fichiérs dèfendus : $1.',
+'uploadlog' => 'jornal des tèlèchargements',
 'uploadlogpage' => 'Jornal des tèlèchargements',
-'uploadlogpagetext' => 'Vê-que la lista des dèrriérs fichiérs tèlèchargiês sur lo sèrvor.
-Vêde la [[Special:NewFiles|galerie des novéls fichiérs]] por una presentacion ples visuâla.',
+'uploadlogpagetext' => 'Vê-que na lista des dèrriérs fichiérs tèlèchargiês.
+Vêde la [[Special:NewFiles|galerie des novéls fichiérs]] por un apèrçu ples visuâl.',
 'filename' => 'Nom du fichiér',
 'filedesc' => 'Dèscripcion',
 'fileuploadsummary' => 'Dèscripcion :',
 'filereuploadsummary' => 'Changements du fichiér :',
-'filestatus' => 'Statut des drêts d’ôtor :',
+'filestatus' => 'Statut du drêt d’ôtor :',
 'filesource' => 'Sôrsa :',
 'uploadedfiles' => 'Fichiérs tèlèchargiês',
-'ignorewarning' => 'Ignorar l’avèrtissement et pués sôvar quand mémo lo fichiér',
-'ignorewarnings' => 'Ignorar tôs los avèrtissements',
-'minlength1' => 'Los noms de fichiér dêvont comprendre u muens yona lètra.',
-'illegalfilename' => 'Lo nom de fichiér « $1 » contint des caractèros dèfendus dens los titros de pâges.
-Lo volyéd renomar et pués lo tornar tèlèchargiér.',
-'filename-toolong' => 'Lo nom du fichiér pôt pas dèpassar 240 octèts.',
-'badfilename' => 'Lo fichiér at étâ renomâ en « $1 ».',
+'ignorewarning' => 'Ignorar la semonce et pués encartar lo fichiér dens tôs los câs',
+'ignorewarnings' => 'Ignorar totes les semonces',
+'minlength1' => 'Los noms de fichiérs dêvont contegnir por lo muens na lètra.',
+'illegalfilename' => 'Lo nom de fichiér « $1 » contint des caractèros dèfendus dedens los titros de pâges.
+Se vos plét, renomâd-lo et pués tornâd-lo tèlèchargiér.',
+'filename-toolong' => 'Los noms de fichiérs pôvont pas dèpassar 240 octèts.',
+'badfilename' => 'Lo nom du fichiér est étâ changiê en « $1 ».',
 'filetype-mime-mismatch' => 'L’èxtension du fichiér « .$1 » corrèspond pas u tipo MIME dècelâ du fichiér ($2).',
 'filetype-badmime' => 'Los fichiérs du tipo MIME « $1 » pôvont pas étre tèlèchargiês.',
-'filetype-bad-ie-mime' => 'Lo fichiér pôt pas étre tèlèchargiê perce que serêt dècelâ coment « $1 » per Internet Explorer, cen que corrèspond a un tipo de fichiér dèfendu perce que pôt-étre dangerox.',
-'filetype-unwanted-type' => "'''« .$1 »''' est un format de fichiér pas dèsirâ.
-{{PLURAL:$3|Lo tipo de fichiérs recomandâ est|Los tipos de fichiérs recomandâs sont}} $2.",
-'filetype-banned-type' => "'''« .$1 »''' {{PLURAL:$4|est pas un tipo de fichiérs ôtorisâ|sont pas des tipos de fichiérs ôtorisâs}}.
-{{PLURAL:$3|Lo tipo de fichiérs accèptâ est|Los tipos de fichiérs accèptâs sont}} $2.",
+'filetype-bad-ie-mime' => 'Lo fichiér pôt pas étre tèlèchargiê perce que serêt dècelâ coment « $1 » per Internet Explorer, cen que corrèspond a un tipo de fichiér dèfendu et pués pôt-étre dangerox.',
+'filetype-unwanted-type' => "'''« .$1 »''' est un tipo de fichiér pas volu.
+{{PLURAL:$3|Lo tipo de fichiér prèferâ est|Los tipos de fichiérs prèferâs sont}} $2.",
+'filetype-banned-type' => "'''« .$1 »''' {{PLURAL:$4|est pas un tipo de fichiér ôtorisâ|sont pas des tipos de fichiérs ôtorisâs}}.
+{{PLURAL:$3|Lo tipo de fichiér ôtorisâ est|Los tipos de fichiérs ôtorisâs sont}} $2.",
 'filetype-missing' => 'Lo fichiér at gins d’èxtension (coment « .jpg » per ègzemplo).',
-'empty-file' => 'Lo fichiér que vos éd somês ére vouedo.',
-'file-too-large' => 'Lo fichiér que vos éd somês ére trop grant.',
+'empty-file' => 'Lo fichiér que vos éd mandâ ére vouedo.',
+'file-too-large' => 'Lo fichiér que vos éd mandâ ére trop grôs.',
 'filename-tooshort' => 'Lo nom du fichiér est trop côrt.',
 'filetype-banned' => 'Cél tipo de fichiér est dèfendu.',
 'verification-error' => 'Cél fichiér pâsse pas lo contrôlo des fichiérs.',
-'hookaborted' => 'Lo changement que vos éd tâchiê de fâre at étâ arrètâ per un grèfon d’una èxtension.',
+'hookaborted' => 'Lo changement que vos éd èprovâ de fâre est étâ anulâ per n’èxtension.',
 'illegal-filename' => 'Lo nom du fichiér est pas ôtorisâ.',
 'overwrite' => 'Ècllafar un fichiér ègzistent est pas ôtorisâ.',
-'unknown-error' => 'Una èrror encognua est arrevâ.',
-'tmp-create-error' => 'Empossiblo de fâre lo fichiér temporèro.',
-'tmp-write-error' => 'Èrror d’ècritura du fichiér temporèro.',
-'large-file' => 'Los fichiérs tèlèchargiês devriant pas étre ples grant que $1 ;
+'unknown-error' => 'Na fôta encognua est arrevâ.',
+'tmp-create-error' => 'Y at pas moyen de fâre lo fichiér temporèro.',
+'tmp-write-error' => 'Fôta d’ècritura du fichiér temporèro.',
+'large-file' => 'O est recomandâ que los fichiérs seyont pas ples grôs que $1 ;
 cél fichiér fât $2.',
-'largefileserver' => 'La talye de cél fichiér est d’amont lo nivél lo ples hôt ôtorisâ.',
-'emptyfile' => 'Lo fichiér que vos voléd tèlèchargiér semble vouedo.
-Cen pôt étre diu a una èrror dedens lo nom du fichiér.
-Volyéd controlar que vos voléd franc tèlèchargiér cél fichiér.',
+'largefileserver' => 'Cél fichiér est ples grôs que lo sèrvior est configurâ por l’ôtorisar.',
+'emptyfile' => 'Lo fichiér que vos éd tèlèchargiê semble étre vouedo.
+Cen pôt étre diu a na fôta dedens lo nom du fichiér.
+Se vos plét, controlâd que vos voléd franc tèlèchargiér cél fichiér.',
 'windows-nonascii-filename' => 'Ceti vouiqui recognêt pas los noms de fichiérs avouéc des caractèros spèciâls.',
-'fileexists' => 'Un fichiér avouéc cél nom ègziste ja.
-Volyéd controlar <strong>[[:$1]]</strong>.
-Éte-vos de sûr de lo volêr changiér ? [[$1|thumb]]',
-'filepageexists' => 'La pâge de dèscripcion por cél fichiér at ja étâ fêta ique <strong>[[:$1]]</strong>, mas nion fichiér de cél nom ègziste ora.
+'fileexists' => 'Un fichiér avouéc cél nom ègziste ja, se vos plét controlâd <strong>[[:$1]]</strong> se vos éte pas de sûr de lo volêr changiér.
+[[$1|thumb]]',
+'filepageexists' => 'La pâge de dèscripcion por cél fichiér est ja étâye fêta ique <strong>[[:$1]]</strong>, mas nion fichiér avouéc cél nom ègziste ora.
 Lo rèsumâ que vos voléd buchiér aparêtrat pas sur la pâge de dèscripcion.
-Por cen fâre vos devréd changiér la pâge a la man.
+Por o fâre, vos la devréd changiér a la man.
 [[$1|thumb]]',
 'fileexists-extension' => 'Un fichiér avouéc un nom d’ense ègziste ja : [[$2|thumb]]
 * Nom du fichiér a tèlèchargiér : <strong>[[:$1]]</strong>
 * Nom du fichiér ègzistent : <strong>[[:$2]]</strong>
-Volyéd chouèsir un ôtro nom.',
-'fileexists-thumbnail-yes' => "Lo fichiér semble étre una émâge en talye rèduita ''(figura)''.
+Se vos plét, chouèsésséd-nen un ôtro.',
+'fileexists-thumbnail-yes' => "Lo fichiér semble étre n’émâge en talye rèduita ''(figura)''.
 [[$1|thumb]]
-Volyéd controlar lo fichiér <strong>[[:$1]]</strong>.
-Se lo fichiér controlâ est la méma émâge avouéc la talye originèla, y at pas fôta de tèlèchargiér una vèrsion rèduita.",
+Se vos plét, controlâd lo fichiér <strong>[[:$1]]</strong>.
+Se lo fichiér controlâ est la mém’émâge avouéc la talye originâla, y at pas fôta de tèlèchargiér na figura.",
 'file-thumbnail-no' => "Lo nom du fichiér comence per <strong>$1</strong>.
-O est possiblo que seye una vèrsion rèduita ''(figura)''.
-Se vos avéd lo fichiér en rèsolucion ples hôta, tèlèchargiéd-lo, ôtrament volyéd changiér son nom.",
+Semble étre n’émâge en talye rèduita ''(figura)''.
+Se vos éd cel’émâge en plêna rèsolucion, tèlèchargiéd-la, ôtrament changiéd lo sin nom, se vos plét.",
 'fileexists-forbidden' => 'Un fichiér avouéc cél nom ègziste ja et pôt pas étre ècllafâ.
-Se vos voléd adés tèlèchargiér voutron fichiér, volyéd tornar arriér et pués utilisar un novél nom.
+Se vos voléd adés tèlèchargiér voutron fichiér, se vos plét tornâd arriér et pués empleyéd un novél nom.
 [[File:$1|thumb|center|$1]]',
-'fileexists-shared-forbidden' => 'Un fichiér avouéc cél nom ègziste ja dens lo dèpôt de fichiérs partagiê.
-Se vos voléd adés tèlèchargiér voutron fichiér, volyéd tornar arriér et pués utilisar un novél nom.
+'fileexists-shared-forbidden' => 'Un fichiér avouéc cél nom ègziste ja dedens lo dèpôt de fichiérs partagiê.
+Se vos voléd adés tèlèchargiér voutron fichiér, se vos plét tornâd arriér et pués empleyéd un novél nom.
 [[File:$1|thumb|center|$1]]',
 'file-exists-duplicate' => 'Cél fichiér est un doblo {{PLURAL:$1|de ceti fichiér|de cetos fichiérs}} :',
-'file-deleted-duplicate' => 'Un fichiér pariér a ceti ([[:$1]]) at ja étâ suprimâ.
+'file-deleted-duplicate' => 'Un fichiér pariér a ceti ([[:$1]]) est ja étâ suprimâ.
 Vos devriâd controlar lo jornal de les suprèssions de cél fichiér devant que lo tornar tèlèchargiér.',
-'uploadwarning' => 'Atencion !',
-'uploadwarning-text' => 'Changiéd la dèscripcion du fichiér et pués tornâd èprovar.',
-'savefile' => 'Sôvar lo fichiér',
+'uploadwarning' => 'Semonce pendent lo tèlèchargement',
+'uploadwarning-text' => 'Se vos plét, changiéd la dèscripcion du fichiér ce-desot et pués tornâd èprovar.',
+'savefile' => 'Encartar lo fichiér',
 'uploadedimage' => 'at tèlèchargiê « [[$1]] »',
-'overwroteimage' => 'at tèlèchargiê una novèla vèrsion de « [[$1]] »',
-'uploaddisabled' => 'Tèlèchargements dèsactivâs',
-'copyuploaddisabled' => 'Tèlèchargement de fichiér per URL dèsactivâ.',
-'uploadfromurl-queued' => 'Voutron tèlèchargement at étâ betâ dens la fela d’atenta.',
-'uploaddisabledtext' => 'Lo tèlèchargement de fichiérs est dèsactivâ.',
-'php-uploaddisabledtext' => 'Lo tèlèchargement de fichiérs at étâ dèsactivâ dens PHP.
-Volyéd controlar lo chouèx de configuracion « file_uploads ».',
-'uploadscripted' => 'Cél fichiér contint de code HTML ou ben un scripte que porrêt étre entèrprètâ de façon fôssa per un navigator vouèbe.',
-'uploadvirus' => 'Cél fichiér contint un virus ! Por més de dètalys, vêde : $1',
-'uploadjava' => 'O est un fichiér ZIP que contint un fichiér Java .class.
-Lo tèlèchargement de fichiérs Java est pas ôtorisâ, perce que pôvont entrênar des rèstriccions de sècuritât.',
+'overwroteimage' => 'at tèlèchargiê na novèla vèrsion de « [[$1]] »',
+'uploaddisabled' => 'Tèlèchargements dèsactivâs.',
+'copyuploaddisabled' => 'Tèlèchargement per URL dèsactivâ.',
+'uploadfromurl-queued' => 'Voutron tèlèchargement est étâ betâ dedens la renche d’atenta.',
+'uploaddisabledtext' => 'Los tèlèchargements de fichiérs sont dèsactivâs.',
+'php-uploaddisabledtext' => 'Los tèlèchargements de fichiérs sont dèsactivâs dedens PHP.
+Se vos plét, controlâd la configuracion de « file_uploads ».',
+'uploadscripted' => 'Cél fichiér contint de code HTML ou ben un scripte que porrêt étre entèrprètâ a tôrt per un navigator Vouèbe.',
+'uploadvirus' => 'Cél fichiér contint un virus !
+Dètalys : $1',
+'uploadjava' => 'O est un fichiér ZIP que contint un fichiér Java « .class ».
+Lo tèlèchargement de fichiérs Java est pas ôtorisâ, pôvont èvitar des rèstriccions de sècuritât.',
 'upload-source' => 'Fichiér sôrsa',
 'sourcefilename' => 'Nom du fichiér sôrsa :',
 'sourceurl' => 'URL sôrsa :',
 'destfilename' => 'Nom du fichiér de dèstinacion :',
-'upload-maxfilesize' => 'Talye la ples granta du fichiér : $1',
+'upload-maxfilesize' => 'Talye maximon du fichiér : $1',
 'upload-description' => 'Dèscripcion du fichiér',
 'upload-options' => 'Chouèx de tèlèchargement',
 'watchthisupload' => 'Siuvre ceti fichiér',
-'filewasdeleted' => 'Un fichiér avouéc cél nom at ja étâ tèlèchargiê, et pués suprimâ.
+'filewasdeleted' => 'Un fichiér avouéc cél nom est ja étâ tèlèchargiê et pués suprimâ.
 Vos devriâd controlar lo $1 devant que lo tornar tèlèchargiér.',
-'filename-bad-prefix' => "Lo nom du fichiér que vos tèlèchargiéd comence per '''« $1 »''' qu’est tipicament un nom balyê ôtomaticament per los aparèlys-fotô numericos.
-Volyéd chouèsir un nom de fichiér dèscriptif.",
+'filename-bad-prefix' => "Lo nom du fichiér que vos tèlèchargiéd comence per '''« $1 »''' qu’est en g·ènèral un nom pas dèscriptif balyê ôtomaticament per los aparèlys-fotô numericos.
+Se vos plét, chouèsésséd un nom ples dèscriptif por voutron fichiér.",
 'filename-prefix-blacklist' => ' #<!-- lèssiéd ceta legne justo d’ense --> <pre>
 # La sintaxa est ceta :
 #  * Tot tèxto que siut un « # » tant qu’a la fin de la legne est un comentèro.
@@ -1871,143 +1871,143 @@ PICT # de totes sôrtes
  #</pre> <!-- lèssiéd ceta legne justo d’ense -->',
 'upload-success-subj' => 'Tèlèchargement fêt avouéc reusséta',
 'upload-success-msg' => 'Voutron tèlèchargement dês [$2] at reussi. Il est disponiblo ique : [[:{{ns:file}}:$1]]',
-'upload-failure-subj' => 'Problèmo de tèlèchargement',
+'upload-failure-subj' => 'Problèmo pendent lo tèlèchargement',
 'upload-failure-msg' => 'Y at avu un problèmo avouéc voutron tèlèchargement dês [$2] :
 
 $1',
-'upload-warning-subj' => 'Avèrtissement pendent lo tèlèchargement',
-'upload-warning-msg' => 'Un problèmo est arrevâ pendent voutron tèlèchargement dês [$2]. Vos pouede tornar u [[Special:Upload/stash/$1|formulèro de tèlèchargement]] por trovar la solucion.',
+'upload-warning-subj' => 'Semonce pendent lo tèlèchargement',
+'upload-warning-msg' => 'Y at avu un problèmo avouéc voutron tèlèchargement dês [$2]. Vos pouede tornar u [[Special:Upload/stash/$1|formulèro de tèlèchargement]] por trovar la sina solucion.',
 
 'upload-proto-error' => 'Protocolo fôx',
-'upload-proto-error-text' => 'Lo tèlèchargement a distance at fôta des URLs que començont per <code>http://</code> ou ben <code>ftp://</code>.',
-'upload-file-error' => 'Èrror de dedens',
-'upload-file-error-text' => 'Una èrror de dedens est arrevâ en volent fâre un fichiér temporèro sur lo sèrvor.
-Vos volyéd veriér vers un [[Special:ListUsers/sysop|administrator]].',
-'upload-misc-error' => 'Èrror encognua pendent lo tèlèchargement',
-'upload-misc-error-text' => 'Una èrror encognua est arrevâ pendent lo tèlèchargement.
-Volyéd controlar que l’URL est valida et accèssibla, et pués tornâd èprovar.
+'upload-proto-error-text' => 'Lo tèlèchargement a distance at fôta dURLs que començont per <code>http://</code> ou ben <code>ftp://</code>.',
+'upload-file-error' => 'Fôta de dedens',
+'upload-file-error-text' => 'Na fôta de dedens est arrevâye en volent fâre un fichiér temporèro sur lo sèrvior.
+Se vos plét, veriéd-vos vers un [[Special:ListUsers/sysop|administrator]].',
+'upload-misc-error' => 'Fôta encognua pendent lo tèlèchargement',
+'upload-misc-error-text' => 'Na fôta encognua est arrevâye pendent lo tèlèchargement.
+Se vos plét, controlâd que l’URL est justa et accèssibla, et pués tornâd èprovar.
 Se lo problèmo continue, veriéd-vos vers un [[Special:ListUsers/sysop|administrator]].',
 'upload-too-many-redirects' => 'L’URL contint trop de redirèccions',
 'upload-unknown-size' => 'Talye encognua',
-'upload-http-error' => 'Una èrror HTTP est arrevâ : $1',
-'upload-copy-upload-invalid-domain' => 'La copia des tèlèchargements est pas disponibla dês ceti domêno.',
+'upload-http-error' => 'Na fôta HTTP est arrevâye : $1',
+'upload-copy-upload-invalid-domain' => 'Los tèlèchargements de copies sont pas disponiblos dês ceti domêno.',
 
 # File backend
-'backend-fail-stream' => 'Empossiblo de liére lo fichiér $1.',
-'backend-fail-backup' => 'Empossiblo de sôvar lo fichiér $1.',
+'backend-fail-stream' => 'Y at pas moyen de tramandar lo fichiér « $1 ».',
+'backend-fail-backup' => 'Y at pas moyen d’encartar lo fichiér « $1 ».',
 'backend-fail-notexists' => 'Lo fichiér $1 ègziste pas.',
-'backend-fail-hashes' => 'Empossiblo d’avêr los chaplâjos du fichiér por comparèson.',
-'backend-fail-notsame' => 'Un fichiér difèrent ègziste ja por $1 .',
-'backend-fail-invalidpath' => '$1 est pas un chemin de stocâjo valido.',
-'backend-fail-delete' => 'Empossiblo de suprimar lo fichiér $1.',
-'backend-fail-describe' => 'Empossiblo de changiér les mètadonâs du fichiér « $1 ».',
-'backend-fail-alreadyexists' => 'Lo fichiér $1 ègziste ja.',
-'backend-fail-store' => 'Empossiblo de stocar lo fichiér $1 en $2.',
-'backend-fail-copy' => 'Empossiblo de copiyér lo fichiér $1 vers $2.',
-'backend-fail-move' => 'Empossiblo de dèplaciér lo fichiér $1 vers $2.',
-'backend-fail-opentemp' => 'Empossiblo d’uvrir lo fichiér temporèro.',
-'backend-fail-writetemp' => 'Empossiblo d’ècrire dedens lo fichiér temporèro.',
-'backend-fail-closetemp' => 'Empossiblo de cllôre lo fichiér temporèro.',
-'backend-fail-read' => 'Empossiblo de liére lo fichiér $1.',
-'backend-fail-create' => 'Empossiblo d’ècrire lo fichiér $1.',
-'backend-fail-maxsize' => 'Empossiblo d’ècrire lo fichiér « $1 » perce qu’il est ples grant que {{PLURAL:$2|yon octèt|$2 octèts}}.',
-'backend-fail-readonly' => "Ora lo sistèmo de stocâjo « $1 » est en lèctura solèta. La rêson balyêye est : « ''$2'' »",
+'backend-fail-hashes' => 'Y at pas moyen d’avêr los chaplâjos du fichiér por comparèson.',
+'backend-fail-notsame' => 'Un fichiér pas pariér ègziste ja a « $1 ».',
+'backend-fail-invalidpath' => '« $1 » est pas un chemin de stocâjo justo.',
+'backend-fail-delete' => 'Y at pas moyen de suprimar lo fichiér « $1 ».',
+'backend-fail-describe' => 'Y at pas moyen de changiér les mètadonâs du fichiér « $1 ».',
+'backend-fail-alreadyexists' => 'Lo fichiér « $1 » ègziste ja.',
+'backend-fail-store' => 'Y at pas moyen de stocar lo fichiér « $1 » dedens « $2 ».',
+'backend-fail-copy' => 'Y at pas moyen de copiyér lo fichiér « $1 » vers « $2 ».',
+'backend-fail-move' => 'Y at pas moyen de dèplaciér lo fichiér « $1 » vers « $2 ».',
+'backend-fail-opentemp' => 'Y at pas moyen d’uvrir lo fichiér temporèro.',
+'backend-fail-writetemp' => 'Y at pas moyen d’ècrire dedens lo fichiér temporèro.',
+'backend-fail-closetemp' => 'Y at pas moyen de cllôre lo fichiér temporèro.',
+'backend-fail-read' => 'Y at pas moyen de liére lo fichiér « $1 ».',
+'backend-fail-create' => 'Y at pas moyen d’ècrire lo fichiér « $1 ».',
+'backend-fail-maxsize' => 'Y at pas moyen d’ècrire lo fichiér « $1 » perce qu’il est ples grôs {{PLURAL:$2|qu’un octèt|que $2 octèts}}.',
+'backend-fail-readonly' => "Ora lo sistèmo de stocâjo « $1 » est justo en lèctura. La rêson balyêe est : « ''$2'' »",
 'backend-fail-synced' => 'Lo fichiér « $1 » est dens un ètat dèsordonâ dedens los sistèmos de stocâjo de dedens',
-'backend-fail-connect' => 'Empossiblo de sè branchiér u sistèmo de stocâjo « $1 ».',
+'backend-fail-connect' => 'Y at pas moyen de sè branchiér u sistèmo de stocâjo « $1 ».',
 'backend-fail-internal' => 'Na fôta encognua est arrevâye dedens lo sistèmo de stocâjo « $1 ».',
-'backend-fail-contenttype' => 'Empossiblo de dètèrmenar lo tipo de contegnu du fichiér a stocar en « $1 ».',
+'backend-fail-contenttype' => 'Y at pas moyen de dètèrmenar lo tipo de contegnu du fichiér a stocar dedens « $1 ».',
 'backend-fail-batchsize' => 'Lo sistèmo de stocâjo at balyê na pârt de $1 {{PLURAL:$1|opèracion|opèracions}} de fichiér ; la limita est $2 {{PLURAL:$2|opèracion|opèracions}}.',
-'backend-fail-usable' => 'Empossiblo de liére ou ben d’ècrire lo fichiér « $1 » a côsa de pèrmissions ensufisentes ou ben de rèpèrtouèros / conteniors manquents.',
+'backend-fail-usable' => 'Y at pas moyen de liére d’ècrire lo fichiér « $1 » a côsa de pèrmissions ensufisentes ou ben de rèpèrtouèros / conteniors manquents.',
 
 # File journal errors
-'filejournal-fail-dbconnect' => 'Empossiblo de sè branchiér a la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
-'filejournal-fail-dbquery' => 'Empossiblo de betar a jorn la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
+'filejournal-fail-dbconnect' => 'Y at pas moyen de sè branchiér a la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
+'filejournal-fail-dbquery' => 'Y at pas moyen de betar a jorn la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
 
 # Lock manager
-'lockmanager-notlocked' => 'Empossiblo de dèvèrrolyér « $1 » ; el est pas vèrrolyê.',
-'lockmanager-fail-closelock' => 'Empossiblo de cllôre lo fichiér de vèrroly por « $1 ».',
-'lockmanager-fail-deletelock' => 'Empossiblo de suprimar lo fichiér de vèrroly por « $1 ».',
-'lockmanager-fail-acquirelock' => 'Empossiblo d’avêr lo vèrroly por « $1 ».',
-'lockmanager-fail-openlock' => 'Empossiblo d’uvrir lo fichiér de vèrroly por « $1 ».',
-'lockmanager-fail-releaselock' => 'Empossiblo de relâchiér lo vèrroly por « $1 ».',
-'lockmanager-fail-db-bucket' => 'Empossiblo de sè veriér vers prod de bâses de balyês de vèrrolyâjo dedens lo godèt $1.',
-'lockmanager-fail-db-release' => 'Empossiblo de relâchiér los vèrrolys sur la bâsa de balyês $1.',
-'lockmanager-fail-svr-acquire' => 'Empossiblo d’avêr des vèrrolys sur lo sèrvior $1.',
-'lockmanager-fail-svr-release' => 'Empossiblo de relâchiér los vèrrolys sur lo sèrvior $1.',
+'lockmanager-notlocked' => 'Y at pas moyen de dèvèrrolyér « $1 » ; il est pas vèrrolyê.',
+'lockmanager-fail-closelock' => 'Y at pas moyen de cllôre lo fichiér de vèrroly por « $1 ».',
+'lockmanager-fail-deletelock' => 'Y at pas moyen de suprimar lo fichiér de vèrroly por « $1 ».',
+'lockmanager-fail-acquirelock' => 'Y at pas moyen d’avêr lo vèrroly por « $1 ».',
+'lockmanager-fail-openlock' => 'Y at pas moyen d’uvrir lo fichiér de vèrroly por « $1 ».',
+'lockmanager-fail-releaselock' => 'Y at pas moyen de relâchiér lo vèrroly por « $1 ».',
+'lockmanager-fail-db-bucket' => 'Y at pas moyen de sè veriér vers prod de bâses de donâs de vèrroly dedens la sèlye $1.',
+'lockmanager-fail-db-release' => 'Y at pas moyen de relâchiér los vèrrolys sur la bâsa de donâs $1.',
+'lockmanager-fail-svr-acquire' => 'Y at pas moyen d’avêr des vèrrolys sur lo sèrvior $1.',
+'lockmanager-fail-svr-release' => 'Y at pas moyen de relâchiér los vèrrolys sur lo sèrvior $1.',
 
 # ZipDirectoryReader
-'zip-file-open-error' => 'Una èrror est arrevâ pendent l’uvèrtura du fichiér ZIP por contrôlo.',
-'zip-wrong-format' => 'Lo fichiér spècefiâ est pas un fichiér ZIP.',
-'zip-bad' => 'Lo fichiér est un fichiér ZIP corrompu ou ben iliésiblo.
-Pôt pas étre controlâ tot drêt por la sècuritât.',
-'zip-unsupported' => 'Lo fichiér est un fichiér ZIP qu’utilise ZIP pas recognues per MediaWiki.
-Pôt pas étre controlâ tot drêt por la sècuritât.',
+'zip-file-open-error' => 'Na fôta est arrevâye pendent l’uvèrtura du fichiér por los contrôlos ZIP.',
+'zip-wrong-format' => 'Lo fichiér spècifiâ est pas un fichiér ZIP.',
+'zip-bad' => 'Lo fichiér est un fichiér ZIP corrompu ou ben ôtrament iliésiblo.
+Pôt pas étre controlâ coment fôt por la sècuritât.',
+'zip-unsupported' => 'Lo fichiér est un fichiér ZIP qu’emplèye des fonccionalitâts ZIP pas recognues per MediaWiki.
+Pôt pas étre controlâ coment fôt por la sècuritât.',
 
 # Special:UploadStash
-'uploadstash' => 'Cache d’importacion',
-'uploadstash-summary' => 'Ceta pâge balye accès ux fichiérs que sont importâs (ou ben en cors d’importacion), mas sont p’oncor publeyês dens lo vouiqui. Celos fichiérs sont p’oncor visiblos, solament por l’usanciér que los at importâs.',
-'uploadstash-clear' => 'Èfaciér los fichiérs en cache d’importacion',
-'uploadstash-nofiles' => 'Vos avéd gins de fichiér en cache d’importacion.',
-'uploadstash-badtoken' => 'L’ègzécucion de cela accion at pas reussia, pôt-étre perce que voutres enformacions de branchement ont èxpirâs. Tornâd èprovar.',
+'uploadstash' => 'Cacho de tèlèchargement',
+'uploadstash-summary' => 'Ceta pâge balye accès ux fichiérs que sont tèlèchargiês ou ben en côrs de tèlèchargement, mas sont p’oncor publeyês dedens lo vouiqui. Celos fichiérs sont p’oncor visiblos, solament por l’utilisator que los at tèlèchargiês.',
+'uploadstash-clear' => 'Èfaciér los fichiérs en cacho',
+'uploadstash-nofiles' => 'Vos éd gins de fichiér en cacho.',
+'uploadstash-badtoken' => 'L’ègzécucion de cel’accion at pas reussi, pôt-étre perce que voutros identifients de changement ont èxpirâ. Tornâd èprovar.',
 'uploadstash-errclear' => 'L’èfacement des fichiérs at pas reussi.',
 'uploadstash-refresh' => 'Rafrèchir la lista des fichiérs',
-'invalid-chunk-offset' => 'Comencement de bocon envalido',
+'invalid-chunk-offset' => 'Dèplacement de bocon pas justo',
 
 # img_auth script messages
 'img-auth-accessdenied' => 'Accès refusâ',
-'img-auth-nopathinfo' => 'PATH_INFO manquent.
-Voutron sèrvor est pas dèfeni por passar cela enformacion.
-Fonccione pôt-étre en CGI et pués recognêt pas img_auth.
+'img-auth-nopathinfo' => 'PATH_INFO manquenta.
+Voutron sèrvior est pas configurâ por passar cel’enformacion.
+Pôt étre bâsâye sur CGI et vêr pas recognetre « img_auth ».
 Vêde https://www.mediawiki.org/wiki/Manual:Image_Authorization.',
 'img-auth-notindir' => 'Lo chemin demandâ est pas lo rèpèrtouèro de tèlèchargement configurâ.',
-'img-auth-badtitle' => 'Empossiblo de construire un titro valido dês « $1 ».',
-'img-auth-nologinnWL' => 'Vos éte pas branchiê et pués « $1 » est pas dens la lista blanche.',
+'img-auth-badtitle' => 'Y at pas moyen de construire un titro justo dês « $1 ».',
+'img-auth-nologinnWL' => 'Vos éte pas branchiê et pués « $1 » est pas dedens la lista blanche.',
 'img-auth-nofile' => 'Lo fichiér « $1 » ègziste pas.',
-'img-auth-isdir' => 'Vos tâchiéd d’arrevar u rèpèrtouèro « $1 ».
+'img-auth-isdir' => 'Vos èprovâd d’arrevar u rèpèrtouèro « $1 ».
 Solament l’accès ux fichiérs est pèrmês.',
 'img-auth-streaming' => 'Lèctura en continu de « $1 ».',
-'img-auth-public' => 'La fonccion de img_auth.php est de fâre vêre des fichiérs d’un vouiqui privâ.
+'img-auth-public' => 'La fonccion de img_auth.php est de sortir des fichiérs d’un vouiqui privâ.
 Ceti vouiqui est configurâ coment un vouiqui publico.
-Por una sècuritât parfèta, img_auth.php est dèsactivâ.',
-'img-auth-noread' => 'L’usanciér at pas lo drêt en lèctura dessus « $1 ».',
-'img-auth-bad-query-string' => 'L’URL at una chêna de requéta envalida.',
+Por na sècuritât pèrfèta, img_auth.php est dèsactivâ.',
+'img-auth-noread' => 'L’utilisator at pas accès a la lèctura de « $1 ».',
+'img-auth-bad-query-string' => 'L’URL at na chêna de demanda pas justa.',
 
 # HTTP errors
-'http-invalid-url' => 'URL fôssa : $1',
+'http-invalid-url' => 'URL pas justa : $1',
 'http-invalid-scheme' => 'Les URLs avouéc lo plan « $1 » sont pas recognues.',
-'http-request-error' => 'Èrror encognua pendent l’èxpèdicion de la requéta.',
-'http-read-error' => 'Èrror de lèctura HTTP.',
-'http-timed-out' => 'La requéta HTTP at èxpirâ.',
-'http-curl-error' => 'Èrror pendent la rècupèracion de l’URL : $1',
-'http-host-unreachable' => 'URL pas juentâbla.',
-'http-bad-status' => 'Y at avu un problèmo pendent la requéta HTTP : $1 $2',
+'http-request-error' => 'La demanda HTTP at pas reussi a côsa d’una fôta encognua.',
+'http-read-error' => 'Fôta de lèctura HTTP.',
+'http-timed-out' => 'La demanda HTTP at èxpirâ.',
+'http-curl-error' => 'Fôta pendent la rècupèracion de l’URL : $1',
+'http-host-unreachable' => 'Y at pas moyen d’avengiér l’URL.',
+'http-bad-status' => 'Y at avu un problèmo pendent la demanda HTTP : $1 $2',
 
 # Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
-'upload-curl-error6' => 'URL pas juentâbla',
-'upload-curl-error6-text' => 'L’URL balyê pôt pas étre juenta.
-Volyéd controlar que l’URL est justa et que lo seto est en legne.',
-'upload-curl-error28' => 'Dèpassement du dèlê pendent lo tèlèchargement',
-'upload-curl-error28-text' => 'Lo seto at betâ trop grant-temps a rèpondre.
-Volyéd controlar que lo seto est en legne, atendre un pou et pués tornar èprovar.
-Vos pouede asse-ben tornar èprovar a una hora de muendra afluence.',
+'upload-curl-error6' => 'Y at pas moyen d’avengiér l’URL',
+'upload-curl-error6-text' => 'L’URL balyêe pôt pas étre avengiêe.
+Se vos plét, tornâd controlar que l’URL est justa et pués que lo seto est en legne.',
+'upload-curl-error28' => 'Dèlê dèpassâ pendent lo tèlèchargement',
+'upload-curl-error28-text' => 'Lo seto at tardâ bien a rèpondre.
+Se vos plét, controlâd que lo seto est en legne, atende un pou et pués tornâd èprovar.
+Vos pouede asse-ben èprovar a n’hora de muendra afluence.',
 
 'license' => 'Licence :',
 'license-header' => 'Licence',
-'nolicense' => 'Gins de licence chouèsia',
-'license-nopreview' => '(Prèvisualisacion pas disponibla)',
-'upload_source_url' => '  (una URL valida et accèssibla publicament)',
-'upload_source_file' => '  (un fichiér sur voutron ordenator)',
+'nolicense' => 'Pas yona chouèsia',
+'license-nopreview' => '(Apèrçu pas disponiblo)',
+'upload_source_url' => ' (n’URL justa et accèssibla publicament)',
+'upload_source_file' => ' (un fichiér sur voutron ordenator)',
 
 # Special:ListFiles
 'listfiles-summary' => 'Ceta pâge spèciâla montre tôs los fichiérs tèlèchargiês.
-Quand el est filtrâ per usanciér, solament los fichiérs que la vèrsion la ples novèla at étâ importâ per cél usanciér sont montrâs.',
-'listfiles_search_for' => 'Rechèrchiér un nom de mèdia :',
+Quand el est filtrâye per utilisator, solament los fichiérs que la vèrsion la ples novèla est étâye tèlèchargiêe per cél utilisator sont montrâs.',
+'listfiles_search_for' => 'Rechèrchiér un nom de fichiér mèdia :',
 'imgfile' => 'fichiér',
-'listfiles' => 'Lista des fichiérs',
+'listfiles' => 'Lista de fichiérs',
 'listfiles_thumb' => 'Figura',
 'listfiles_date' => 'Dâta',
 'listfiles_name' => 'Nom',
-'listfiles_user' => 'Usanciér',
+'listfiles_user' => 'Utilisator',
 'listfiles_size' => 'Talye',
 'listfiles_description' => 'Dèscripcion',
 'listfiles_count' => 'Vèrsions',
@@ -2015,77 +2015,82 @@ Quand el est filtrâ per usanciér, solament los fichiérs que la vèrsion la pl
 # File description page
 'file-anchor-link' => 'Fichiér',
 'filehist' => 'Historico du fichiér',
-'filehist-help' => 'Clicar sur na dâta et hora por vêre lo fichiér coment il ére a cél moment.',
+'filehist-help' => 'Clicar sur na dâta / hora por vêre lo fichiér coment il ére a cél moment.',
 'filehist-deleteall' => 'suprimar tot',
 'filehist-deleteone' => 'suprimar',
-'filehist-revert' => 'rètablir',
-'filehist-current' => 'ora',
-'filehist-datetime' => 'Dâta et hora',
+'filehist-revert' => 'rèvocar',
+'filehist-current' => 'd’ora',
+'filehist-datetime' => 'Dâta / hora',
 'filehist-thumb' => 'Figura',
-'filehist-thumbtext' => 'Figura por la vèrsion du $1',
-'filehist-nothumb' => 'Gins de figura',
-'filehist-user' => 'Usanciér',
+'filehist-thumbtext' => 'Figura por la vèrsion du $2 a $3',
+'filehist-nothumb' => 'Niona figura',
+'filehist-user' => 'Utilisator',
 'filehist-dimensions' => 'Dimensions',
 'filehist-filesize' => 'Talye du fichiér',
 'filehist-comment' => 'Comentèro',
 'filehist-missing' => 'Fichiér manquent',
 'imagelinks' => 'Usâjo du fichiér',
-'linkstoimage' => '{{PLURAL:$1|Ceta pâge utilise|Cetes $1 pâges utilisont}} ceti fichiér :',
-'linkstoimage-more' => 'Més de {{PLURAL:$1|yona pâge utilise|$1 pâges utilisont}} ceti fichiér.
-Ceta lista montre ren que {{PLURAL:$1|la premiére pâge qu’utilise|les $1 premiéres pâges qu’utilisont}} ceti fichiér.
-Una [[Special:WhatLinksHere/$2|lista complèta]] est disponibla.',
-'nolinkstoimage' => 'Niona pâge utilise ceti fichiér.',
+'linkstoimage' => '{{PLURAL:$1|Cela pâge-que emplèye|Celes $1 pâges-que emplèyont}} ceti fichiér :',
+'linkstoimage-more' => 'Més {{PLURAL:$1|d’una pâge emplèye|de $1 pâges emplèyont}} ceti fichiér.
+Ceta lista montre ren que {{PLURAL:$1|la premiére pâge qu’emplèye|les $1 premiéres pâges qu’emplèyont}} ceti fichiér.
+Na [[Special:WhatLinksHere/$2|lista complèta]] est disponibla.',
+'nolinkstoimage' => 'Niona pâge emplèye ceti fichiér.',
 'morelinkstoimage' => 'Vêde [[Special:WhatLinksHere/$1|més de lims]] de vers ceti fichiér.',
 'linkstoimage-redirect' => '$1 (redirèccion de fichiér) $2',
-'duplicatesoffile' => '{{PLURAL:$1|Ceti fichiér est un doblo|Cetos fichiérs sont des doblos}} de ceti ([[Special:FileDuplicateSearch/$2|més de dètalys]]) :',
-'sharedupload' => 'Ceti fichiér vint de $1 et pôt étre utilisâ per d’ôtros projèts.',
-'sharedupload-desc-there' => 'Ceti fichiér vint de $1 et pôt étre utilisâ per d’ôtros projèts.
-Vêde sa [$2 pâge de dèscripcion] por més d’enformacions.',
-'sharedupload-desc-here' => 'Ceti fichiér vint de $1 et pôt étre utilisâ per d’ôtros projèts.
-La dèscripcion de sa [$2 pâge de dèscripcion] est montrâ ce-desot.',
+'duplicatesoffile' => '{{PLURAL:$1|Cél fichiér-que est un doblo|Celos $1 fichiérs-que sont des doblos}} de ceti ([[Special:FileDuplicateSearch/$2|més de dètalys]]) :',
+'sharedupload' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.',
+'sharedupload-desc-there' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+Se vos plét, vêde la sina [$2 pâge de dèscripcion] por més d’enformacions.',
+'sharedupload-desc-here' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+La dèscripcion de la sina [$2 pâge de dèscripcion] est montrâye ce-desot.',
+'sharedupload-desc-edit' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+Pôt-étre vos voléd changiér la dèscripcion sur la sina [$2 pâge de dèscripcion].',
+'sharedupload-desc-create' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+Pôt-étre vos voléd changiér la dèscripcion sur la sina [$2 pâge de dèscripcion].',
 'filepage-nofile' => 'Nion fichiér de cél nom ègziste.',
 'filepage-nofile-link' => 'Nion fichiér de cél nom ègziste, mas vos en pouede [$1 tèlèchargiér yon].',
-'uploadnewversion-linktext' => 'Tèlèchargiér una novèla vèrsion de ceti fichiér',
-'shared-repo-from' => 'de $1',
+'uploadnewversion-linktext' => 'Tèlèchargiér na novèla vèrsion de ceti fichiér',
+'shared-repo-from' => 'de $1',
 'shared-repo' => 'un dèpôt partagiê',
 'filepage.css' => '/* Lo code CSS betâ ique est encllu dens la pâge de dèscripcion du fichiér, et pués dens los vouiquis cliants ètrangiérs. */',
+'upload-disallowed-here' => 'Vos pouede pas ècllafar ceti fichiér.',
 
 # File reversion
-'filerevert' => 'Rètablir $1',
-'filerevert-legend' => 'Rètablir lo fichiér',
-'filerevert-intro' => "Vos éte prèst a rètablir lo fichiér '''[[Media:$1|$1]]''' a la [$4 vèrsion du $2 a $3].",
+'filerevert' => 'Rèvocar $1',
+'filerevert-legend' => 'Rèvocar lo fichiér',
+'filerevert-intro' => "Vos éte prèst a rèvocar lo fichiér '''[[Media:$1|$1]]''' a la [$4 vèrsion du $2 a $3].",
 'filerevert-comment' => 'Rêson :',
-'filerevert-defaultcomment' => 'Vèrsion du $1 a $2 rètablia',
-'filerevert-submit' => 'Rètablir',
-'filerevert-success' => "'''[[Media:$1|$1]]''' at étâ rètabli a la [$4 vèrsion du $2 a $3].",
-'filerevert-badversion' => 'Y at gins de vèrsion ples vielye du fichiér avouéc la dâta balyê.',
+'filerevert-defaultcomment' => 'Rèvocâ a la vèrsion du $1 a $2',
+'filerevert-submit' => 'Rèvocar',
+'filerevert-success' => "'''[[Media:$1|$1]]''' est étâ rèvocâ a la [$4 vèrsion du $2 a $3].",
+'filerevert-badversion' => 'Y at gins de vèrsion locala devant de cél fichiér avouéc l’horodatâjo balyê.',
 
 # File deletion
 'filedelete' => 'Suprimar $1',
 'filedelete-legend' => 'Suprimar lo fichiér',
-'filedelete-intro' => "Vos éte prèst a suprimar '''[[Media:$1|$1]]''' et pués tot son historico.",
+'filedelete-intro' => "Vos éte prèst a suprimar lo fichiér '''[[Media:$1|$1]]''' et pués tot lo sin historico.",
 'filedelete-intro-old' => "Vos éte aprés suprimar la vèrsion de '''[[Media:$1|$1]]''' du [$4 $2 a $3].",
 'filedelete-comment' => 'Rêson :',
 'filedelete-submit' => 'Suprimar',
-'filedelete-success' => "'''$1''' at étâ suprimâ.",
-'filedelete-success-old' => "La vèrsion de '''[[Media:$1|$1]]''' du $2 a $3 at étâ suprimâ.",
+'filedelete-success' => "'''$1''' est étâ suprimâ.",
+'filedelete-success-old' => "La vèrsion de '''[[Media:$1|$1]]''' du $2 a $3 est étâye suprimâye.",
 'filedelete-nofile' => "'''$1''' ègziste pas.",
-'filedelete-nofile-old' => "Ègziste gins de vèrsion arch·ivâ de '''$1''' avouéc los atributs spècefiâs.",
+'filedelete-nofile-old' => "Ègziste gins de vèrsion arch·ivâye de '''$1''' avouéc los atributs spècifiâs.",
 'filedelete-otherreason' => 'Ôtra rêson / rêson de ples :',
 'filedelete-reason-otherlist' => 'Ôtra rêson',
 'filedelete-reason-dropdown' => '*Rêsons corentes de suprèssion
 ** Violacion du drêt d’ôtor
 ** Fichiér en doblo',
 'filedelete-edit-reasonlist' => 'Changiér les rêsons de suprèssion',
-'filedelete-maintenance' => 'La suprèssion et la rèstoracion de fichiérs est dèsactivâ temporèrament pendent la mantegnence.',
-'filedelete-maintenance-title' => 'Empossiblo de suprimar lo fichiér',
+'filedelete-maintenance' => 'La suprèssion et la rèstoracion de fichiérs est dèsactivâye por un moment pendent la mantegnence.',
+'filedelete-maintenance-title' => 'Y at pas moyen de suprimar lo fichiér',
 
 # MIME search
-'mimesearch' => 'Rechèrche per tipo de contegnu MIME',
-'mimesearch-summary' => "Ceta pâge vos pèrmèt de listar los fichiérs accèssiblos per ceti vouiqui d’aprés lor tipo de contegnu MIME.
-Entrâ : ''tipo de contegnu''/''sot-tipo'', per ègzemplo <code>image/jpeg</code>.",
+'mimesearch' => 'Rechèrche per tipo MIME',
+'mimesearch-summary' => "Ceta pâge pèrmèt de filtrar los fichiérs per lor tipo MIME.
+Entrâ : ''tipodecontegnu''/''sot-tipo'', per ègzemplo <code>image/jpeg</code>.",
 'mimetype' => 'Tipo MIME :',
-'download' => 'Tèlèchargiér',
+'download' => 'tèlèchargiér',
 
 # Unwatched pages
 'unwatchedpages' => 'Pâges pas siuvues',
@@ -2094,51 +2099,52 @@ Entrâ : ''tipo de contegnu''/''sot-tipo'', per ègzemplo <code>image/jpeg</code
 'listredirects' => 'Lista de les redirèccions',
 
 # Unused templates
-'unusedtemplates' => 'Modèlos inutilisâs',
-'unusedtemplatestext' => 'Ceta pâge liste totes les pâges de l’èspâço de noms « {{ns:template}} » que sont pas entrebetâyes dedens nionôtra pâge.
+'unusedtemplates' => 'Modèlos pas empleyês',
+'unusedtemplatestext' => 'Ceta pâge liste totes les pâges de l’èspâço de noms « {{ns:template}} » que sont pas entrebetâyes dedens nionôtra pâge.
 Oubliâd pas de controlar s’y at gins d’ôtro lim de vers los modèlos devant que los suprimar.',
 'unusedtemplateswlh' => 'ôtros lims',
 
 # Random page
-'randompage' => 'Pâge a l’hasârd',
-'randompage-nopages' => 'Y at gins de pâge dens {{PLURAL:$2|ceti èspâço|cetos èspâços}} de noms : $1.',
+'randompage' => 'Pâge per hasârd',
+'randompage-nopages' => 'Y at gins de pâge dedens {{PLURAL:$2|cet’èspâço|cetos èspâços}} de noms : $1.',
 
 # Random redirect
-'randomredirect' => 'Pâge de redirèccion a l’hasârd',
-'randomredirect-nopages' => 'Y at gins de pâge de redirèccion dens l’èspâço de noms « $1 ».',
+'randomredirect' => 'Redirèccion per hasârd',
+'randomredirect-nopages' => 'Y at gins de pâge de redirèccion dedens l’èspâço de noms « $1 ».',
 
 # Statistics
 'statistics' => 'Statistiques',
 'statistics-header-pages' => 'Statistiques de les pâges',
 'statistics-header-edits' => 'Statistiques des changements',
-'statistics-header-views' => 'Statistiques de les visualisacions',
-'statistics-header-users' => 'Statistiques ux usanciérs',
+'statistics-header-views' => 'Statistiques de les vues',
+'statistics-header-users' => 'Statistiques des utilisators',
 'statistics-header-hooks' => 'Ôtres statistiques',
 'statistics-articles' => 'Pâges de contegnu',
 'statistics-pages' => 'Pâges',
-'statistics-pages-desc' => 'Totes les pâges du vouiqui, les pâges de discussion, les redirèccions, ... avouéc',
+'statistics-pages-desc' => 'Totes les pâges du vouiqui, les pâges de discussion, les redirèccions, et tot cen que vat avouéc',
 'statistics-files' => 'Fichiérs tèlèchargiês',
 'statistics-edits' => 'Changements de pâges dês l’enstalacion de {{SITENAME}}',
 'statistics-edits-average' => 'Nombro moyen de changements per pâge',
-'statistics-views-total' => 'Soma de les visualisacions',
-'statistics-views-total-desc' => 'Les visualisacions de les pâges pas ègzistentes et de les pâges spèciâles sont pas encllues',
-'statistics-views-peredit' => 'Visualisacions per changement',
-'statistics-users' => '[[Special:ListUsers|Usanciérs]] encartâs',
-'statistics-users-active' => 'Usanciérs actifs',
-'statistics-users-active-desc' => 'Usanciérs qu’ont fêt u muens una accion pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}',
+'statistics-views-total' => 'Soma de les vues',
+'statistics-views-total-desc' => 'Les vues de les pâges pas ègzistentes et de les pâges spèciâles sont pas avouéc',
+'statistics-views-peredit' => 'Vues per changement',
+'statistics-users' => '[[Special:ListUsers|Utilisators]] encartâs',
+'statistics-users-active' => 'Utilisators actifs',
+'statistics-users-active-desc' => 'Utilisators qu’ont fêt por lo muens n’accion pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}',
 'statistics-mostpopular' => 'Pâges les ples vues',
 
 'disambiguations' => 'Pâges qu’ont des lims de vers des pâges d’homonimia',
 'disambiguationspage' => 'Template:Homonimia',
-'disambiguations-text' => "Cetes pâges ont u muens yon lim de vers na '''pâge d’homonimia'''.
+'disambiguations-text' => "Cetes pâges ont por lo muens un lim de vers na '''pâge d’homonimia'''.
 Devriant pletout pouentar vers na pâge que vat avouéc.<br />
-Na pâge est trètâye coment na pâge d’homonimia s’empleye un modèlo liyê a [[MediaWiki:Disambiguationspage]].",
+Na pâge est trètâye coment na pâge d’homonimia s’emplèye un modèlo liyê a [[MediaWiki:Disambiguationspage]].",
 
 'doubleredirects' => 'Redirèccions dobles',
-'doubleredirectstext' => 'Vê-que la lista de les pâges que redirijont vers des pâges que sont lor-mémes des pâges de redirèccion.
-Châque entrâ contint des lims de vers la premiére et la seconda redirèccion, et pués la premiére legne de tèxto de la seconda pâge, cen que balye habituèlament la « veré » pâge ciba, de vers laquinta la premiére redirèccion devrêt redirigiér.
-Les entrâs <del>barrâs</del> ont étâ solucionâs.',
-'double-redirect-fixed-move' => 'Cela redirèccion, que la ciba [[$1]] at étâ renomâ, mène ora vers [[$2]].',
+'doubleredirectstext' => 'Ceta pâge liste les pâges que redirijont vers d’ôtres pâges de redirèccion.
+Châque renche contint des lims de vers la premiére et la seconda redirèccion, et pués la ciba de la seconda redirèccion, cen que balye habituèlament la « veré » pâge ciba, de vers laquinta la premiére redirèccion devrêt pouentar.
+Les entrâs <del>barrâyes</del> sont étâyes solucionâyes.',
+'double-redirect-fixed-move' => '[[$1]] est étâye dèplaciêe.
+Ora redirige vers [[$2]].',
 'double-redirect-fixed-maintenance' => 'Correge la redirèccion dobla de [[$1]] vers [[$2]].',
 'double-redirect-fixer' => 'Corrèctor de redirèccion',
 
@@ -2148,11 +2154,11 @@ Les entrâs <del>barrâs</del> ont étâ solucionâs.',
 'brokenredirects-delete' => 'suprimar',
 
 'withoutinterwiki' => 'Pâges sen lims entèrlengoues',
-'withoutinterwiki-summary' => 'Cetes pâges ont gins de lim de vers d’ôtres lengoues :',
+'withoutinterwiki-summary' => 'Cetes pâges ont gins de lim de vers d’ôtres lengoues.',
 'withoutinterwiki-legend' => 'Prèfixo',
 'withoutinterwiki-submit' => 'Montrar',
 
-'fewestrevisions' => 'Pâges les muens changiês',
+'fewestrevisions' => 'Pâges avouéc lo muens de vèrsions',
 
 # Miscellaneous special pages
 'nbytes' => '$1 octèt{{PLURAL:$1||s}}',
@@ -2161,87 +2167,87 @@ Les entrâs <del>barrâs</del> ont étâ solucionâs.',
 'nlinks' => '$1 lim{{PLURAL:$1||s}}',
 'nmembers' => '$1 membro{{PLURAL:$1||s}}',
 'nrevisions' => '$1 vèrsion{{PLURAL:$1||s}}',
-'nviews' => '$1 visualisacion{{PLURAL:$1||s}}',
-'nimagelinks' => 'Utilisâ dessus $1 pâge{{PLURAL:$1||s}}',
-'ntransclusions' => 'utilisâ dessus $1 pâge{{PLURAL:$1||s}}',
+'nviews' => '$1 vu{{PLURAL:$1|a|es}}',
+'nimagelinks' => 'Empleyê dessus $1 pâge{{PLURAL:$1||s}}',
+'ntransclusions' => 'empleyê dessus $1 pâge{{PLURAL:$1||s}}',
 'specialpage-empty' => 'Y at gins de rèsultat a fâre vêre.',
 'lonelypages' => 'Pâges orfenes',
-'lonelypagestext' => 'Cetes pâges sont pas liyês ou ben encllues dês d’ôtres pâges de {{SITENAME}}.',
-'uncategorizedpages' => 'Pâges sen catègorie',
-'uncategorizedcategories' => 'Catègories sen catègorie',
-'uncategorizedimages' => 'Fichiérs sen catègorie',
-'uncategorizedtemplates' => 'Modèlos sen catègorie',
-'unusedcategories' => 'Catègories inutilisâs',
-'unusedimages' => 'Fichiérs inutilisâs',
-'popularpages' => 'Pâges les ples vues',
-'wantedcategories' => 'Catègories les ples demandâs',
+'lonelypagestext' => 'Cetes pâges sont ni pouentâyes ni entrebetâyes per d’ôtres pâges de {{SITENAME}}.',
+'uncategorizedpages' => 'Pâges sen catègories',
+'uncategorizedcategories' => 'Catègories sen catègories',
+'uncategorizedimages' => 'Fichiérs sen catègories',
+'uncategorizedtemplates' => 'Modèlos sen catègories',
+'unusedcategories' => 'Catègories pas empleyêes',
+'unusedimages' => 'Fichiérs pas empleyês',
+'popularpages' => 'Pâges populères',
+'wantedcategories' => 'Catègories demandâyes',
 'wantedpages' => 'Pâges demandâyes',
-'wantedpages-badtitle' => 'Titro envalido dens los rèsultats : $1',
+'wantedpages-badtitle' => 'Titro pas justo dedens l’ensemblo de rèsultats : $1',
 'wantedfiles' => 'Fichiérs demandâs',
-'wantedfiletext-cat' => 'Cetos fichiérs sont utilisâs, mas ègzistont pas. Los fichiérs de dèpôts a distance pôvont étre listâs mâlgrât qu’ègzistont. Tot celos fôx positifs seront <del>traciês</del>. Pués, les pâges qu’apondont des fichiérs qu’ègzistont pas sont rèpèrtoriyês dedens [[:$1]].',
-'wantedfiletext-nocat' => 'Cetos fichiérs sont utilisâs, mas ègzistont pas. Los fichiérs de dèpôts a distance pôvont étre listâs mâlgrât qu’ègzistont. Tot celos fôx positifs seront <del>traciês</del>.',
-'wantedtemplates' => 'Modèlos los ples demandâs',
-'mostlinked' => 'Pâges les ples liyês',
-'mostlinkedcategories' => 'Catègories les ples utilisâs',
-'mostlinkedtemplates' => 'Modèlos los ples utilisâs',
-'mostcategories' => 'Pâges qu’utilisont lo més de catègories',
-'mostimages' => 'Fichiérs los ples utilisâs',
+'wantedfiletext-cat' => 'Cetos fichiérs sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>. Et pués les pâges qu’apondont des fichiérs qu’ègzistont pas sont listâs dedens [[:$1]].',
+'wantedfiletext-nocat' => 'Cetos fichiérs sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>.',
+'wantedtemplates' => 'Modèlos demandâs',
+'mostlinked' => 'Pâges les ples liyêes',
+'mostlinkedcategories' => 'Catègories les ples liyêes',
+'mostlinkedtemplates' => 'Modèlos los ples liyês',
+'mostcategories' => 'Pâges avouéc lo més de catègories',
+'mostimages' => 'Fichiérs los ples liyês',
 'mostinterwikis' => 'Pâges avouéc lo més de lims entèrvouiquis',
-'mostrevisions' => 'Pâges les ples changiês',
+'mostrevisions' => 'Pâges avouéc lo més de vèrsions',
 'prefixindex' => 'Totes les pâges que començont per...',
 'prefixindex-namespace' => 'Totes les pâges avouéc prèfixo (èspâço de noms $1)',
 'shortpages' => 'Pâges côrtes',
 'longpages' => 'Pâges longes',
 'deadendpages' => 'Pâges en cul-de-sac',
-'deadendpagestext' => 'Cetes pâges ont gins de lim de vers d’ôtres pâges de {{SITENAME}}.',
-'protectedpages' => 'Pâges protègiês',
-'protectedpages-indef' => 'Solament les protèccions sen fin',
-'protectedpages-cascade' => 'Solament les protèccions en cascâda',
-'protectedpagestext' => 'Cetes pâges sont protègiês contre los changements et/ou lo changement de nom :',
-'protectedpagesempty' => 'Ora, niona pâge est protègiê avouéc celos paramètres.',
+'deadendpagestext' => 'Cetes pâges contegnont gins de lim de vers d’ôtres pâges de {{SITENAME}}.',
+'protectedpages' => 'Pâges protègiêes',
+'protectedpages-indef' => 'Ren que les protèccions sen fin',
+'protectedpages-cascade' => 'Ren que les protèccions en cascâda',
+'protectedpagestext' => 'Cetes pâges sont protègiêes contre los dèplacements los changements',
+'protectedpagesempty' => 'Ora niona pâge est protègiêe avouéc celos paramètros.',
 'protectedtitles' => 'Titros protègiês',
-'protectedtitlestext' => 'Cetos titros sont protègiês a la crèacion :',
-'protectedtitlesempty' => 'Ora, nion titro est protègiê avouéc celos paramètres.',
-'listusers' => 'Lista ux usanciérs',
-'listusers-editsonly' => 'Fâre vêre ren que los usanciérs qu’ont u muens yona contribucion',
-'listusers-creationsort' => 'Triyér per dâta de crèacion',
+'protectedtitlestext' => 'Cetos titros sont protègiês a la crèacion',
+'protectedtitlesempty' => 'Ora nion titro est protègiê avouéc celos paramètros.',
+'listusers' => 'Lista des utilisators',
+'listusers-editsonly' => 'Montrar ren que los utilisators avouéc des contribucions',
+'listusers-creationsort' => 'Betar per dâta de crèacion',
 'usereditcount' => '$1 changement{{PLURAL:$1||s}}',
 'usercreated' => 'Fêt{{GENDER:$3||a}} lo $1 a $2',
 'newpages' => 'Pâges novèles',
 'newpages-username' => 'Nom d’utilisator :',
-'ancientpages' => 'Pâges les muens dèrriérement changiês',
-'move' => 'Renomar',
-'movethispage' => 'Renomar ceta pâge',
-'unusedimagestext' => 'Cetos fichiérs ègzistont, mas sont pas encllus dens niona pâge.
-Volyéd notar que d’ôtros setos pôvont avêr un lim drêt de vers un fichiér, et donc qu’un fichiér pôt étre listâ ique pendent qu’il est en rèalitât utilisâ sur celos setos.',
-'unusedcategoriestext' => 'Cetes catègories ègzistont mas gins de pâge ou ben de catègorie les utilise.',
-'notargettitle' => 'Gins de ciba',
-'notargettext' => 'Vos éd pas spècefiâ una pâge ou ben un usanciér ciba sur laquinta / loquint vos souhètâd fâre cela accion.',
-'nopagetitle' => 'Gins de pâge ciba',
-'nopagetext' => 'La pâge ciba que vos éd spècefiâ ègziste pas.',
+'ancientpages' => 'Pâges les ples vielyes',
+'move' => 'Dèplaciér',
+'movethispage' => 'Dèplaciér ceta pâge',
+'unusedimagestext' => 'Cetos fichiérs ègzistont, mas sont pas entrebetâs dedens niona pâge.
+Se vos plét, notâd que d’ôtros setos Vouèbe pôvont avêr un lim de vers un fichiér avouéc n’URL drêta, donc un fichiér pôt adés étre listâ ique pendent qu’il est en usâjo actif.',
+'unusedcategoriestext' => 'Cetes catègories ègzistont, mas nion’ôtra pâge niona catègorie les emplèye.',
+'notargettitle' => 'Niona ciba',
+'notargettext' => 'Vos éd pas spècifiâ na pâge un utilisator ciba sur laquinta / loquint vos souhètâd fâre cel’accion.',
+'nopagetitle' => 'Niona pâge ciba d’ense',
+'nopagetext' => 'La pâge ciba que vos éd spècifiâye ègziste pas.',
 'pager-newer-n' => '{{PLURAL:$1|ples novèla|$1 ples novèles}}',
 'pager-older-n' => '{{PLURAL:$1|ples vielye|$1 ples vielyes}}',
 'suppress' => 'Ôtar',
-'querypage-disabled' => 'Ceta pâge spèciâla est dèsactivâ por des rêsons de capacitât.',
+'querypage-disabled' => 'Ceta pâge spèciâla est dèsactivâye por des rêsons de capacitât.',
 
 # Book sources
 'booksources' => 'Ôvres de refèrence',
-'booksources-search-legend' => 'Rechèrchiér permié des ôvres de refèrence',
+'booksources-search-legend' => 'Rechèrchiér entre-mié les ôvres de refèrence',
 'booksources-isbn' => 'ISBN :',
 'booksources-go' => 'Listar',
-'booksources-text' => 'Vê-que la lista endicativa et pas èxcllusiva de lims de vers d’ôtros setos que vendont des lévros nôfs et d’ocasion et sur losquints vos troveréd pôt-étre des enformacions sur les ôvres que vos chèrchiéd :',
-'booksources-invalid-isbn' => 'L’ISBN balyê semble pas étre valido ; controlâd se vos éd fêt una èrror en copiyent la sôrsa originâla.',
+'booksources-text' => 'Vê-que na lista de lims de vers d’ôtros setos que vendont des lévros nôfs et d’ocasion, et pués pôvont avêr des enformacions de ples sur les ôvres que vos chèrchiéd :',
+'booksources-invalid-isbn' => 'L’ISBN balyê semble pas étre justo ; controlâd se vos éd fêt na fôta en copiyent la sôrsa originâla.',
 
 # Special:Log
 'specialloguserlabel' => 'Ôtor :',
-'speciallogtitlelabel' => 'Ciba (titro ou ben usanciér) :',
+'speciallogtitlelabel' => 'Ciba (titro ou ben utilisator) :',
 'log' => 'Jornals',
 'all-logs-page' => 'Tôs los jornals publicos',
-'alllogstext' => 'Visualisacion combinâ de tôs los jornals disponiblos dessus {{SITENAME}}.
-Vos pouede rètrendre la vua en chouèséssent un tipo de jornal, un nom d’usanciér (sensiblo a la câssa) ou ben una pâge afèctâ (sensibla a la câssa avouéc).',
-'logempty' => 'Nion èlèment d’ense at étâ trovâ dens lo jornal.',
-'log-title-wildcard' => 'Chèrchiér permié los titros que començont per ceti tèxto',
-'showhideselectedlogentries' => 'Fâre vêre / cachiér les entrâs de jornal chouèsies',
+'alllogstext' => 'Vua combinâye de tôs los jornals disponiblos dessus {{SITENAME}}.
+Vos pouede rètrendre la vua en chouèséssent un tipo de jornal, lo nom d’utilisator (sensiblo a la câssa) la pâge regardâye (sensibla a la câssa avouéc).',
+'logempty' => 'Niona piéce que corrèspond dedens lo jornal.',
+'log-title-wildcard' => 'Chèrchiér entre-mié los titros que començont per cél tèxto',
+'showhideselectedlogentries' => 'Montrar / cachiér les entrâs de jornal chouèsies',
 
 # Special:AllPages
 'allpages' => 'Totes les pâges',
@@ -2251,32 +2257,34 @@ Vos pouede rètrendre la vua en chouèséssent un tipo de jornal, un nom d’usa
 'allpagesfrom' => 'Fâre vêre les pâges dês :',
 'allpagesto' => 'Fâre vêre les pâges tant qu’a :',
 'allarticles' => 'Totes les pâges',
-'allinnamespace' => 'Totes les pâges (dens l’èspâço de noms « $1 »)',
+'allinnamespace' => 'Totes les pâges (dedens l’èspâço de noms « $1 »)',
 'allnotinnamespace' => 'Totes les pâges (en defôr de l’èspâço de noms « $1 »)',
 'allpagesprev' => 'Devant',
 'allpagesnext' => 'Aprés',
 'allpagessubmit' => 'Listar',
 'allpagesprefix' => 'Fâre vêre les pâges que començont per lo prèfixo :',
-'allpagesbadtitle' => 'Lo titro de pâge balyê est fôx ou ben il at un prèfixo entèrlengoua ou entèrvouiqui resèrvâ.
-Contint sûrement yon ou ben un mouél de caractèros que pôvont pas étre utilisâs dens los titros.',
+'allpagesbadtitle' => 'Lo titro de la pâge balyêe est pas justo ou ben il at un prèfixo entèrlengoua ou entèrvouiqui resèrvâ.
+Contint de sûr yon ou ben un mouél de caractèros que pôvont pas étre empleyês dedens los titros.',
 'allpages-bad-ns' => '{{SITENAME}} at gins d’èspâço de noms « $1 ».',
 'allpages-hide-redirects' => 'Cachiér les redirèccions',
 
 # SpecialCachedPage
-'cachedspecial-refresh-now' => 'Vêre lo ples novél.',
+'cachedspecial-viewing-cached-ttl' => 'Vos vêde na vèrsion betâye en cacho de cela pâge, que pôt étre vielye por lo més $1.',
+'cachedspecial-viewing-cached-ts' => 'Vos vêde na vèrsion betâye en cacho de cela pâge, que porrêt pas étre tot a fêt a jorn.',
+'cachedspecial-refresh-now' => 'Vêre la ples novèla.',
 
 # Special:Categories
 'categories' => 'Catègories',
-'categoriespagetext' => '{{PLURAL:$1|Ceta catègorie contint|Cetes catègories contegnont}} des pâges ou ben des fichiérs mèdia.
-Les [[Special:UnusedCategories|catègories inutilisâs]] sont pas montrâs ique.
-Vêde asse-ben les [[Special:WantedCategories|catègories les ples demandâs]].',
+'categoriespagetext' => '{{PLURAL:$1|Ceta catègorie contint|Cetes catègories contegnont}} des pâges des fichiérs mèdia.
+Les [[Special:UnusedCategories|catègories pas empleyêes]] sont pas montrâyes ique.
+Vêde asse-ben les [[Special:WantedCategories|catègories demandâyes]].',
 'categoriesfrom' => 'Fâre vêre les catègories dês :',
-'special-categories-sort-count' => 'tri per nombro d’èlèments',
+'special-categories-sort-count' => 'tri per nombro de piéces',
 'special-categories-sort-abc' => 'tri alfabètico',
 
 # Special:DeletedContributions
-'deletedcontributions' => 'Contribucions suprimâs',
-'deletedcontributions-title' => 'Contribucions suprimâs',
+'deletedcontributions' => 'Contribucions suprimâyes',
+'deletedcontributions-title' => 'Contribucions suprimâyes',
 'sp-deletedcontributions-contribs' => 'contribucions',
 
 # Special:LinkSearch
@@ -2284,133 +2292,133 @@ Vêde asse-ben les [[Special:WantedCategories|catègories les ples demandâs]].'
 'linksearch-pat' => 'Modèlo de rechèrche :',
 'linksearch-ns' => 'Èspâço de noms :',
 'linksearch-ok' => 'Rechèrchiér',
-'linksearch-text' => 'Des caractèros j·oquères coment « *.wikipedia.org » pôvont étre utilisâs.
-Ils ont fôta d’u muens un domêno de nivél supèrior, per ègzemplo « *.org ».<br />
-Protocolos recognus : <code>$1</code> (apondéd gins de cetos dedens voutra rechèrche).',
+'linksearch-text' => 'Des caractèros j·oquères coment « *.wikipedia.org » pôvont étre empleyês.
+Ils ont fôta de por lo muens un domêno de nivél de dessus, per ègzemplo « *.org ».<br />
+{{PLURAL:$2|Protocolo recognu|Protocolos recognus}} : <code>$1</code> (http:// per dèfôt se nion protocolo est spècifiâ).',
 'linksearch-line' => '$1 est liyê dês $2',
-'linksearch-error' => 'Los caractèros j·oquères pôvont étre utilisâs ren qu’u comencement du nom de domêno de l’hôto.',
+'linksearch-error' => 'Los caractèros j·oquères pôvont étre empleyês ren qu’u comencement du nom de domêno de l’hôto.',
 
 # Special:ListUsers
 'listusersfrom' => 'Fâre vêre los utilisators dês :',
-'listusers-submit' => 'Montrar',
-'listusers-noresult' => 'Gins d’usanciér trovâ.',
-'listusers-blocked' => '(blocâ)',
+'listusers-submit' => 'Listar',
+'listusers-noresult' => 'Nion utilisator trovâ.',
+'listusers-blocked' => '(blocâ{{GENDER:$1||ye|(ye)}})',
 
 # Special:ActiveUsers
-'activeusers' => 'Lista ux usanciérs actifs',
-'activeusers-intro' => 'O est una lista ux usanciérs qu’ont ègzèrciê una activitât quinta que seye pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|novél changement|novéls changements}} dens {{PLURAL:$3|lo jorn passâ|los $3 jorns passâs}}',
+'activeusers' => 'Lista des utilisators actifs',
+'activeusers-intro' => 'O est na lista des utilisators qu’ont ègzèrciê n’activitât la 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 bots',
+'activeusers-hidebots' => 'Cachiér los robots',
 'activeusers-hidesysops' => 'Cachiér los administrators',
-'activeusers-noresult' => 'Gins d’usanciér trovâ.',
+'activeusers-noresult' => 'Nion utilisator trovâ.',
 
 # Special:ListGroupRights
-'listgrouprights' => 'Drêts a les tropes d’usanciérs',
-'listgrouprights-summary' => 'Ceta pâge contint una lista a les tropes dèfenies sur ceti vouiqui et pués los drêts d’accès que lor sont associyês.
-Y pôt avêr [[{{MediaWiki:Listgrouprights-helppage}}|més d’enformacions]] sur los drêts particuliérs.',
+'listgrouprights' => 'Drêts de les tropes d’utilisators',
+'listgrouprights-summary' => 'Vê-que na lista de les tropes d’utilisators dèfenies sur ceti vouiqui et pués los sins drêts d’accès.
+Y pôt avêr [[{{MediaWiki:Listgrouprights-helppage}}|més d’enformacions]] sur los drêts endividuèls.',
 'listgrouprights-key' => '* <span class="listgrouprights-granted">Drêt balyê</span>
-* <span class="listgrouprights-revoked">Drêt rèvocâ</span>',
+* <span class="listgrouprights-revoked">Drêt cassâ</span>',
 'listgrouprights-group' => 'Tropa',
-'listgrouprights-rights' => 'Drêts associyês',
-'listgrouprights-helppage' => 'Help:Drêts a les tropes',
-'listgrouprights-members' => '(lista ux membros)',
-'listgrouprights-addgroup' => 'Apondre des membros a {{PLURAL:$2|la tropa|les tropes}} : $1',
-'listgrouprights-removegroup' => 'Enlevar des membros de {{PLURAL:$2|la tropa|les tropes}} : $1',
-'listgrouprights-addgroup-all' => 'Apondre des membros a totes les tropes',
-'listgrouprights-removegroup-all' => 'Enlevar des membros de totes les tropes',
+'listgrouprights-rights' => 'Drêts',
+'listgrouprights-helppage' => 'Help:Drêts de les tropes',
+'listgrouprights-members' => '(lista des membros)',
+'listgrouprights-addgroup' => 'Apondre a {{PLURAL:$2|la tropa|les tropes}} : $1',
+'listgrouprights-removegroup' => 'Enlevar de {{PLURAL:$2|la tropa|les tropes}} : $1',
+'listgrouprights-addgroup-all' => 'Apondre a totes les tropes',
+'listgrouprights-removegroup-all' => 'Enlevar de totes les tropes',
 'listgrouprights-addgroup-self' => 'Sè pôt apondre {{PLURAL:$2|la tropa|les tropes}} a son prôpro compto : $1',
 'listgrouprights-removegroup-self' => 'Sè pôt enlevar {{PLURAL:$2|la tropa|les tropes}} de son prôpro compto : $1',
 'listgrouprights-addgroup-self-all' => 'Sè pôt apondre totes les tropes a son prôpro compto',
 'listgrouprights-removegroup-self-all' => 'Sè pôt enlevar totes les tropes de son prôpro compto',
 
 # E-mail user
-'mailnologin' => 'Gins d’adrèce d’èxpèdior',
-'mailnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê]] et avêr endicâ una adrèce èlèctronica valida dens voutres [[Special:Preferences|prèferences]] por povêr mandar des mèssâjos a d’ôtros usanciérs.',
+'mailnologin' => 'Nion’adrèce d’èxpèdior',
+'mailnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê]] et avêr spècifiâ n’adrèce èlèctronica justa dens voutres [[Special:Preferences|prèferences]] por povêr mandar des mèssâjos a d’ôtros utilisators.',
 'emailuser' => 'Lui mandar un mèssâjo',
 'emailuser-title-target' => 'Mandar un mèssâjo a cet’utilisat{{GENDER:$1|or|rice}}',
 'emailuser-title-notarget' => 'Mandar un mèssâjo a l’utilisator',
 'emailpage' => 'Mandar un mèssâjo a l’utilisator',
 'emailpagetext' => 'Vos pouede empleyér lo formulèro ce-desot por mandar un mèssâjo a cet’utilisat{{GENDER:$1|or|rice}}.
-L’adrèce èlèctronica que vos éd buchiêye dens voutres [[Special:Preferences|prèferences]] aparètrat dedens lo champ « Èxpèdior » de voutron mèssâjo ; d’ense, lo dèstinatèro vos porrat rèpondre tot drêt.',
-'usermailererror' => 'Èrror dens lo sujèt du mèssâjo :',
-'defemailsubject' => 'Mèssâjo de {{SITENAME}} de l’usanciér « $1 »',
-'usermaildisabled' => 'L’èxpèdicion de mèssâjos entre-mié usanciérs est dèsactivâ',
-'usermaildisabledtext' => 'Vos pouede pas mandar des mèssâjos a d’ôtros usanciérs sur ceti vouiqui',
-'noemailtitle' => 'Dèstinatèro sen adrèce èlèctronica',
-'noemailtext' => 'Ceti usanciér at pas spècefiâ una adrèce èlèctronica valida.',
-'nowikiemailtitle' => 'Gins de mèssageria èlèctronica ôtorisâ',
-'nowikiemailtext' => 'Ceti usanciér at chouèsi de pas recêvre de mèssâjo de la pârt d’ôtros usanciérs.',
-'emailnotarget' => 'Nom d’usanciér u dèstinatèro pas ègzistent ou ben envalido.',
-'emailtarget' => 'Buchiéd lo nom d’usanciér u dèstinatèro',
+L’adrèce èlèctronica que vos éd buchiêe dens voutres [[Special:Preferences|prèferences]] aparêtrat dedens lo champ « Èxpèdior » de voutron mèssâjo ; d’ense, lo dèstinatèro vos porrat rèpondre tot drêt.',
+'usermailererror' => 'Fôta dens la chousa du mèssâjo :',
+'defemailsubject' => 'Mèssâjo de {{SITENAME}} de l’utilisator « $1 »',
+'usermaildisabled' => 'L’èxpèdicion de mèssâjos entre utilisators est dèsactivâye',
+'usermaildisabledtext' => 'Vos pouede pas mandar de mèssâjos a d’ôtros utilisators sur ceti vouiqui',
+'noemailtitle' => 'Nion’adrèce èlèctronica',
+'noemailtext' => 'Cet’utilisator at pas spècifiâ n’adrèce èlèctronica justa.',
+'nowikiemailtitle' => 'Niona mèssageria èlèctronica ôtorisâye',
+'nowikiemailtext' => 'Cél utilisator at chouèsi de pas recêvre de mèssâjos de la pârt d’ôtros utilisators.',
+'emailnotarget' => 'Nom d’utilisator du dèstinatèro pas ègzistent pas justo.',
+'emailtarget' => 'Buchiéd lo nom d’utilisator du dèstinatèro',
 'emailusername' => 'Nom d’utilisator :',
-'emailusernamesubmit' => 'Sometre',
-'email-legend' => 'Mandar un mèssâjo a un ôtro usanciér de {{SITENAME}}',
+'emailusernamesubmit' => 'Mandar',
+'email-legend' => 'Mandar un mèssâjo a un ôtr’utilisator de {{SITENAME}}',
 'emailfrom' => 'De :',
-'emailto' => 'Dèstinatèro :',
-'emailsubject' => 'Sujèt :',
+'emailto' => 'A :',
+'emailsubject' => 'Chousa :',
 'emailmessage' => 'Mèssâjo :',
 'emailsend' => 'Mandar',
-'emailccme' => 'Mè mandar per mèssageria èlèctronica una copia de mon mèssâjo.',
+'emailccme' => 'Mè mandar per mèssageria èlèctronica na copia de mon mèssâjo.',
 'emailccsubject' => 'Copia de voutron mèssâjo a $1 : $2',
 'emailsent' => 'Mèssâjo mandâ',
-'emailsenttext' => 'Voutron mèssâjo at étâ mandâ per mèssageria èlèctronica.',
-'emailuserfooter' => 'Ceti mèssâjo at étâ mandâ per « $1 » a « $2 » per la fonccion « Lui mandar un mèssâjo » de {{SITENAME}}.',
+'emailsenttext' => 'Voutron mèssâjo est étâ mandâ per mèssageria èlèctronica.',
+'emailuserfooter' => 'Ceti mèssâjo est étâ mandâ per « $1 » a « $2 » per la fonccion « Lui mandar un mèssâjo » de {{SITENAME}}.',
 
 # User Messenger
-'usermessage-summary' => 'At lèssiê un mèssâjo sistèmo.',
+'usermessage-summary' => 'Il at lèssiê un mèssâjo sistèmo.',
 'usermessage-editor' => 'Mèssagiér du sistèmo',
 'usermessage-template' => 'MediaWiki:MèssâjoUtilisator',
 
 # Watchlist
-'watchlist' => 'Lista de survelyence',
-'mywatchlist' => 'Lista de survelyence',
+'watchlist' => 'Lista de siuvu',
+'mywatchlist' => 'Lista de siuvu',
 'watchlistfor2' => 'Por $1 $2',
-'nowatchlist' => 'Voutra lista de survelyence contint gins d’èlèment.',
-'watchlistanontext' => 'Vos volyéd $1 por vêre ou ben changiér les piéces de voutra lista de survelyence.',
+'nowatchlist' => 'Vos éd gins de piéce dedens voutra lista de siuvu.',
+'watchlistanontext' => 'Se vos plét, vos vos dête $1 por povêr vêre ou ben changiér les piéces de voutra lista de siuvu.',
 'watchnologin' => 'Pas branchiê',
-'watchnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê]] por changiér voutra lista de survelyence.',
-'addwatch' => 'Apondre a la lista de survelyence',
-'addedwatchtext' => 'La pâge « [[:$1]] » est étâye apondua a voutra [[Special:Watchlist|lista de survelyence]].
+'watchnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê(ye)]] por povêr changiér voutra lista de siuvu.',
+'addwatch' => 'Apondre a la lista de siuvu',
+'addedwatchtext' => 'La pâge « [[:$1]] » est étâye apondua a voutra [[Special:Watchlist|lista de siuvu]].
 Los changements que vegnont de ceta pâge et de la sina pâge de discussion y seront listâs.',
-'removewatch' => 'Enlevar de la lista de survelyence',
-'removedwatchtext' => 'La pâge « [[:$1]] » at étâ enlevâ de voutra [[Special:Watchlist|lista de survelyence]].',
+'removewatch' => 'Enlevar de la lista de siuvu',
+'removedwatchtext' => 'La pâge « [[:$1]] » est étâye enlevâye de voutra [[Special:Watchlist|lista de siuvu]].',
 'watch' => 'Siuvre',
 'watchthispage' => 'Siuvre ceta pâge',
 'unwatch' => 'Pas més siuvre',
 'unwatchthispage' => 'Pas més siuvre',
-'notanarticle' => 'Pas una pâge de contegnu',
-'notvisiblerev' => 'La vèrsion at étâ suprimâ',
-'watchnochange' => 'Nion des èlèments que vos siude at étâ changiê pendent lo temps montrâ.',
-'watchlist-details' => 'Voutra lista de survelyence contint $1 pâge{{PLURAL:$1||s}}, sen comptar les pâges de discussion.',
-'wlheader-enotif' => '* La notificacion per mèssageria èlèctronica est activâ.',
-'wlheader-showupdated' => "* Les pâges qu’ont étâ changiês dês voutra dèrriére visita sont montrâs en '''grâs'''.",
+'notanarticle' => 'O est pas na pâge de contegnu',
+'notvisiblerev' => 'La dèrriére vèrsion per un ôtr’utilisator est étâye suprimâye',
+'watchnochange' => 'Pas yona de les piéces que vos siude est étâye changiêe pendent lo temps fêt vêre.',
+'watchlist-details' => 'Y at $1 pâge{{PLURAL:$1||s}} dedens voutra lista de siuvu, sen comptar les pâges de discussion.',
+'wlheader-enotif' => '* La notificacion per mèssageria èlèctronica est activâye.',
+'wlheader-showupdated' => "* Les pâges que sont étâyes changiêes dês voutra dèrriére visita sont montrâyes en '''grâs'''.",
 'watchmethod-recent' => 'contrôlo des novéls changements por y trovar des pâges siuvues',
 'watchmethod-list' => 'contrôlo de les pâges siuvues por y trovar des novéls changements',
-'watchlistcontains' => 'Voutra lista de survelyence contint $1 pâge{{PLURAL:$1||s}}.',
-'iteminvalidname' => 'Problèmo avouéc l’èlèment « $1 » : lo nom est envalido.',
-'wlnote' => "Vê-que {{PLURAL:$1|lo dèrriér changement fêt|los '''$1''' dèrriérs changements fêts}} pendent {{PLURAL:$2|l’hora passâ|les '''$2''' hores passâs}}, dês $3, $4.",
+'watchlistcontains' => 'Voutra lista de siuvu contint $1 pâge{{PLURAL:$1||s}}.',
+'iteminvalidname' => 'Problèmo avouéc la piéce « $1 », nom pas justo...',
+'wlnote' => "Vê-que {{PLURAL:$1|lo dèrriér changement fêt|los '''$1''' dèrriérs changements fêts}} pendent {{PLURAL:$2|l’hora passâye|les '''$2''' hores passâyes}}, dês $3 a $4.",
 'wlshowlast' => 'Montrar les $1 hores passâyes, los $2 jorns passâs ou ben $3',
-'watchlist-options' => 'Chouèx de la lista de survelyence',
+'watchlist-options' => 'Chouèx de la lista de siuvu',
 
 # Displayed when you click the "watch" button and it is in the process of watching
-'watching' => 'Survelyence...',
-'unwatching' => 'Fin de la survelyence...',
-'watcherrortext' => 'Una èrror est arrevâ pendent lo changement des paramètres de voutra lista de survelyence por « $1 ».',
+'watching' => 'Siuvu...',
+'unwatching' => 'Fin du siuvu...',
+'watcherrortext' => 'Na fôta est arrevâye pendent lo changement de la configuracion de voutra lista de siuvu por « $1 ».',
 
 'enotif_mailer' => 'Sistèmo de notificacion per mèssageria èlèctronica de {{SITENAME}}',
-'enotif_reset' => 'Marcar totes les pâges coment visitâs',
-'enotif_impersonal_salutation' => 'Usanciér de {{SITENAME}}',
+'enotif_reset' => 'Marcar totes les pâges coment visitâyes',
+'enotif_impersonal_salutation' => 'Utilisator de {{SITENAME}}',
 'enotif_subject_deleted' => 'La pâge $1 dessus {{SITENAME}} est étâye suprimâye per {{GENDER:$2|$2}}',
 'enotif_subject_created' => 'La pâge $1 dessus {{SITENAME}} est étâye fêta per {{GENDER:$2|$2}}',
-'enotif_subject_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye renomâye per {{GENDER:$2|$2}}',
+'enotif_subject_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye dèplaciêe per {{GENDER:$2|$2}}',
 'enotif_subject_restored' => 'La pâge $1 dessus {{SITENAME}} est étâye refêta per {{GENDER:$2|$2}}',
-'enotif_subject_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêye per {{GENDER:$2|$2}}',
+'enotif_subject_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêe per {{GENDER:$2|$2}}',
 'enotif_body_intro_deleted' => 'La pâge $1 dessus {{SITENAME}} est étâye suprimâye lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3.',
 'enotif_body_intro_created' => 'La pâge $1 dessus {{SITENAME}} est étâye fêta lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
-'enotif_body_intro_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye renomâye lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
+'enotif_body_intro_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye dèplaciêe lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
 'enotif_body_intro_restored' => 'La pâge $1 dessus {{SITENAME}} est étâye refêta lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
-'enotif_body_intro_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêye lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
+'enotif_body_intro_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêe lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
 'enotif_lastvisited' => 'Vêde $1 por tôs los changements dês voutra dèrriére visita.',
 'enotif_lastdiff' => 'Vêde $1 por vêre cél changement.',
 'enotif_anon_editor' => 'utilisator anonimo $1',
@@ -4128,7 +4136,6 @@ Les émâges sont montrâs dens lor plêna rèsolucion, los ôtros fichiérs son
 'logentry-newusers-create' => 'Lo compto utilisator $1 est étâ fêt',
 'logentry-newusers-create2' => 'Lo compto utilisator $3 est étâ fêt per $1',
 'logentry-newusers-autocreate' => 'Lo compto $1 at étâ fêt ôtomaticament',
-'newuserlog-byemail' => 'contresegno mandâ per mèssageria èlèctronica',
 'logentry-rights-rights' => '$1 at changiê l’apartegnence a la tropa por « $3 » de $4 a $5',
 'logentry-rights-rights-legacy' => '$1 at changiê l’apartegnence a la tropa por « $3 »',
 'logentry-rights-autopromote' => '$1 est étâ nomâ ôtomaticament de $4 a $5',
index deadbed..4d0846f 100644 (file)
@@ -152,6 +152,7 @@ $messages = array(
 'newwindow' => '(wårt önj en nai waning ääm mååged)',
 'cancel' => 'Oufbreege',
 'moredotdotdot' => 'Mör ...',
+'morenotlisted' => 'Öödern, ei apfeerd ...',
 'mypage' => 'Sidj',
 'mytalk' => 'Diskusjuun',
 'anontalk' => 'Diskusjoonssid foon jüdeer IP',
@@ -185,6 +186,7 @@ $messages = array(
 'namespaces' => 'Noomerüme',
 'variants' => 'Fariante',
 
+'navigation-heading' => 'Nawigatsjuun',
 'errorpagetitle' => 'Fäägel',
 'returnto' => 'Tubääg tu jü side $1.',
 'tagline' => 'Üt {{SITENAME}}',
@@ -285,6 +287,10 @@ Sii jü [[Special:Version|Färsjoonssid]]',
 'youhavenewmessages' => 'Dü hääst $1 aw din diskusjoonssid ($2).',
 'newmessageslink' => 'naie tisinge',
 'newmessagesdifflink' => 'Leest änring',
+'youhavenewmessagesfromusers' => 'Dü heest $1 faan {{PLURAL:$3|en öödern brüker|$3 ööder brükern}} ($2).',
+'youhavenewmessagesmanyusers' => 'Dü heest $1 faan flook ööder brükern ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|ian nei nooracht|nei noorachten}}',
+'newmessagesdifflinkplural' => 'leetst {{PLURAL:$1|feranrang|feranrangen}}',
 'youhavenewmessagesmulti' => 'Dü hääst nai tisinge aw $1',
 'editsection' => 'Beårbe',
 'editsection-brackets' => '[$1]',
@@ -413,6 +419,7 @@ Di grünj faan di administraator as: „$3“.',
 'invalidtitle-knownnamespace' => 'Ferkiard auerskraft uun di nöömrüm „$2“ an tekst „$3“',
 'invalidtitle-unknownnamespace' => 'Ferkiard auerskraft uun di ünbekäänd nöömrüm „$1“ an tekst „$2“',
 'exception-nologin' => 'Ei uunmeldet',
+'exception-nologin-text' => 'Det könst dü bluas bewerke, wan dü uunmeldet beest.',
 
 # Virus scanner
 'virus-badscanner' => "Hiinje konfigurasjoon: ünbekånde fiirusscanner: ''$1''",
@@ -424,12 +431,16 @@ Di grünj faan di administraator as: „$3“.',
 
 Dü koost {{SITENAME}} nü anonüüm widerbrüke, unti de wider uner diseelew unti en oudern brükernoome <span class='plainlinks'>[$1 önjmälde]</span>.
 Påås aw, dåt hu side nuch wise koone, dåt dü önjmälded bast, sülung dü ai dan browsercache lääsimååged heest.",
+'welcomeuser' => 'Welkimen, $1!',
+'welcomecreation-msg' => 'Din brükerkonto as iinracht wurden.
+Ferjid det ei, an aachte üüb din [[Special:Preferences|{{SITENAME}} iinstelangen]].',
 'yourname' => 'Brükernoome:',
 'yourpassword' => 'Pååsuurd:',
 'yourpasswordagain' => 'Schriw pååsuurd nuch iinjsen:',
-'remembermypassword' => 'Aw diheere komputer foon duur önjmälde (maksimool for {{PLURAL:$1|däi|deege}})',
+'remembermypassword' => 'Aw diheere komputer foon duur önjmälde (maksimool for $1 {{PLURAL:$1|däi|deege}})',
 'securelogin-stick-https' => 'Eefter önjmälding ma HTTPS ferbünen bliwe',
 'yourdomainname' => 'Din domain:',
+'password-change-forbidden' => 'Üüb detheer wiki könst dü nian paaswurden feranre.',
 'externaldberror' => 'Deer läit en fäägel bai jü äkstärn autentifisiiring for, unti dü möist din äkstärn brükerkonto äi aktualisiire.',
 'login' => 'Önjmälde',
 'nav-login-createaccount' => 'Önjmälde',
@@ -445,7 +456,7 @@ Påås aw, dåt hu side nuch wise koone, dåt dü önjmälded bast, sülung dü
 'gotaccount' => "Dü hääst ål en brükerkonto? '''$1'''.",
 'gotaccountlink' => 'Önjmälde',
 'userlogin-resetlink' => 'Heest dü din login dooten ferjiden?',
-'createaccountmail' => 'ouer E-mail',
+'createaccountmail' => 'E-mail tu det adres oner fersjüür mä en tufelag paaswurd',
 'createaccountreason' => 'Grün:',
 'badretype' => 'Da biise pååsuurde stime ai oueriinj.',
 'userexists' => 'Dideer brükernoome as ål ferjääwen.
@@ -519,6 +530,7 @@ Wees sü gödj än täif, bit dü wider ferseechst.',
 # E-mail sending
 'php-mail-error-unknown' => 'Ünbekäänd feeler mä det funktsjuun mail() faan PHP.',
 'user-mail-no-addy' => 'Köö niinj e-mail schake suner e-mail-adres.',
+'user-mail-no-body' => 'Dü wulst en e-mail saner tekst wechsjüür.',
 
 # Change password dialog
 'resetpass' => 'Pååsuurd änre',
@@ -575,6 +587,7 @@ Tidwis paasuurd: $2',
 'changeemail-oldemail' => 'Aktuel e-mail adres',
 'changeemail-newemail' => 'Nei e-mail adres',
 'changeemail-none' => '(niin)',
+'changeemail-password' => 'Din {{SITENAME}} paaswurd:',
 'changeemail-submit' => 'E-mail adres feranre',
 'changeemail-cancel' => 'Ufbreeg',
 
@@ -670,6 +683,10 @@ Dü koost dideere tiitel aw da ouder side [[Special:Search/{{PAGENAME}}|säke]],
 <span class="plainlinks">önj da deertuhiirende [{{fullurl:{{#special:Log}}|page={{FULLPAGENAMEE}}}} logböke säke] unti jüdeer sid [{{fullurl:{{FULLPAGENAME}}|action=edit}} beårbe]</span>.',
 'noarticletext-nopermission' => 'Üüb detdiar sidj stäänt noch niks, oober dü mutst diar uk niks iinskriiw.
 Dü könst diar üüb ööder sidjen efter [[Special:Search/{{PAGENAME}}|sjük]] of a <span class="plainlinks">[{{fullurl:{{#special:Log}}|page={{FULLPAGENAME}}}} logbuken uunluke].</span>',
+'missing-revision' => 'Det werjuun #$1 faan det sidj "{{PAGENAME}}" jaft at ei.
+
+Det komt diar miast faan, dat en ual ferwisang stregen wurden as.
+Dü könst det uun\'t [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} logbuk faan stregen sidjen] efterlees.',
 'userpage-userdoesnotexist' => "Det brükerkonto ''$1'' as ei diar.
 Wel dü detdiar sidj würelk maage/bewerke?",
 'userpage-userdoesnotexist-view' => 'Benjüterkonto "$1" bestoont ai.',
@@ -735,7 +752,7 @@ Wan dü heer wat iinskrafst, do beest dü diarmä iinferstenen an seekerst tu, d
 '''Auerdreeg nään frääm teksten an bilen saner ferloof!'''",
 'longpageerror' => "'''Error: Dan tekst as {{PLURAL:$1|ian kilobyte|$1 kilobytes}} lung, hi mut oober ei linger wees üs {{PLURAL:$2|ian kilobyte|$2 kilobytes}}.'''Hi koon ei ufspiikerd wurd.",
 'readonlywarning' => "'''PÅÅS AW: Jü dootenbånk wörd for unerhult spärd, sü dåt din änringe tutids ai spiikerd wårde koone.
-Wees sü gödj än sääkre di täkst lokool aw din kompjuuter än fersäk tu n lääsern tidpunkt, da änringe tu ouerdreegen.'''.
+Wees sü gödj än sääkre di täkst lokool aw din kompjuuter än fersäk tun lääsern tidpunkt, da änringe tu ouerdreegen.'''.
 
 Grün for jü späre: $1",
 'protectedpagewarning' => "'''Paase üüb: Detdiar sidj as speret wurden. Bluas administratooren kön det bewerke.'''
@@ -773,6 +790,15 @@ Jü wörd önjscheened sleeked.',
 'edit-already-exists' => 'Köö niinj nai sid mååge.
 Dåt bestöö ål.',
 'defaultmessagetext' => 'Standard tekst',
+'content-failed-to-parse' => "Parsing faan $2 för't model $1 ging skiaf: $3",
+'invalid-content-data' => 'Diar stäänt wat uun, wat diar ei hen hiart',
+'content-not-allowed-here' => '„$1“ mut ei skrewen wurd üüb sidj [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitekst',
+'content-model-text' => 'normool tekst',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Woorschauing: Jüdeer sid önjthålt tu fool apteele foon widluftie parserfunksjoone.
@@ -792,6 +818,7 @@ Deer {{PLURAL:$2|mötj ai mör ås 1 apteel|mönje ai mör ås $1 apteele}} wees
 'expansion-depth-exceeded-warning' => 'Detdiar sidj hää tuföl ütjwidjangen (expansion)',
 'parser-unstrip-loop-warning' => 'Diar as en jinsidjag ferwisang',
 'parser-unstrip-recursion-limit' => 'Tuföl jinsidjag ferwisangen bi $1',
+'converter-manual-rule-error' => "Bi't manuel reegel för't spriakferanrang lääpt wat skiaf.",
 
 # "Undo" feature
 'undo-success' => 'Detdiar feranrang koon turag nimen wurd. 
@@ -979,6 +1006,10 @@ A nawigatsjuun links saat ales weder turag üüb di ual stant.',
 'editundo' => 'tunintemååge',
 'diff-multi' => '({{PLURAL:$1|Ian wersjuun diartesken|$1 wersjuunen diartesken}} faan {{PLURAL:$2|ään brüker|$2 brükern}} {{PLURAL:$1|woort|wurd}} ei uunwiset)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Ian wersjuun diartesken|$1 wersjuunen diartesken}} faan muar üs $2 {{PLURAL:$2|brüker|brükern}} wurd ei uunwiset)',
+'difference-missing-revision' => "{{PLURAL:$2|Ian werjuun|$2 werjuunen}} faan di ferskeel ($1) {{PLURAL:$2|as|san}} ei fünjen wurden.
+
+Det komt diar miast faan, dat en ual ferwisang stregen wurden as.
+Dü könst det uun't [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} logbuk faan stregen sidjen] efterlees.",
 
 # Search results
 'searchresults' => 'Säkjresultoote',
@@ -1198,14 +1229,14 @@ Do san jo ual iinstelangen wech.',
 'group-sysop' => 'Administratooren',
 'group-bureaucrat' => 'Bürokraaten',
 'group-suppress' => 'Oversighter',
-'group-all' => '(aaltumaal)',
+'group-all' => '(Aaltumaal)',
 
-'group-user-member' => '{{GENDER:$1|brüker}}',
-'group-autoconfirmed-member' => '{{GENDER:$1|registriaret brüker}}',
-'group-bot-member' => '{{GENDER:$1|bot}}',
-'group-sysop-member' => '{{GENDER:$1|administraator}}',
-'group-bureaucrat-member' => '{{GENDER:$1|bürokraat}}',
-'group-suppress-member' => '{{GENDER:$1|oversighter}}',
+'group-user-member' => '{{GENDER:$1|Brüker}}',
+'group-autoconfirmed-member' => '{{GENDER:$1|Registriaret brüker}}',
+'group-bot-member' => '{{GENDER:$1|Bot}}',
+'group-sysop-member' => '{{GENDER:$1|Administraator}}',
+'group-bureaucrat-member' => '{{GENDER:$1|Bürokraat}}',
+'group-suppress-member' => '{{GENDER:$1|Oversighter}}',
 
 'grouppage-user' => '{{ns:project}}:Brükern',
 'grouppage-autoconfirmed' => '{{ns:project}}:Registriaret brükern',
@@ -1421,7 +1452,7 @@ Det beskriiwang faan't [$2 beskriiwangssidj] woort oner uunwiset.",
 'emailuser' => 'E-mail tu dideere brüker',
 
 # Watchlist
-'watchlist' => 'Eefterkiikliste',
+'watchlist' => "Uun't uug behual",
 'mywatchlist' => "Uun't uug behual",
 'watchlistfor2' => 'Foon $1 $2',
 'addedwatchtext' => "Det sidj „[[:$1]]“ wel dü [[Special:Watchlist|uun't uug behual]].
index 8cac7b2..15a1cfd 100644 (file)
@@ -1691,9 +1691,6 @@ Se il file al è stât cambiât rispiet al so stât origjinâl, cualchi informaz
 'htmlform-submit' => 'Invie',
 'htmlform-selectorother-other' => 'Altris',
 
-# New logging system
-'newuserlog-byemail' => 'peraule clâf mandade par pueste eletroniche',
-
 # Search suggestions
 'searchsuggest-search' => 'Ricercje',
 'searchsuggest-containing' => 'che al à dentri...',
index 994b15b..c974809 100644 (file)
@@ -2355,7 +2355,6 @@ Wolle jo de side wier op 'e nij skriuwe?",
 # New logging system
 'revdelete-restricted' => 'hat beheinings oplein oan behearders',
 'revdelete-unrestricted' => 'hat beheinings foar behearders goedmakke',
-'newuserlog-byemail' => 'wachtwurd is ferstjoerd oer e-mail',
 'rightsnone' => '(gjin)',
 
 );
index ba39b45..d0f4166 100644 (file)
@@ -496,6 +496,7 @@ Tabhair faoi deara go taispeáinfear roinnt leathanaigh mar atá tú logáilte i
 'createaccount' => 'Cruthaigh cuntas nua',
 'gotaccount' => "An bhfuil cuntas agat cheana féin? '''$1'''.",
 'gotaccountlink' => 'Logáil isteach',
+'userlogin-resetlink' => 'Sonraí logála isteach dearmadta agat?',
 'createaccountmail' => 'le ríomhphost',
 'createaccountreason' => 'Fáth:',
 'badretype' => "D'iontráil tú dhá fhocal faire difriúla.",
@@ -782,17 +783,22 @@ Treoir: (rth) = difríocht ón leagan reatha, (rmh) = difríocht ón leagan roim
 'notextmatches' => 'Ní bhfuarthas an téacs ar leathanach ar bith',
 'prevn' => 'na {{PLURAL:$1|$1}} cinn roimhe seo',
 'nextn' => 'an {{PLURAL:$1|$1}} i ndiadh',
+'shown-title' => 'Taispeáin $1 {{PLURAL:$1|thoradh|torthaí}} an leathanach',
 'viewprevnext' => 'Taispeáin ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-legend' => 'Sainroghanna cuardaithe',
 'searchmenu-new' => "'''Cruthaigh an leathanach \"[[:\$1]]\" ar an vicí seo!'''",
 'searchhelp-url' => 'Help:Clár_ábhair',
+'searchprofile-articles' => 'Leathanaigh ábhair',
 'searchprofile-project' => 'Leathanaigh thionscadail agus cabhair',
 'searchprofile-images' => 'Ilmheáin',
 'searchprofile-everything' => 'Gach rud',
+'searchprofile-advanced' => 'Casta',
 'searchprofile-articles-tooltip' => 'Cuardaigh i $1',
 'searchprofile-project-tooltip' => 'Cuardaigh i $1',
 'searchprofile-images-tooltip' => 'Cuardaigh le comhaid',
-'search-result-size' => '$1 ({{PLURAL:$2|focal amháin|$2 focail}})',
+'searchprofile-everything-tooltip' => 'Cuardaigh an t-ábhar ar fad (leathanaigh plé san áireamh)',
+'searchprofile-advanced-tooltip' => 'Cuardaigh in ainmspásanna saincheaptha',
+'search-result-size' => '$1 ({{PLURAL:$2|fhocal amháin|$2 focail}})',
 'search-redirect' => '(athsheoladh $1)',
 'search-section' => '(gearradh $1)',
 'search-suggest' => 'An raibh $1 á lorg agat?',
@@ -899,7 +905,7 @@ Beidh an t-eolas seo poiblí.',
 'email' => 'Ríomhphost',
 'prefs-help-realname' => '* <strong>Fíorainm</strong> (roghnach): má toghaíonn tú é sin a chur ar fáil, úsáidfear é chun
 do chuid dreachtaí a chur i leith tusa.',
-'prefs-help-email' => '<strong>Ríomhphost</strong> (roghnach): Leis an tréith seo is féidir teagmháil a dhéanamh leat tríd do leathanach úsáideora nó leathanach phlé gan do sheoladh ríomhphost a thaispeáint.',
+'prefs-help-email' => 'Is roghnach seoladh ríomhphoist a thabhairt, ach is riachtanach é chun focal faire a athshocrú, má dhéanann tú dearmad air.',
 'prefs-help-email-required' => 'Ní foláir seoladh ríomhpoist a thabhairt.',
 'prefs-info' => 'Buneolas',
 'prefs-i18n' => 'Logánú',
@@ -965,6 +971,7 @@ do chuid dreachtaí a chur i leith tusa.',
 'recentchanges-legend' => 'Roghanna do na hathruithe is déanaí',
 'recentchanges-summary' => 'Déan faire ar na hathruithe is déanaí sa vicí ar an leathanach seo.',
 'recentchanges-feed-description' => 'Rianaigh na n-athruite vicí is déanaí sa fotha seo.',
+'recentchanges-label-minor' => 'Mionathrú é seo',
 'recentchanges-label-bot' => 'Chomhlíon róbó an t-athrú seo',
 'rcnote' => "Is {{PLURAL:$1|é seo a leanas <strong>an t-athrú amháin</strong>|iad seo a leanas na <strong>$1</strong> athruithe is déanaí}} {{PLURAL:$2|ar feadh an lae dheireanaigh|ar feadh na '''$2''' lá deireanacha}}, as $5, $4.",
 'rcnotefrom' => 'Is iad seo a leanas na hathruithe ó <b>$2</b> (go dti <b>$1</b> taispeánaithe).',
@@ -1202,7 +1209,7 @@ chun an gníomh seo a dhéanamh ar.',
 # Special:Log
 'specialloguserlabel' => 'Úsáideoir:',
 'speciallogtitlelabel' => 'Teideal:',
-'log' => 'Loganna',
+'log' => 'Logaí',
 'all-logs-page' => 'Gach loga poiblí',
 'alllogstext' => 'Bailiúchán cuimsitheach de gach loga {{SITENAME}}.
 Is féidir leat an méid ar taispeáint a chúngú trí roghnú an saghas loga, an t-ainm úsáideora (cásíogair), nó an leathanach (cásíogair freisin) atá i gceist agat.',
@@ -1270,7 +1277,7 @@ Beidh do seoladh ríomhphoist a d\'iontráil tú i [[Special:Preferences|do chui
 'emailsenttext' => 'Seoladh do theachtaireacht ríomhphoist go ráthúil.',
 
 # Watchlist
-'watchlist' => 'Mo liosta faire',
+'watchlist' => 'Liosta faire',
 'mywatchlist' => 'Liosta faire',
 'watchlistfor2' => 'Do $1 ($2)',
 'nowatchlist' => 'Níl aon rud ar do liosta faire.',
@@ -1370,6 +1377,7 @@ Féach ar $2 chun cuntas na scriosiadh deireanacha a fháil.',
 'rollback' => 'Athruithe a rolladh siar',
 'rollback_short' => 'Roll siar',
 'rollbacklink' => 'roll siar',
+'rollbacklinkcount' => 'Roll siar $1 {{PLURAL:$1|athrú|athruithe}}',
 'rollbackfailed' => 'Theip an rolladh siar',
 'cantrollback' => 'Ní féidir an athrú a athúsáid; ba é údar an ailt an t-aon duine a rinne athrú dó.',
 'alreadyrolled' => "Ní féidir eagrán níos luaí an leathanaigh [[:$1]] le [[User:$2|$2]] ([[User talk:$2|Plé]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) a athúsáid; d'athraigh duine eile é cheana fein, nó d'athúsáid duine eile eagrán níos luaí cheana féin.
@@ -1453,7 +1461,7 @@ Is an téacs as na leagan scriosta seo ar fáil do riarthóirí amháin.',
 'blanknamespace' => '(Gnáth)',
 
 # Contributions
-'contributions' => 'Dréachtaí úsáideora',
+'contributions' => 'Dréachtaí {{GENDER:$1|úsáideora}}',
 'contributions-title' => 'Dréachtaí úsáideora do $1',
 'mycontris' => 'Dréachtaí',
 'contribsub2' => 'Do $1 ($2)',
@@ -1467,6 +1475,8 @@ Is an téacs as na leagan scriosta seo ar fáil do riarthóirí amháin.',
 '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-uploads' => 'uaslódálacha',
+'sp-contributions-logs' => 'logaí',
 'sp-contributions-talk' => 'plé',
 'sp-contributions-userrights' => 'bainistíocht cearta úsáideora',
 'sp-contributions-search' => 'Cuardaigh dréachtaí',
@@ -1713,7 +1723,7 @@ ní féidir uaslódála staire díreacha a dhéanamh faoi láthair.",
 'tooltip-n-mainpage-description' => 'Tabhair cuairt ar an bpríomhleathanach',
 'tooltip-n-portal' => 'Maidir leis an tionscadal, cad is féidir leat a dhéanamh, conas achmhainní a fháil',
 'tooltip-n-currentevents' => 'Faigh eolas cúlrach maidir le chursaí reatha',
-'tooltip-n-recentchanges' => 'Liosta de na hathruithe is déanaí sa vicí.',
+'tooltip-n-recentchanges' => 'Liosta de na hathruithe is déanaí sa vicí',
 'tooltip-n-randompage' => 'Lódáil leathanach fánach',
 'tooltip-n-help' => 'An áit chun cabhair a fháil.',
 'tooltip-t-whatlinkshere' => 'Liosta de gach leathanach sa vicí ina bhfuil nasc chuig an leathanach seo',
@@ -1742,7 +1752,9 @@ ní féidir uaslódála staire díreacha a dhéanamh faoi láthair.",
 'tooltip-diff' => 'Taispeáin na difríochtaí áirithe a rinne tú don téacs',
 'tooltip-compareselectedversions' => 'Féach na difríochtaí idir an dhá leagain roghnaithe den leathanach seo.',
 'tooltip-watch' => 'Cuir an leathanach seo le do liosta faire',
+'tooltip-rollback' => 'Fill ar leagan an leathanaigh seo roimh athruithe an eagarthóra dheireanaigh in aon chlic amháin',
 'tooltip-undo' => 'Cuirtear "Cealaigh" an t-athrú seo ar cheal agus osclaítear an fhoirm eagair i mód réamhamhairc. Is féidir cúis na hathruithe a chur san achoimre.',
+'tooltip-summary' => 'Cuir isteach achoimre ghearr',
 
 # Stylesheets
 'monobook.css' => '/* athraigh an comhad seo chun an craiceann MonoBook a athrú don suíomh ar fad */',
@@ -1820,11 +1832,11 @@ B'fheidir go gcuirfear do chóras i gcontúirt dá rithfeá é.",
 'sp-newimages-showfrom' => 'Taispeáin íomhánna nua as $2, $1',
 
 # Bad image list
-'bad_image_list' => 'An formáid ná a leanas:
+'bad_image_list' => 'Is é seo a leanas an formáid:
 
-Míreanna liosta amháin (líonta a tosú le *) atá eisithe.
-Tá ar an chead nasc ar líne, naiscthe le drochchomhad.
-Aon naisc a leanas ar an líne céanna atá eisithe mar eisceachtaí; leathanaigh ina tarlaigh an comhad inlíne.',
+Níl ach míreanna liosta amháin (línte ag tosú le *) san áireamh.
+Is riachtanach gur nasc do dhrochchomhad é an chéad nasc ar líne.
+Is eisceachtaí iad na naisc eile ar an líne céanna, .i. leathanaigh gur féidir an comhad a bheith orthu go hinlíne.',
 
 # Metadata
 'metadata' => 'Meiteasonraí',
@@ -1832,7 +1844,7 @@ Aon naisc a leanas ar an líne céanna atá eisithe mar eisceachtaí; leathanaig
 Má tá an comhad mionathraithe as an bunleagan, b'fhéidir nach mbeidh ceann de na sonraí fágtha sa comhad atá athruithe.",
 'metadata-expand' => 'Taispeáin sonraí síneadh',
 'metadata-collapse' => 'Folaigh sonraí síneadh',
-'metadata-fields' => 'Beidh meiteasonraí EXIF atá liosta sa teachtaireacht seo san áireamh ar an leathanach íomhá nuair ata an clár meiteasonraí ceilte.
+'metadata-fields' => 'Beidh na meiteasonraí EXIF seo a leanas dá dtaispeáint ar an leathanach íomhá nuair atá an clár meiteasonraí ceilte.
 Beidh na cinn eile ceilte de réir réamhshocraithe.
 * make
 * model
index 64c800e..778b3f6 100644 (file)
@@ -20,7 +20,7 @@ $namespaceNames = array(
        NS_TALK             => '談詑',
        NS_USER             => '用戶',
        NS_USER_TALK        => '用戶・談詑',
-       NS_PROJECT_TALK     => '$1_談詑',
+       NS_PROJECT_TALK     => '$1談詑',
        NS_FILE             => '文檔',
        NS_FILE_TALK        => '文檔・談詑',
        NS_MEDIAWIKI_TALK   => 'MediaWiki・談詑',
@@ -32,6 +32,10 @@ $namespaceNames = array(
        NS_CATEGORY_TALK    => '分類・談詑',
 );
 
+$namespaceAliases = array(
+       '$1_談詑' => NS_PROJECT_TALK,
+);
+
 $messages = array(
 # Variants for Gan language
 'variantname-gan-hans' => '简体',
index 7dc9d67..ce0e3da 100644 (file)
@@ -168,6 +168,7 @@ $messages = array(
 'newwindow' => "(a' fosgladh ann an uinneag ùr)",
 'cancel' => 'Sguir dheth',
 'moredotdotdot' => 'Barrachd...',
+'morenotlisted' => 'Barrachd nach eil air an liosta...',
 'mypage' => 'Duilleag',
 'mytalk' => 'Deasbaireachd',
 'anontalk' => 'Conaltradh airson an IP seo',
@@ -201,6 +202,7 @@ $messages = array(
 'namespaces' => 'Namespaces',
 'variants' => 'Tionndaidhean',
 
+'navigation-heading' => 'Clàr-taice na seòladaireachd',
 'errorpagetitle' => 'Mearachd',
 'returnto' => 'Till dhan duilleag a leanas: $1',
 'tagline' => 'O {{SITENAME}}',
@@ -444,6 +446,9 @@ Thug an rianaire a ghlais e seachad an t-adhbhar a leanas: "$3".',
 'logouttext' => "'''Chaidh do logadh a-mach.'''
 'S urrainn dhut leantainn air adhart a' cleachdadh {{SITENAME}} a chleachdadh gun urra no 's urrainn dhut <span class='plainlinks'>[$1 logadh a-steach a-rithist]</span> mar an dearbh-chleachdaiche no mar chleachdaiche eile.
 Thoir an aire gum bi coltas air cuide dhe na duilleagan mar gum biodh tu air logadh a-steach gus am falamhaich thu tasgadan a' bhrabhsair agad.",
+'welcomeuser' => 'Fàilte ort, $1',
+'welcomecreation-msg' => 'Chaidh an cunntas agad a chruthachadh.
+Na dìochuimhnich na [[Special:Preferences|roghainnean agad air {{SITENAME}}]] a ghleusadh dhut fhèin.',
 'yourname' => 'Ainm-cleachdaiche:',
 'yourpassword' => 'Am facal-faire agad',
 'yourpasswordagain' => 'Ath-sgrìobh facal-faire',
@@ -466,7 +471,7 @@ Thoir an aire gum bi coltas air cuide dhe na duilleagan mar gum biodh tu air log
 'gotaccount' => 'A bheil cunntas agad mu thràth? $1.',
 'gotaccountlink' => 'Log a-steach',
 'userlogin-resetlink' => "Na dhìochuimhnich thu d' ainm is facal-faire?",
-'createaccountmail' => 'Le post-d',
+'createaccountmail' => "Cleachd facal-faire sealach air thuaiream agus cuir e dhan phost-d a tha 'ga shònrachadh gu h-ìosal",
 'createaccountreason' => 'Adhbhar:',
 'badretype' => "Chan eil an dà fhacal-faire a chuir thu a-steach a' freagairt ri chèile.",
 'userexists' => "Tha an t-ainm-cleachdaiche a chuir thu a-steach 'ga chleachdadh mu thràth.
@@ -546,6 +551,7 @@ Fuirich ort mus feuch thu ris a-rithist.",
 # E-mail sending
 'php-mail-error-unknown' => 'Mearachd neo-aithichte san fheart mail() aig PHP.',
 'user-mail-no-addy' => 'Cha do ghabh am post-d a chur leis nach robh seòladh puist-d ann.',
+'user-mail-no-body' => 'Bha bodhaig na teachdaireachd bàn no air leth goirid.',
 
 # Change password dialog
 'resetpass' => 'Atharraich am facal-faire',
@@ -604,6 +610,7 @@ Facal-faire sealach: $2',
 'changeemail-oldemail' => 'An seòladh puist-d làithreach:',
 'changeemail-newemail' => 'An seòladh puist-d ùr:',
 'changeemail-none' => '(chan eil gin)',
+'changeemail-password' => 'Am facal-faire agad air {{SITENAME}}:',
 'changeemail-submit' => 'Atharraich am post-d',
 'changeemail-cancel' => 'Sguir dheth',
 
@@ -776,7 +783,7 @@ Ma dh'fhoilleachas tu rudeigin an seo, bidh tu a' dearbhadh gun do sgrìobh thu
 '''NA CLEACHDAIBH SAOTHAIR FO DHLIGHE-SGRÌOBHAIDH GUN CHEAD!'''",
 'longpageerror' => "'''Mearachd: Tha an teacsa a chur thu thugainn {{PLURAL:$1 kilobyte|$1 kilobyte|$1 kilobyte|$1 kilobyte|$1 kilobyte|$1 kilobyte|}} a dh'fhaid is tha sin nas fhaide na tha ceadaichte ({{PLURAL:$1 kilobyte|$2 kilobyte|$2 kilobyte|$2 kilobyte|$2 kilobyte|$2 kilobyte|}}).'''
 Cha ghabh a shàbhaladh.",
-'readonlywarning' => "'''Rabhadh: Chaidh an stòr-dàta a ghlasadh a chum obair-ghlèidhidh agus chan urrainn dhut na còraichean-deasachaidh agad a chur gu feum an-dràsta fhèin.'''
+'readonlywarning' => "'''Rabhadh: Chaidh an stòr-dàta a ghlasadh a chum obair-ghlèidhidh agus chan urrainn dhut na dheasaich thu a shàbhaladh an-dràsta fhèin.'''
 'S mathaid gum b' fheairrde dhut lethbhreac a dhèanamh dhen teacsa agus a shàbhaladh ann am faidhle ach an urrainn dhut a chleachdadh as a dhèidh seo.
 
 Seo am mìneachadh a thug an rianaire a ghlais e: $1",
@@ -817,6 +824,15 @@ Tha coltas gun deach a sguabadh às.",
 'edit-already-exists' => "Cha b' urrainn dhuinn an duilleag ùr a chruthachadh.
 Tha e ann mu thràth.",
 'defaultmessagetext' => 'Teacsa bunaiteach na teachdaireachd',
+'content-failed-to-parse' => "Dh'fhàillig parsadh susbaint $2 airson modail $1: $3",
+'invalid-content-data' => 'Dàta susbaint a tha mì-dhligheach',
+'content-not-allowed-here' => 'Chan eil susbaint "$1" ceadaichte air an duilleag [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitext',
+'content-model-text' => 'teacsa lom',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Rabhadh:''' Tha cus expensive parser function calls san duilleag seo.
@@ -856,7 +872,7 @@ Mìneachadh: '''({{int:cur}})''' = an diofar eadar e 's am mùthadh as ùire, ''
 'history-show-deleted' => 'Na chaidh sguabadh às a-mhàin',
 'histfirst' => 'As sine',
 'histlast' => 'As ùire',
-'historysize' => '({{PLURAL:$1|1 bhaidt|$1 bhaidht|$1 bhaidht|$1 bhaidht|$1 baidht|$1 baidht}})',
+'historysize' => '({{PLURAL:$1|1 bhaidt|$1 bhaidht|$1 bhaidht|$1 bhaidht|$1 baidhtichean|$1 baidht}})',
 'historyempty' => '(falamh)',
 
 # Revision feed
@@ -874,9 +890,11 @@ Feuch is [[Special:Search|lorg duilleagan ùra iomachaidh air an uici]]",
 'rev-delundel' => 'seall/falaich',
 'rev-showdeleted' => 'seall',
 'revdelete-hide-user' => 'Falaich ainm-cleachdaiche/seòladh IP an deasaiche',
+'revdelete-log' => 'Adhbhar:',
 'revdel-restore' => 'mùth follaiseachd',
 'revdel-restore-deleted' => 'mùthaidhean a chaidh a sguabadh às',
 'revdel-restore-visible' => 'mùthaidhean faicsinneach',
+'pagehist' => 'Eachdraidh na duilleige',
 'revdelete-otherreason' => 'Adhbhar eile/a bharrachd:',
 'revdelete-reasonotherlist' => 'Adhbhar eile',
 'revdelete-edit-reasonlist' => 'Deasaich adhbharan an sguabaidh às',
@@ -902,6 +920,8 @@ Feuch is [[Special:Search|lorg duilleagan ùra iomachaidh air an uici]]",
 'searchresulttext' => 'Airson barrachd fiosrachaidh mu rannsachadh {{SITENAME}}, cuir sùil air [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => 'Lorg thu \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|gach duilleag a tha a\' tòiseachadh le "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|gach duilleag a tha a\' ceangal ri "$1"]])',
 'searchsubtitleinvalid' => "Lorg thu airson '''$1'''",
+'toomanymatches' => 'Fhuaras cus thoraidhean, feuch ceist eile',
+'titlematches' => "Tiotalan dhuilleagan a tha a' maidseadh",
 'notitlematches' => "Chan eil tiotal de dhuilleag sam bith a' freagairt ris",
 'notextmatches' => "Chan eil tiotal de dhuilleag sam bith a' freagairt ris",
 'prevn' => 'an {{PLURAL:$1|$1}} mu dheireadh',
@@ -925,6 +945,7 @@ Feuch is [[Special:Search|lorg duilleagan ùra iomachaidh air an uici]]",
 'searchprofile-advanced-tooltip' => 'Lorg am broinn ainm-spàsan gnàthaichte',
 'search-result-size' => '$1 ({{PLURAL:$2|1 fhacal|$2 fhacal|1 fhacal|$2 fhacal|$2 faclan|$2 facal}})',
 'search-result-category-size' => '{{PLURAL:$1|1 bhall|$1 bhall|$1 bhall|$1 bhall|$1 bhuill|$1 ball}} ({{PLURAL:$2|1 fho-roinn|$2 fho-roinn|$2 fho-roinn|$2 fho-roinn|$2 fo-roinnean|$2 fo-roinn}}, {{PLURAL:$3|1 fhaidhle|$3 fhaidhle|$3 fhaidhle|$3 fhaidhle|$3 faidhlichean|$3 faidhle}})',
+'search-result-score' => 'Buntainneas: $1%',
 'search-redirect' => '(ag ath-sheòladh $1)',
 'search-section' => '(earrann $1)',
 'search-suggest' => 'An e na leanas a bha fa-near dhut: $1',
@@ -1193,7 +1214,7 @@ Thoir sùil air na [[Special:WantedCategories|roinntean-seòrsa a thathar 'gan i
 'emailsend' => 'Cuir',
 
 # Watchlist
-'watchlist' => 'Mo chlàr-faire',
+'watchlist' => 'An clàr-faire',
 'mywatchlist' => 'An clàr-faire',
 'watchlistfor2' => 'Do $1 $2',
 'nowatchlist' => "Chan eil rud sam bith air a' chlàr-fhaire agad.",
@@ -1282,7 +1303,7 @@ Seo roghainnean làithreach na duilleige '''$1''':",
 
 # Namespace form on various pages
 'namespace' => 'Namespace:',
-'invert' => 'Cuir na tagh mi bun os cionn',
+'invert' => 'Cuir na thagh mi bun os cionn',
 'blanknamespace' => '(Prìomh)',
 
 # Contributions
index a7adc64..040dc1c 100644 (file)
@@ -178,6 +178,7 @@ $magicWords = array(
        'currentday2'               => array( '1', 'DÍAACTUAL2', 'DIAATUAL2', 'CURRENTDAY2' ),
        'currentdayname'            => array( '1', 'NOMEDODÍAACTUAL', 'NOMEDODIAATUAL', 'CURRENTDAYNAME' ),
        'currentyear'               => array( '1', 'ANOACTUAL', 'ANOATUAL', 'CURRENTYEAR' ),
+       'currenttime'               => array( '1', 'DATAEHORAACTUAIS', 'HORARIOATUAL', 'CURRENTTIME' ),
        'currenthour'               => array( '1', 'HORAACTUAL', 'HORAATUAL', 'CURRENTHOUR' ),
        'localmonth'                => array( '1', 'MESLOCAL', 'LOCALMONTH', 'LOCALMONTH2' ),
        'localmonth1'               => array( '1', 'MESLOCAL1', 'LOCALMONTH1' ),
@@ -187,26 +188,46 @@ $magicWords = array(
        'localday2'                 => array( '1', 'DÍALOCAL2', 'DIALOCAL2', 'LOCALDAY2' ),
        'localdayname'              => array( '1', 'NOMEDODÍALOCAL', 'NOMEDODIALOCAL', 'LOCALDAYNAME' ),
        'localyear'                 => array( '1', 'ANOLOCAL', 'LOCALYEAR' ),
+       'localtime'                 => array( '1', 'DATAEHORALOCAIS', 'HORARIOLOCAL', 'LOCALTIME' ),
        'localhour'                 => array( '1', 'HORALOCAL', 'LOCALHOUR' ),
        'numberofpages'             => array( '1', 'NÚMERODEPÁXINAS', 'NUMERODEPAGINAS', 'NÚMERODEPÁGINAS', 'NUMBEROFPAGES' ),
        'numberofarticles'          => array( '1', 'NÚMERODEARTIGOS', 'NUMERODEARTIGOS', 'NUMBEROFARTICLES' ),
        'numberoffiles'             => array( '1', 'NÚMERODEFICHEIROS', 'NUMERODEARQUIVOS', 'NÚMERODEARQUIVOS', 'NUMBEROFFILES' ),
        'numberofusers'             => array( '1', 'NÚMERODEUSUARIOS', 'NUMERODEUSUARIOS', 'NÚMERODEUSUÁRIOS', 'NUMBEROFUSERS' ),
+       'numberofactiveusers'       => array( '1', 'NÚMERODEUSUARIOSACTIVOS', 'NUMERODEUSUARIOSATIVOS', 'NÚMERODEUSUÁRIOSATIVOS', 'NUMBEROFACTIVEUSERS' ),
        'numberofedits'             => array( '1', 'NÚMERODEEDICIÓNS', 'NUMERODEEDICOES', 'NÚMERODEEDIÇÕES', 'NUMBEROFEDITS' ),
+       'numberofviews'             => array( '1', 'NÚMERODEVISITAS', 'NUMERODEEXIBICOES', 'NÚMERODEEXIBIÇÕES', 'NUMBEROFVIEWS' ),
        'pagename'                  => array( '1', 'NOMEDAPÁXINA', 'NOMEDAPAGINA', 'NOMEDAPÁGINA', 'PAGENAME' ),
        'namespace'                 => array( '1', 'ESPAZODENOMES', 'DOMINIO', 'DOMÍNIO', 'ESPACONOMINAL', 'ESPAÇONOMINAL', 'NAMESPACE' ),
        'fullpagename'              => array( '1', 'NOMECOMPLETODAPÁXINA', 'NOMECOMPLETODAPAGINA', 'NOMECOMPLETODAPÁGINA', 'FULLPAGENAME' ),
        'subpagename'               => array( '1', 'NOMEDASUBPÁXINA', 'NOMEDASUBPAGINA', 'NOMEDASUBPÁGINA', 'SUBPAGENAME' ),
        'basepagename'              => array( '1', 'NOMEDAPÁXINABASE', 'NOMEDAPAGINABASE', 'NOMEDAPÁGINABASE', 'BASEPAGENAME' ),
        'talkpagename'              => array( '1', 'NOMEDAPÁXINADECONVERSA', 'NOMEDAPAGINADEDISCUSSAO', 'NOMEDAPÁGINADEDISCUSSÃO', 'TALKPAGENAME' ),
-       'img_manualthumb'           => array( '1', 'miniatura=$1', 'miniaturadaimagem=$1', 'thumbnail=$1', 'thumb=$1' ),
+       'img_thumbnail'             => array( '1', 'miniatura', 'miniaturadaimaxe', 'miniaturadaimagem', 'thumbnail', 'thumb' ),
+       'img_manualthumb'           => array( '1', 'miniatura=$1', 'miniaturadaimaxe=$1', 'miniaturadaimagem=$1', 'thumbnail=$1', 'thumb=$1' ),
        'img_right'                 => array( '1', 'dereita', 'direita', 'right' ),
        'img_left'                  => array( '1', 'esquerda', 'left' ),
        'img_none'                  => array( '1', 'ningún', 'nenhum', 'none' ),
        'img_center'                => array( '1', 'centro', 'center', 'centre' ),
+       'img_framed'                => array( '1', 'conmarco', 'conbordo', 'marco', 'commoldura', 'comborda', 'framed', 'enframed', 'frame' ),
+       'img_frameless'             => array( '1', 'senmarco', 'senbordo', 'semmoldura', 'semborda', 'frameless' ),
        'img_page'                  => array( '1', 'páxina=$1', 'páxina $1', 'página=$1', 'página $1', 'page=$1', 'page $1' ),
        'img_border'                => array( '1', 'bordo', 'borda', 'border' ),
+       'img_top'                   => array( '1', 'arriba', 'acima', 'top' ),
+       'img_text_top'              => array( '1', 'texto-arriba', 'text-top' ),
+       'img_middle'                => array( '1', 'medio', 'meio', 'middle' ),
+       'img_bottom'                => array( '1', 'abaixo', 'bottom' ),
+       'img_text_bottom'           => array( '1', 'texto-abaixo', 'text-bottom' ),
+       'img_link'                  => array( '1', 'ligazón=$1', 'ligação=$1', 'link=$1' ),
+       'img_class'                 => array( '1', 'clase=$1', 'class=$1' ),
+       'sitename'                  => array( '1', 'NOMEDOSITIO', 'NOMEDOSITE', 'NOMEDOSÍTIO', 'SITENAME' ),
+       'localurl'                  => array( '0', 'URLLOCAL', 'LOCALURL:' ),
+       'articlepath'               => array( '0', 'RUTADOARTIGO', 'ARTICLEPATH' ),
+       'pageid'                    => array( '0', 'IDDAPÁXINA', 'PAGEID' ),
+       'server'                    => array( '0', 'SERVIDOR', 'SERVER' ),
+       'servername'                => array( '0', 'NOMEDOSERVIDOR', 'SERVERNAME' ),
        'grammar'                   => array( '0', 'GRAMÁTICA:', 'GRAMMAR:' ),
+       'gender'                    => array( '0', 'SEXO:', 'GENERO', 'GÊNERO', 'GENDER:' ),
        'displaytitle'              => array( '1', 'AMOSAROTÍTULO', 'EXIBETITULO', 'EXIBETÍTULO', 'DISPLAYTITLE' ),
        'newsectionlink'            => array( '1', '__LIGAZÓNDANOVASECCIÓN__', '__LINKDENOVASECAO__', '__LINKDENOVASEÇÃO__', '__LIGACAODENOVASECAO__', '__LIGAÇÃODENOVASEÇÃO__', '__NEWSECTIONLINK__' ),
        'language'                  => array( '0', '#LINGUA:', '#IDIOMA:', '#LANGUAGE:' ),
@@ -217,6 +238,11 @@ $magicWords = array(
        'hiddencat'                 => array( '1', '__CATEGORÍAOCULTA__', '__CATEGORIAOCULTA__', '__CATOCULTA__', '__HIDDENCAT__' ),
        'pagesincategory'           => array( '1', 'PÁXINASNACATEGORÍA', 'PAGINASNACATEGORIA', 'PÁGINASNACATEGORIA', 'PAGINASNACAT', 'PÁGINASNACAT', 'PAGESINCATEGORY', 'PAGESINCAT' ),
        'pagesize'                  => array( '1', 'TAMAÑODAPÁXINA', 'TAMANHODAPAGINA', 'TAMANHODAPÁGINA', 'PAGESIZE' ),
+       'url_path'                  => array( '0', 'RUTA', 'PATH' ),
+       'pagesincategory_all'       => array( '0', 'todos', 'all' ),
+       'pagesincategory_pages'     => array( '0', 'páxinas', 'pages' ),
+       'pagesincategory_subcats'   => array( '0', 'subcategorías', 'subcats' ),
+       'pagesincategory_files'     => array( '0', 'ficheiros', 'files' ),
 );
 
 $separatorTransformTable = array( ',' => '.', '.' => ',' );
@@ -469,7 +495,7 @@ $1',
 'helppage' => 'Help:Axuda',
 'mainpage' => 'Portada',
 'mainpage-description' => 'Portada',
-'policy-url' => 'Project:Política e normas',
+'policy-url' => 'Project:Políticas e normas',
 'portal' => 'Portal da comunidade',
 'portal-url' => 'Project:Portal da comunidade',
 'privacy' => 'Política de protección de datos',
@@ -660,7 +686,7 @@ Non esqueza personalizar as súas [[Special:Preferences|preferencias de {{SITENA
 'gotaccount' => "Xa ten unha conta? '''$1'''.",
 'gotaccountlink' => 'Acceda ao sistema',
 'userlogin-resetlink' => 'Esqueceu os seus datos de rexistro?',
-'createaccountmail' => 'Por correo electrónico',
+'createaccountmail' => 'Utilizar un contrasinal aleatorio temporal e envialo ao enderezo de correo electrónico especificado embaixo',
 'createaccountreason' => 'Motivo:',
 'badretype' => 'Os contrasinais que inseriu non coinciden.',
 'userexists' => 'O nome de usuario que inseriu xa está en uso.
@@ -956,7 +982,7 @@ Isto pode acontecer porque estea a empregar un servizo de ''proxy'' anónimo def
 A área de texto superior contén o texto da páxina tal e como existe na actualidade.
 Os seus cambios móstranse na área inferior.
 Pode mesturar os seus cambios co texto existente.
-'''Só''' se gardará o texto na área superior cando prema \"{{int:savearticle}}\".",
+'''Só''' se gardará o texto na área superior cando prema en \"{{int:savearticle}}\".",
 'yourtext' => 'O seu texto',
 'storedversion' => 'Versión gardada',
 'nonunicodebrowser' => "'''Atención: O seu navegador non soporta o Unicode.'''
@@ -1280,7 +1306,7 @@ O [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} rexistro de borrad
 'search-interwiki-default' => 'Resultados en $1:',
 'search-interwiki-more' => '(máis)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Deshabilitar as suxestións AJAX',
+'mwsuggest-disable' => 'Desactivar as suxestións de procura',
 'searcheverything-enable' => 'Procurar en todos os espazos de nomes',
 'searchrelated' => 'relacionado',
 'searchall' => 'todo',
@@ -1586,7 +1612,7 @@ Ha de ter menos {{PLURAL:$1|dun carácter|de $1 caracteres}}.',
 'action-sendemail' => 'enviar correos electrónicos',
 
 # Recent changes
-'nchanges' => '$1 {{PLURAL:$1|cambio|cambios}}',
+'nchanges' => '$1 {{PLURAL:$1|modificación|modificacións}}',
 'recentchanges' => 'Cambios recentes',
 'recentchanges-legend' => 'Opcións dos cambios',
 'recentchanges-summary' => 'Nesta páxina pode seguir as modificacións máis recentes feitas no wiki.',
@@ -2197,7 +2223,7 @@ Cómpre, polo menos, un dominio de nivel superior; por exemplo, "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Lista de usuarios activos',
 '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|edición|edicións}} {{PLURAL:$3|no último día|nos últimos $3 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',
@@ -2260,7 +2286,7 @@ O enderezo de correo electrónico que inseriu [[Special:Preferences|nas súas pr
 'usermessage-editor' => 'Editor das mensaxes do sistema',
 
 # Watchlist
-'watchlist' => 'A miña lista de vixilancia',
+'watchlist' => 'Lista de vixilancia',
 'mywatchlist' => 'Lista de vixilancia',
 'watchlistfor2' => 'De $1 $2',
 'nowatchlist' => 'Non ten elementos na súa lista de vixilancia.',
@@ -2416,7 +2442,7 @@ Vexa a [[Special:ProtectedPages|lista de páxinas protexidas]] se quere obter a
 'protect-legend' => 'Confirmar a protección',
 'protectcomment' => 'Motivo:',
 'protectexpiry' => 'Caducidade:',
-'protect_expiry_invalid' => 'O tempo de duración da protección non e válido.',
+'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-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'''\".",
@@ -2617,13 +2643,13 @@ Olle a [[Special:BlockList|lista de bloqueos]] para revisalo.',
 'ipb-blockingself' => 'Está a piques de se bloquear! Está seguro de querer facelo?',
 'ipb-confirmhideuser' => 'Está a piques de bloquear un usuario coa opción "agochar o usuario" activada. Isto suprime o nome de usuario de todas as listas e entradas de rexistro. Está seguro de querer facelo?',
 'ipb-edit-dropdown' => 'Editar os motivos de bloqueo',
-'ipb-unblock-addr' => 'Desbloquear a "$1"',
+'ipb-unblock-addr' => 'Desbloquear a $1',
 'ipb-unblock' => 'Desbloquear un usuario ou enderezo IP',
 'ipb-blocklist' => 'Ver os bloqueos vixentes',
-'ipb-blocklist-contribs' => 'Contribucións de "$1"',
-'unblockip' => 'Desbloquear o usuario',
+'ipb-blocklist-contribs' => 'Contribucións de $1',
+'unblockip' => 'Desbloquear un usuario',
 'unblockiptext' => 'Use o seguinte formulario para dar de novo acceso de escritura a un enderezo IP ou usuario que estea bloqueado.',
-'ipusubmit' => 'Retirar este bloqueo',
+'ipusubmit' => 'Retirar o bloqueo',
 'unblocked' => '[[User:$1|$1]] foi {{GENDER:$1|desbloqueado|desbloqueada}}',
 'unblocked-range' => '$1 foi desbloqueado',
 'unblocked-id' => 'O bloqueo $1 foi eliminado',
@@ -2667,7 +2693,7 @@ O motivo do bloqueo de $1 é: "$2"',
 'blocklogtext' => 'Este é o rexistro das accións de bloqueo e desbloqueo de usuarios.
 Non se listan os enderezos IP bloqueados automaticamente.
 Olle a [[Special:BlockList|lista de bloqueos]] para comprobar os bloqueos vixentes.',
-'unblocklogentry' => 'desbloqueou a "$1"',
+'unblocklogentry' => 'desbloqueou a $1',
 'block-log-flags-anononly' => 'só os usuarios anónimos',
 'block-log-flags-nocreate' => 'desactivada a creación de contas',
 'block-log-flags-noautoblock' => 'bloqueo automático deshabilitado',
@@ -2676,11 +2702,11 @@ Olle a [[Special:BlockList|lista de bloqueos]] para comprobar os bloqueos vixent
 'block-log-flags-angry-autoblock' => 'realzou o autobloqueo permitido',
 'block-log-flags-hiddenname' => 'nome de usuario agochado',
 'range_block_disabled' => 'A funcionalidade de administrador de crear rangos de bloqueos está deshabilitada.',
-'ipb_expiry_invalid' => 'Tempo de duración non válido.',
+'ipb_expiry_invalid' => 'O tempo de duración non é válido.',
 'ipb_expiry_temp' => 'Os bloqueos a nomes de usuario agochados deberían ser permanentes.',
-'ipb_hide_invalid' => 'Incapaz de suprimir esta conta; pode que teña moitas edicións.',
+'ipb_hide_invalid' => 'Non se pode suprimir esta conta; se cadra, ten moitas edicións.',
 'ipb_already_blocked' => '"$1" xa está bloqueado',
-'ipb-needreblock' => '"$1" xa está bloqueado. Quere cambiar as configuracións?',
+'ipb-needreblock' => '$1 xa está bloqueado. Quere cambiar as configuracións?',
 'ipb-otherblocks-header' => '{{PLURAL:$1|Outro bloqueo|Outros bloqueos}}',
 '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.',
@@ -2725,24 +2751,24 @@ Lembre [[Special:UnlockDB|eliminar o bloqueo]] unha vez completado o seu manteme
 # Move page
 'move-page' => 'Mover "$1"',
 'move-page-legend' => 'Mover páxina',
-'movepagetext' => "Ao usar o formulario de embaixo vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
+'movepagetext' => "Ao usar o formulario inferior vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
 O título vello vaise converter nunha páxina de redirección ao novo título.
 Pode actualizar automaticamente as redireccións que van dar ao título orixinal.
 Se escolle non facelo, asegúrese de verificar que non hai redireccións [[Special:DoubleRedirects|dobres]] ou [[Special:BrokenRedirects|crebadas]].
 Vostede é responsábel de asegurarse de que as ligazóns continúan a apuntar cara a onde se supón que deberían.
 
-Teña en conta que a páxina '''non''' será movida se xa existe unha páxina co novo título, a menos que sexa unha redirección e non teña historial de edicións.
+Teña en conta que a páxina '''non''' será trasladada se xa existe unha páxina co novo título, a menos que esta última sexa unha redirección e non teña historial de edicións.
 Isto significa que pode volver renomear unha páxina ao seu nome antigo se comete un erro, e que non pode sobrescribir unha páxina que xa existe.
 
 '''Atención!'''
 Este cambio nunha páxina popular pode ser drástico e inesperado;
 por favor, asegúrese de que entende as consecuencias disto antes de proseguir.",
-'movepagetext-noredirectfixer' => "Ao usar o formulario de embaixo vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
+'movepagetext-noredirectfixer' => "Ao usar o formulario inferior vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
 O título vello vaise converter nunha páxina de redirección ao novo título.
 Asegúrese de verificar que non hai redireccións [[Special:DoubleRedirects|dobres]] ou [[Special:BrokenRedirects|crebadas]].
 Vostede é responsábel de asegurarse de que as ligazóns continúan a apuntar cara a onde se supón que deberían.
 
-Teña en conta que a páxina '''non''' será movida se xa existe unha páxina co novo título, a menos que sexa unha redirección e non teña historial de edicións.
+Teña en conta que a páxina '''non''' será trasladada se xa existe unha páxina co novo título, a menos que esta última sexa unha redirección e non teña historial de edicións.
 Isto significa que pode volver renomear unha páxina ao seu nome antigo se comete un erro, e que non pode sobrescribir unha páxina que xa existe.
 
 '''Atención!'''
@@ -2894,7 +2920,7 @@ Gárdeo no seu disco duro e cárgueo aquí.',
 'importbadinterwiki' => 'Ligazón interwiki incorrecta',
 'importnotext' => 'Baleiro ou sen texto',
 'importsuccess' => 'A importación rematou!',
-'importhistoryconflict' => 'Existe un conflito no historial de revisións (por ter importado esta páxina antes)',
+'importhistoryconflict' => 'Existe un conflito no historial de revisións (se cadra, xa se importou esta páxina anteriormente)',
 'importnosources' => 'Non se defininiu ningunha fonte de importación transwiki e os envíos directos dos historiais están desactivados.',
 'importnofile' => 'Non se enviou ningún ficheiro de importación.',
 'importuploaderrorsize' => 'Fallou o envío do ficheiro de importación. O ficheiro é máis grande que o tamaño de envío permitido.',
@@ -3082,6 +3108,7 @@ Isto, probabelmente, se debe a unha ligazón cara a un sitio externo que está n
 'pageinfo-robot-noindex' => 'Non indexable',
 'pageinfo-views' => 'Número de visitas',
 'pageinfo-watchers' => 'Número de vixiantes da páxina',
+'pageinfo-few-watchers' => 'Menos de $1 {{PLURAL:$1|vixiante|vixiantes}}',
 'pageinfo-redirects-name' => 'Redireccións cara a esta páxina',
 'pageinfo-subpages-name' => 'Subpáxinas desta páxina',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirección|redireccións}}; $3 {{PLURAL:$3|non-redirección|non-redireccións}})',
@@ -3863,7 +3890,7 @@ As imaxes móstranse na súa resolución completa; outros tipos de ficheiros in
 'specialpages-group-highuse' => 'Páxinas con máis uso',
 'specialpages-group-pages' => 'Listas de páxinas',
 'specialpages-group-pagetools' => 'Ferramentas das páxinas',
-'specialpages-group-wiki' => 'Datos do wiki e ferramentas',
+'specialpages-group-wiki' => 'Datos e ferramentas',
 'specialpages-group-redirects' => 'Páxinas de redirección especiais',
 'specialpages-group-spam' => 'Ferramentas contra o spam',
 
@@ -3892,7 +3919,7 @@ As imaxes móstranse na súa resolución completa; outros tipos de ficheiros in
 'tags-description-header' => 'Descrición completa do significado',
 'tags-hitcount-header' => 'Edicións etiquetadas',
 'tags-edit' => 'editar',
-'tags-hitcount' => '$1 {{PLURAL:$1|cambio|cambios}}',
+'tags-hitcount' => '$1 {{PLURAL:$1|modificación|modificacións}}',
 
 # Special:ComparePages
 'comparepages' => 'Comparar páxinas',
@@ -3960,8 +3987,8 @@ As imaxes móstranse na súa resolución completa; outros tipos de ficheiros in
 'logentry-newusers-newusers' => 'Creouse a conta de usuario $1',
 'logentry-newusers-create' => 'Creouse a conta de usuario $1',
 'logentry-newusers-create2' => '$1 creou a conta de usuario $3',
+'logentry-newusers-byemail' => '$1 creou a conta de usuario $3; o contrasinal enviouse por correo electrónico',
 'logentry-newusers-autocreate' => 'A conta de usuario $1 creouse automaticamente',
-'newuserlog-byemail' => 'contrasinal enviado por correo electrónico',
 'logentry-rights-rights' => '$1 cambiou o grupo ao que pertence $3 de $4 a $5',
 'logentry-rights-rights-legacy' => '$1 cambiou o grupo ao que pertence $3',
 'logentry-rights-autopromote' => '$1 foi promovido automaticamente de $4 a $5',
@@ -4018,7 +4045,8 @@ En caso contrario, pode empregar o formulario sinxelo inferior. O seu comentario
 'api-error-nomodule' => 'Erro interno: Non hai ningún módulo de cargas.',
 'api-error-ok-but-empty' => 'Erro interno: Non hai resposta do servidor.',
 'api-error-overwrite' => 'Non está permitido sobrescribir un ficheiro existente.',
-'api-error-stashfailed' => 'Erro interno: O servidor non puido almacenar os ficheiros temporais.',
+'api-error-stashfailed' => 'Erro interno: O servidor non puido almacenar o ficheiro temporal.',
+'api-error-publishfailed' => 'Erro interno: O servidor non puido publicar o ficheiro temporal.',
 'api-error-timeout' => 'O servidor non respondeu no tempo esperado.',
 'api-error-unclassified' => 'Houbo un erro descoñecido.',
 'api-error-unknown-code' => 'Erro descoñecido: "$1"',
index 20117a8..6a4316f 100644 (file)
@@ -2701,7 +2701,6 @@ $5
 # New logging system
 'revdelete-restricted' => 'ἐφηρμοσμένοι περιορισμοὶ διὰ τοὺς ἐπιτρόπους',
 'revdelete-unrestricted' => 'αἱρεθέντες περιορισμοὶ διὰ τοὺς ἐπιτρόπους',
-'newuserlog-byemail' => 'σύνθημα ἀπεσταλμένον μέσῳ ἠλ-ταχυδρομείου',
 'rightsnone' => '(Οὐδέν)',
 
 # Feedback
index b456087..904d1d5 100644 (file)
@@ -2834,8 +2834,8 @@ Die uf em lokale Rächner spychere un derno do uffelade.',
 'pageinfo-article-id' => 'Syten-ID',
 'pageinfo-language' => 'Syteninhaltssproch',
 'pageinfo-robot-policy' => 'Suechmaschinestatus',
-'pageinfo-robot-index' => 'Indizierbar',
-'pageinfo-robot-noindex' => 'Nit indizierbar',
+'pageinfo-robot-index' => 'Indexierbar',
+'pageinfo-robot-noindex' => 'Nit indexierbar',
 'pageinfo-views' => 'Aazahl Sytenufruef',
 'pageinfo-watchers' => 'Aazahl vu Beobachter',
 'pageinfo-redirects-name' => 'Wyterleitige zue däre Syte',
@@ -3681,7 +3681,6 @@ Di aagfrogt Datei wird diräkt dargstellt bzw. mit dr verchnipfte Aawändig gsta
 'logentry-newusers-create' => 'Benutzerkonto $1 isch aagleit wore.',
 'logentry-newusers-create2' => 'Benutzerkonto $3 isch aalgeit wore vu $1',
 'logentry-newusers-autocreate' => 'S Benutzerchonto $1 isch automatisch erstellt worde',
-'newuserlog-byemail' => 's Passwort isch per E-Mail gschickt wore',
 'logentry-rights-rights' => '$1 het d Gruppezuegherigkeit fir $3 vu $4 uf $5 gänderet',
 'logentry-rights-rights-legacy' => '$1 het d Gruppezuegherigkeit fir $3 gänderet',
 'logentry-rights-autopromote' => '$1 isch automatisch vu $4 zue $5 zuegordnet wore',
index afe55ba..bc14e93 100644 (file)
@@ -2621,7 +2621,7 @@ $1',
 # Move page
 'move-page' => '$1 ખસેડો',
 'move-page-legend' => 'પાનું ખસેડો',
-'movepagetext' => "નà«\80àª\9aà«\87નà«\81àª\82 àª«à«\8bરà«\8dમ àªµàª¾àªªàª°àªµàª¾àª¥à«\80 àª\86 àªªàª¾àª¨àª¾àª¨à«\81àª\82 àª¨àª¾àª® àª¬àª¦àª²àª¾àª\87 àª\9cશà«\87 àª\85નà«\87 àª¤à«\87માàª\82 àª°àª¹à«\87લà«\80 àª¬àª§à«\80 àª®àª¹àª¿àª¤àª¿ નવા નામે બનેલાં પાનામાં ખસેડાઇ જશે.
+'movepagetext' => "નà«\80àª\9aà«\87નà«\81àª\82 àª«à«\8bરà«\8dમ àªµàª¾àªªàª°àªµàª¾àª¥à«\80 àª\86 àªªàª¾àª¨àª¾àª¨à«\81àª\82 àª¨àª¾àª® àª¬àª¦àª²àª¾àª\87 àª\9cશà«\87 àª\85નà«\87 àª¤à«\87માàª\82 àª°àª¹à«\87લà«\80 àª¬àª§à«\80 àª®àª¾àª¹àª¿àª¤à«\80 નવા નામે બનેલાં પાનામાં ખસેડાઇ જશે.
 જુનું પાનું, નવા બનેલા પાના તરફ વાળતું થશે.
 તમે આવા અન્યત્ર વાળેલાં પનાઓને આપોઆપ જ તેના મુળ શીર્ષક સાથે જોડી શકશો.
 જો તમે તેમ કરવા ના ઇચ્છતા હોવ તો, [[Special:DoubleRedirects|બેવડા]] અથવા [[Special:BrokenRedirects|ત્રુટક કડી વાળા]] અન્યત્ર વાળેલા પાનાઓની યાદી ચકાસીને ખાતરી કરી લેશો.
@@ -3765,7 +3765,6 @@ $5
 'logentry-newusers-create' => 'સભ્ય ખાતું $1 બનાવવામાં આવ્યું',
 'logentry-newusers-create2' => 'સભ્ય ખાતું $3 $1 વડે બનાવવામાં આવ્યું',
 'logentry-newusers-autocreate' => 'એકાઉન્ટ $1 બનાવનાર આપોઆપ',
-'newuserlog-byemail' => 'ગુપ્ત સંજ્ઞા ઇ-મેલ દ્વારા મોકલાઇ છે.',
 'rightsnone' => '(કંઈ નહી)',
 
 # Feedback
index c0d230b..a62ba4f 100644 (file)
@@ -790,7 +790,7 @@ $2',
 'gotaccount' => 'כבר נרשמתם? $1.',
 'gotaccountlink' => 'כניסה לחשבון',
 'userlogin-resetlink' => 'שכחת את פרטי הכניסה?',
-'createaccountmail' => '×\91×\90×\9eצע×\95ת ×\93×\95×\90\9c',
+'createaccountmail' => 'ש×\99×\9e×\95ש ×\91ס×\99ס×\9e×\94 ×\96×\9e× ×\99ת ×\90קר×\90×\99ת ×\95ש×\9c×\99×\97ת×\94 ×\9c×\9bת×\95×\91ת ×\94×\93×\95×\90\9c ×\94×\9eצ×\95×\99נת ×\9c×\94×\9c×\9f',
 'createaccountreason' => 'סיבה:',
 'badretype' => 'הסיסמאות שהזנתם אינן מתאימות.',
 'userexists' => 'שם המשתמש שבחרתם כבר נמצא בשימוש.
@@ -1401,7 +1401,7 @@ $1",
 'search-interwiki-default' => 'תוצאות ב{{GRAMMAR:תחילית|$1}}:',
 'search-interwiki-more' => '(עוד)',
 'search-relatedarticle' => 'קשור',
-'mwsuggest-disable' => 'ביטול הצעות AJAX',
+'mwsuggest-disable' => 'ביטול הצעות חיפוש',
 'searcheverything-enable' => 'חיפוש בכל מרחבי השם',
 'searchrelated' => 'קשור',
 'searchall' => 'הכול',
@@ -2316,7 +2316,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'רשימת משתמשים פעילים',
 'activeusers-intro' => 'זוהי רשימת המשתמשים שביצעו פעולה כלשהי {{PLURAL:$1|ביום האחרון|ביומיים האחרונים|ב־$1 הימים האחרונים}}.',
-'activeusers-count' => '{{PLURAL:$1|ער×\99×\9b×\94 ×\90×\97ת|$1 ×¢×¨×\99×\9bות}} ב{{PLURAL:$3|יום האחרון|יומיים האחרונים|־$3 הימים האחרונים}}',
+'activeusers-count' => '{{PLURAL:$1|פע×\95×\9c×\94 ×\90×\97ת|$1 ×¤×¢×\95×\9cות}} ב{{PLURAL:$3|יום האחרון|יומיים האחרונים|־$3 הימים האחרונים}}',
 'activeusers-from' => 'הצגת משתמשים החל מ:',
 'activeusers-hidebots' => 'הסתרת בוטים',
 'activeusers-hidesysops' => 'הסתרת מפעילי מערכת',
@@ -2379,7 +2379,7 @@ $1',
 'usermessage-editor' => 'שולח הודעות המערכת',
 
 # Watchlist
-'watchlist' => 'רשימת המעקב שלי',
+'watchlist' => 'רשימת המעקב',
 'mywatchlist' => 'רשימת מעקב',
 'watchlistfor2' => 'עבור $1 $2',
 'nowatchlist' => 'אין דפים ברשימת המעקב.',
@@ -2417,16 +2417,16 @@ $1',
 'enotif_mailer' => 'הודעות {{SITENAME}}',
 'enotif_reset' => 'סימון כל הדפים כאילו נצפו',
 'enotif_impersonal_salutation' => 'משתמש של {{SITENAME}}',
-'enotif_subject_deleted' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נמחק על ידי {{gender:$2|$2}}',
-'enotif_subject_created' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נוצר על ידי {{gender:$2|$2}}',
-'enotif_subject_moved' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} הועבר על ידי {{gender:$2|$2}}',
-'enotif_subject_restored' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שוחזר על ידי {{gender:$2|$2}}',
-'enotif_subject_changed' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שונה על ידי {{gender:$2|$2}}',
-'enotif_body_intro_deleted' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נמחק ב־$PAGEEDITDATE על ידי {{gender:$2|$2}}, ראו $3.',
-'enotif_body_intro_created' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נוצר ב־$PAGEEDITDATE על ידי {{gender:$2|$2}}, ראו $3 לגרסה הנוכחית.',
-'enotif_body_intro_moved' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} הועבר ב־$PAGEEDITDATE על ידי {{gender:$2|$2}}, ראו $3 לגרסה הנוכחית.',
-'enotif_body_intro_restored' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שוחזר ב־$PAGEEDITDATE על ידי {{gender:$2|$2}}, ראו $3 לגרסה הנוכחית.',
-'enotif_body_intro_changed' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שונה ב־$PAGEEDITDATE על ידי {{gender:$2|$2}}, ראו $3 לגרסה הנוכחית.',
+'enotif_subject_deleted' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נמחק על ידי $2',
+'enotif_subject_created' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נוצר על ידי $2',
+'enotif_subject_moved' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} הועבר על ידי $2',
+'enotif_subject_restored' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שוחזר על ידי $2',
+'enotif_subject_changed' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שונה על ידי $2',
+'enotif_body_intro_deleted' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נמחק ב־$PAGEEDITDATE על ידי $2, ראו $3.',
+'enotif_body_intro_created' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} נוצר ב־$PAGEEDITDATE על ידי $2, ראו $3 לגרסה הנוכחית.',
+'enotif_body_intro_moved' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} הועבר ב־$PAGEEDITDATE על ידי $2, ראו $3 לגרסה הנוכחית.',
+'enotif_body_intro_restored' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שוחזר ב־$PAGEEDITDATE על ידי $2, ראו $3 לגרסה הנוכחית.',
+'enotif_body_intro_changed' => 'הדף $1 ב{{grammar:תחילית|{{SITENAME}}}} שונה ב־$PAGEEDITDATE על ידי $2, ראו $3 לגרסה הנוכחית.',
 'enotif_lastvisited' => 'ראו $1 לכל השינויים מאז ביקורכם האחרון.',
 'enotif_lastdiff' => 'ראו $1 לשינוי זה.',
 'enotif_anon_editor' => 'משתמש אנונימי $1',
@@ -2846,7 +2846,7 @@ $1',
 אם תבחרו לא לעשות זאת, אנא ודאו שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|שבורות]].
 אתם אחראים לוודא שכל הקישורים ימשיכו להצביע למקום שאליו הם אמורים להצביע.
 
-ש×\99×\9e×\95 ×\9c×\91: ×\94×\93×£ '''×\9c×\90''' ×\99×\95×¢×\91ר ×\90×\9d ×\9b×\91ר ×\99ש ×\93×£ ×ª×\97ת ×\94ש×\9d ×\94×\97×\93ש, ×\90×\9c×\90 ×\90×\9d ×\94×\93×£ ×\94×\96×\94 הוא הפניה ואין לו היסטוריית עריכות קודמות.
+ש×\99×\9e×\95 ×\9c×\91: ×\94×\93×£ '''×\9c×\90''' ×\99×\95×¢×\91ר ×\90×\9d ×\9b×\91ר ×\99ש ×\93×£ ×ª×\97ת ×\94ש×\9d ×\94×\97×\93ש, ×\90×\9c×\90 ×\90×\9d ×\94×\93×£ ×\94שנ×\99 הוא הפניה ואין לו היסטוריית עריכות קודמות.
 פירוש הדבר שאפשר לשנות חזרה את שמו של דף לשם המקורי אם נעשתה טעות, ושלא ניתן לדרוס דף קיים.
 
 '''אזהרה!'''
@@ -3198,6 +3198,7 @@ $1',
 'pageinfo-robot-noindex' => 'לא יכול להיאסף למפתחות חיפוש',
 'pageinfo-views' => 'מספר הצפיות',
 'pageinfo-watchers' => 'מספר העוקבים אחר הדף',
+'pageinfo-few-watchers' => 'פחות מ{{PLURAL:$1|עוקב אחד|־$1 עוקבים}}',
 'pageinfo-redirects-name' => 'הפניות לדף זה',
 'pageinfo-subpages-name' => 'דפי־משנה של דף זה',
 'pageinfo-subpages-value' => '$1 ({{PLURAL:$2|הפניה אחת|$2 הפניות}}; {{PLURAL:$3|דף רגיל אחד|$3 דפים רגילים}})',
@@ -4036,7 +4037,7 @@ $5
 'specialpages-group-highuse' => 'דפים בשימוש רב',
 'specialpages-group-pages' => 'רשימות דפים',
 'specialpages-group-pagetools' => 'כלים לדפים',
-'specialpages-group-wiki' => 'מידע וכלים על האתר',
+'specialpages-group-wiki' => 'מידע וכלים',
 'specialpages-group-redirects' => 'הפניות מדפים מיוחדים',
 'specialpages-group-spam' => 'כלי ספאם',
 
@@ -4133,8 +4134,8 @@ $5
 'logentry-newusers-newusers' => 'חשבון המשתמש $1 נוצר',
 'logentry-newusers-create' => 'חשבון המשתמש $1 נוצר',
 'logentry-newusers-create2' => 'חשבון המשתמש $3 נוצר על ידי $1',
+'logentry-newusers-byemail' => 'חשבון המשתמש $3 נוצר על ידי $1 והסיסמה נשלחה בדוא"ל',
 'logentry-newusers-autocreate' => 'חשבון המשתמש $1 נוצר אוטומטית',
-'newuserlog-byemail' => 'הסיסמה נשלחה בדוא"ל',
 'logentry-rights-rights' => '$1 שינה את ההרשאות של $3 מ$4 ל$5',
 'logentry-rights-rights-legacy' => '$1 שינה את ההרשאות של $3',
 'logentry-rights-autopromote' => '$1 קודם אוטומטית מ$4 ל$5',
@@ -4192,6 +4193,7 @@ $5
 'api-error-ok-but-empty' => 'שגיאה פנימית: אין תשובה מהשרת.',
 'api-error-overwrite' => 'לא מותרת החלפת קובץ קיים.',
 'api-error-stashfailed' => 'שגיאה פנימית: השרת נכשל באחסון הקובץ הזמני.',
+'api-error-publishfailed' => 'שגיאה פנימית: השרת נכשל בפרסום הקובץ הזמני.',
 'api-error-timeout' => 'השרת לא השיב בזמן המצופה.',
 'api-error-unclassified' => 'אירעה שגיאה בלתי ידועה.',
 'api-error-unknown-code' => 'שגיאה בלתי ידועה: "$1".',
index b607859..8494883 100644 (file)
@@ -19,6 +19,7 @@
  * @author Dineshjk
  * @author Hemant wikikosh1
  * @author Htt
+ * @author InfinityO O
  * @author Kaganer
  * @author Kamal
  * @author Kannankumar
@@ -77,7 +78,7 @@ $specialPageAliases = array(
        'Allmessages'               => array( 'सभी_सन्देश', 'सभी_संदेश' ),
        'Allpages'                  => array( 'सभी_पृष्ठ', 'सभी_पन्ने' ),
        'Ancientpages'              => array( 'पुराने_पृष्ठ', 'पुराने_पन्ने' ),
-       'Badtitle'                  => array( 'खराब_शीर्षक' ),
+       'Badtitle'                  => array( 'à¤\96़राब_शà¥\80रà¥\8dषà¤\95' ),
        'Blankpage'                 => array( 'रिक्त_पृष्ठ', 'खाली_पृष्ठ' ),
        'Block'                     => array( 'अवरोधन', 'आइ_पी_अवरोधन', 'सदस्य_अवरोधन' ),
        'Blockme'                   => array( 'स्वावरोधन', 'स्व_अवरोधन', 'मुझे_रोकिये' ),
@@ -102,6 +103,7 @@ $specialPageAliases = array(
        'Filepath'                  => array( 'फ़ाइल_पथ', 'फाइल_पथ', 'संचिका_पथ' ),
        'Import'                    => array( 'आयात' ),
        'Invalidateemail'           => array( 'अप्रमाणित_ईमेल', 'अमान्य_ईमेल', 'ईमेल_अमान्य_करें' ),
+       'JavaScriptTest'            => array( 'जावा_स्क्रिप्ट_परीक्षा' ),
        'BlockList'                 => array( 'अवरोध_सूची', 'अवरोधित_सदस्य_सूची', 'अवरोधित_आइ_पी_सूची' ),
        'LinkSearch'                => array( 'बाहरी_कड़ी_खोज' ),
        'Listadmins'                => array( 'प्रबन्धक_सूची', 'प्रबंधक_सूची' ),
@@ -118,6 +120,7 @@ $specialPageAliases = array(
        'MIMEsearch'                => array( 'माइम_खोज' ),
        'Mostcategories'            => array( 'सर्वाधिक_श्रेणीकृत', 'सर्वाधिक_श्रेणियाँ' ),
        'Mostimages'                => array( 'सर्वाधिक_प्रयुक्त_फ़ाइलें', 'सर्वाधिक_प्रयुक्त_फाइलें' ),
+       'Mostinterwikis'            => array( 'ज़्यादा_इंटेर्विकियाँ' ),
        'Mostlinked'                => array( 'सर्वाधिक_जुड़े_पृष्ठ' ),
        'Mostlinkedcategories'      => array( 'सर्वाधिक_प्रयुक्त_श्रेणियाँ' ),
        'Mostlinkedtemplates'       => array( 'सर्वाधिक_प्रयुक्त_साँचे' ),
@@ -163,6 +166,10 @@ $specialPageAliases = array(
        'Withoutinterwiki'          => array( 'अन्तरविकि_रहित', 'अंतरविकि_रहित' ),
 );
 
+$magicWords = array(
+       'redirect'                  => array( '0', '#अनुप्रेषित', '#REDIRECT' ),
+);
+
 $digitTransformTable = array(
        '0' => '०', # &#x0966;
        '1' => '१', # &#x0967;
@@ -447,7 +454,7 @@ $1',
 'youhavenewmessagesfromusers' => 'आपके लिये {{PLURAL:$3|एक अन्य सदस्य का सन्देश है|$3 अन्य सदस्यों के सन्देश हैं}}। ($2)',
 'youhavenewmessagesmanyusers' => 'आपके लिये $1 हैं। ($2)',
 'newmessageslinkplural' => '{{PLURAL:$1|एक नया सन्देश|नये सन्देश}}',
-'newmessagesdifflinkplural' => 'à¤\85à¤\82तिम {{PLURAL:$1|परिवर्तन}}',
+'newmessagesdifflinkplural' => 'पिà¤\9bलà¥\87 {{PLURAL:$1|परिवर्तन}}',
 'youhavenewmessagesmulti' => '$1 पर आपके लिए नया संदेश है',
 'editsection' => 'सम्पादन',
 'editold' => 'सम्पादन',
@@ -3847,7 +3854,6 @@ $5
 'logentry-newusers-create' => 'सदस्य खाता $1 बनाया गया',
 'logentry-newusers-create2' => 'सदस्य खाता $3 $1 द्वारा बनाया गया था',
 'logentry-newusers-autocreate' => 'खाते $1 स्वचालित रूप से बनाया गया',
-'newuserlog-byemail' => 'कूटशब्द इ-मेल द्वारा भेजा गया हैं',
 'logentry-rights-rights' => '$1 ने $3 के सदस्य समूह $4 से बदलकर $5 किये',
 'logentry-rights-rights-legacy' => '$1 ने $3 के सदस्य समूह बदले',
 'logentry-rights-autopromote' => '$1 के सदस्य समूह स्वतः $4 से बदलकर $5 किये गए',
index 1f38e0a..c9176a6 100644 (file)
@@ -3239,7 +3239,6 @@ Wahii line pe aur koi jorr exception consider karaa jai i.e. jahaan pe panna sak
 # New logging system
 'revdelete-restricted' => 'sysops pe llabu restrictions',
 'revdelete-unrestricted' => 'sysops se hatawa gae rukawat',
-'newuserlog-byemail' => 'password ke e-mail se bheja gais hai',
 'logentry-rights-rights' => '$1 $3 ke group ke membership ke $4 se badal ke $5 kar dia hae',
 'logentry-rights-rights-legacy' => '$1 $3 ke group membership ke badal dia hae',
 'logentry-rights-autopromote' => '$1 ke apne se $2 se $3 ke promotion dewa gais',
index dfa3649..56dfd2c 100644 (file)
@@ -434,7 +434,7 @@ $messages = array(
 'category-subcat-count-limited' => 'Ova kategorija ima {{PLURAL:$1|podkategoriju|$1 podkategorije|$1 podkategorija}}.',
 'category-article-count' => '{{PLURAL:$2|Ova kategorija sadrži $2 članak.|{{PLURAL:$1|Prikazano je $1 članak|Prikazana su $1 članka|Prikazano je $1 članaka}} od njih $2 ukupno.}}',
 'category-article-count-limited' => '{{PLURAL:$1|stranica je|$1 stranice su|$1 stranica je}} u ovoj kategoriji.',
-'category-file-count' => '{{PLURAL:$2|Ova kategorija sadrži samo sljedeću datoteku.|{{PLURAL:$1|datoteka je|$1 datoteke su|$1 datoteka je}} u ovoj kategoriji, od njih $2 ukupno.}}',
+'category-file-count' => 'Ova kategorija sadrži $2 {{PLURAL:$2|datoteku|datoteke|datoteka}}. {{PLURAL:$1|Slijedi $1 datoteka|Slijede $1 datoteke|Slijedi $1 datoteka}}.',
 'category-file-count-limited' => '{{PLURAL:$1|datoteka je|$1 datoteke su|$1 datoteka su}} u ovoj kategoriji.',
 'listingcontinuesabbrev' => 'nast.',
 'index-category' => 'Indeksirane stranice',
@@ -3983,7 +3983,6 @@ Slike se na taj način prikazuju u punoj rezoluciji, a drugi tipovi datoteka se
 'logentry-newusers-create' => 'Suradnički račun $1 je otvoren.',
 'logentry-newusers-create2' => '$1 je  {{GENDER:$2|otvorio|otvorila}} suradnički račun $3',
 'logentry-newusers-autocreate' => 'Suradnički račun $1 je automatski stvoren',
-'newuserlog-byemail' => 'lozinka poslana e-poštom',
 'logentry-rights-rights' => '$1 {{GENDER:$2|je promijenio|je promijenila}} suradnička prava računa $3 iz $4 u $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$2|je promijenio|je promijenila|je promijenio}} članstvo grupe suradničkog računa $3',
 'logentry-rights-autopromote' => 'Suradničkom računu $1 {{GENDER:$1|je automatski promijenjeno članstvo|su automatski promijenjena članstva}} iz $4 u $5',
index e01379c..c8b66e6 100644 (file)
@@ -11,6 +11,7 @@
  * @author J budissin
  * @author Kaganer
  * @author Michawiki
+ * @author Shirayuki
  * @author Tchoř
  * @author Tlustulimu
  * @author לערי ריינהארט
@@ -419,7 +420,7 @@ $1',
 'newmessagesdifflink' => 'poslednja změna',
 'youhavenewmessagesfromusers' => 'Maš $1 wot {{PLURAL:$3|druheho wužiwarja|$3 wužiwarjow|$3 wužiwarjow|$3 wužiwarjow}} ($2).',
 'youhavenewmessagesmanyusers' => 'Maš $1 wot wjele wužiwarjow ($2).',
-'newmessageslinkplural' => '{{PLURAL:$1|nowa powěsć|nowej powěsći|nowe powěsće|nowe powěsće}}',
+'newmessageslinkplural' => '{{PLURAL:$1|nowu powěsć|nowej powěsći|nowe powěsće}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|poslednja změna|poslednjej změnje|poslednje změny|poslednje změny}}',
 'youhavenewmessagesmulti' => 'Maš nowe powěsće: $1',
 'editsection' => 'wobdźěłać',
@@ -585,7 +586,7 @@ Njezabudź swoje [[Special:Preferences|nastajenja za {{GRAMMAR:akuzatiw|{{SITENA
 'gotaccount' => 'Maš hižo wužiwarske konto? $1.',
 'gotaccountlink' => 'Přizjewić',
 'userlogin-resetlink' => 'Přizjewjenske daty zabył?',
-'createaccountmail' => 'z mejlku',
+'createaccountmail' => 'Nachwilne přidatne hesło wužiwać a jo na slědowacu e-mejlowu adresu pósłać',
 'createaccountreason' => 'Přičina:',
 'badretype' => 'Hesle, kotrejž sy zapodał, so njekryjetej.',
 'userexists' => 'Wužiwarske mjeno, kotrež sy zapodał, so hižo wužiwa.
@@ -860,7 +861,8 @@ Lubiš nam tež, zo sy jón sam napisał abo ze zjawneje domejny abo z podobneho
 
 '''NJESKŁADUJ PŘINOŠKI Z COPYRIGHTOM BJEZ DOWOLNOSĆE!'''",
 'longpageerror' => "'''ZMYLK: Tekst, kotryž pospytuješ składować, je {{PLURAL:$1| jedyn kilobajt|$1 kilobajtaj|$1 kilobajty|$1 kilobajtow}} dołho, maksimalna wulkosć pak je {{PLURAL:$2|jedyn kilobajt|$1 kilobajtaj|$1 kilobajty|$1 kilobajtow}}.''' Njehodźi so składować.",
-'readonlywarning' => "'''KEDŹBU: Datowa banka bu wothladanja dla zawrjena, tohodla njemóžeš swoje změny nětko składować. Móžeš tekst do tekstoweje dataje přesunyć a jón za pozdźišo składować.'''
+'readonlywarning' => "'''KEDŹBU: Datowa banka bu wothladowanja dla zawrjena, tohodla njemóžeš swoje změny nětko składować.'''
+Móžeš tekst do tekstoweje dataje kopěrować a jón za pozdźišo składować.
 
 Administrator, kiž je ju zawrjena, je tutu přičinu podał: $1",
 'protectedpagewarning' => "'''KEDŹBU: Tuta strona bu zawrjena, tak zo jenož wužiwarjo z prawami administratora móža ju wobdźěłać.'''
@@ -946,7 +948,7 @@ Přičina za blokowanje, podata wot $3, je: ''$2''",
 'nohistory' => 'Njeje žanych staršich wersijow strony.',
 'currentrev' => 'Aktualna wersija',
 'currentrev-asof' => 'Aktualna wersija wot $1',
-'revisionasof' => 'Wersija z $1',
+'revisionasof' => 'Wersija wot $1',
 'revision-info' => 'Wersija wot $1 wužiwarja $2',
 'previousrevision' => '← Starša wersija',
 'nextrevision' => 'Nowša wersija →',
@@ -1104,7 +1106,7 @@ Zawěsć, zo tuta změna stawiznisku kontinuitu strony wobchowuje.',
 
 # Diffs
 'history-title' => '$1: Wersijowe stawizny',
-'difference-title' => '$1: Rozdźěl mjez wersijemi',
+'difference-title' => '$1: Rozdźěl mjez wersijomaj',
 'difference-title-multipage' => '$1 a $2: Rozdźěl mjez stronami',
 'difference-multipage' => '(Rozdźěl mjez stronami)',
 'lineno' => 'Rjadka $1:',
@@ -1160,7 +1162,7 @@ Podrobnosće móžeš w [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}
 'search-interwiki-default' => '$1 wuslědki:',
 'search-interwiki-more' => '(dalše)',
 'search-relatedarticle' => 'Přiwuzne',
-'mwsuggest-disable' => 'Namjety AJAX znjemóžnić',
+'mwsuggest-disable' => 'Pytanske namjety znjemóžnić',
 'searcheverything-enable' => 'We wšěch mjenowych rumach pytać',
 'searchrelated' => 'přiwuzny',
 'searchall' => 'wšě',
@@ -2055,7 +2057,7 @@ Znajmjeńša hłowna domena je trěbna, na přikład "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Lisćina aktiwnych wužiwarjow',
 '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|změna|změnje|změny|změnow}} w {{PLURAL:$3|zańdźenej dnju|zańdźenymaj $3 dnjomaj|zańdźenych $3 dnjach|zańdźenych $3 dnjach}}',
+'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ć',
@@ -2117,7 +2119,7 @@ E-mejlowa adresa, kotruž sy w [[Special:Preferences|swojich wužiwarskich nasta
 'usermessage-editor' => 'Systemowy powěstnik',
 
 # Watchlist
-'watchlist' => 'wobkedźbowanki',
+'watchlist' => 'Wobkedźbowanki',
 'mywatchlist' => 'Wobkedźbowanki',
 'watchlistfor2' => 'Za wužiwarja $1 $2',
 'nowatchlist' => 'Nimaš žane strony w swojich wobkedźbowankach.',
@@ -2563,11 +2565,11 @@ Hlej [[Special:BlockList|lisćinu blokowanjow]], zo by zablokowanjow pruwował.'
 # Move page
 'move-page' => '$1 přesunyć',
 'move-page-legend' => 'Stronu přesunyć',
-'movepagetext' => 'Wužiwanje formulara deleka budźe stronu přemjenować, suwajo jeje cyłe stawizny pod nowe mjeno. Stary titl budźe daleposrědkowanje na nowy titl. Wotkazy na stary titl so njezměnja. Pruwuj za dwójnymi abo skóncowanymi daleposrědkowanjemi. Dyrbiš zaručić, zo wotkazy na stronu pokazuja, na kotruž dyrbja dowjesć.
+'movepagetext' => "Wužiwanje formulara deleka budźe stronu přemjenować, suwajo jeje cyłe stawizny pod nowe mjeno. Stary titl budźe daleposrědkowanje na nowy titl.  Móžeš dalesposrědkowanja, kotrež na prěnjotny titl pokazać, awtomatisce aktualizować. Pruwuj za [[Special:DoubleRedirects|dwójnymi]] abo [[Special:BrokenRedirects|skóncowanymi daleposrědkowanjemi]]. Dyrbiš zaručić, zo wotkazy na stronu pokazuja, na kotruž dyrbja dowjesć.
 
-Wobkedźbuj, zo strona so <b>nje</b> přesunje, jeli strona z nowym titlom hizo eksistuje, chibazo wona je prózdna abo dalesposrědkowanje a nima zašłe stawizny. To woznamjenja, zo móžeš stronu tam wróćo přemjenować, hdźež bu runje přemjenowana, jeli zmylk činiš a njemóžeš wobstejacu stronu přepisować.
+Wobkedźbuj, zo strona so '''nje'''přesunje, jeli strona z nowym titlom hizo eksistuje, chibazo poslednja je dalesposrědkowanje a nima zašłe stawizny. To woznamjenja, zo móžeš stronu tam wróćo přemjenować, hdźež bu runje přemjenowana, jeli zmylk činiš a njemóžeš wobstejacu stronu přepisować.
 
-<b>KEDŹBU!</b> Móže to drastiska a njewočakowana změna za woblubowanu stronu być; prošu budź sej wěsty, zo sćěwki rozumiš, prjedy hač pokročuješ.',
+'''Kedźbu!''' Móže to drastiska a njewočakowana změna za woblubowanu stronu być; prošu budź sej wěsty, zo sćěwki rozumiš, prjedy hač pokročuješ.",
 'movepagetext-noredirectfixer' => "Wužiwajo slědowacy formular, móžeš stronu přemjenować a wšě jich daty do stawiznow noweho titula přesunyć.
 Stary titul budźe dalesposrědkowanska strona k nowemu titulej.
 Skontroluj za [[Special:DoubleRedirects|dwójnymi]] abo [[Special:BrokenRedirects|wobškodźenymi dalesposrědkowanjemi]].
@@ -2878,6 +2880,7 @@ W poslednim padźe móžeš tež wotkaz wužiwać, na př. „[[{{#Special:Expor
 'pageinfo-robot-noindex' => 'Njeindeksujomny',
 'pageinfo-views' => 'Ličba zwobraznjenjow',
 'pageinfo-watchers' => 'Ličba wobkedźbowarjow strony',
+'pageinfo-few-watchers' => 'Mjenje hač $1 {{PLURAL:$1|wobkedźbowar|wobkedźbowarjej|wobkedźbowarje|wobkedźbowarjow}}',
 'pageinfo-redirects-name' => 'Dalesposrědkowanja k tutej stronje',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Podstrony tuteje strony',
@@ -3462,9 +3465,9 @@ $5
 
 Tute wobkrućenski kod spadnje $4.',
 'confirmemail_body_set' => 'Něchtó, najskerje ty, wot IP-adresy $1,
-je e-mejlowu adresu konta "$2" na {{GRAMMAR:lokatiw|{{STENAME}}}} na tutu adresu stajił.
+je e-mejlowu adresu konta "$2" na {{GRAMMAR:lokatiw|{{SITENAME}}}} na tutu adresu stajił.
 
-Zo by wobkrućił, zo tute konto ći woprawdźe słuša a zo bychu so e-mejlowe funkcije na {{GRAMMAR:lokatiw|{{STENAME}}}} znowa aktiwizowali, wočiń tutón wotkaz w swojim wobhladowaku:
+Zo by wobkrućił, zo tute konto ći woprawdźe słuša a zo bychu so e-mejlowe funkcije na {{GRAMMAR:lokatiw|{{SITENAME}}}} znowa aktiwizowali, wočiń tutón wotkaz w swojim wobhladowaku:
 
 $3
 
@@ -3642,7 +3645,7 @@ Wobrazy so połnym rozeznaću pokazuja, druhe datajowe typy so ze zwjazanym prog
 'specialpages-group-highuse' => 'Často wužiwane strony',
 'specialpages-group-pages' => 'Lisćiny stronow',
 'specialpages-group-pagetools' => 'Nastroje stronow',
-'specialpages-group-wiki' => 'Wikijowe daty a nastroje',
+'specialpages-group-wiki' => 'Daty a nastroje',
 'specialpages-group-redirects' => 'Daleposrědkowace specialne strony',
 'specialpages-group-spam' => 'Spamowe nastroje',
 
@@ -3739,8 +3742,8 @@ Wobrazy so połnym rozeznaću pokazuja, druhe datajowe typy so ze zwjazanym prog
 'logentry-newusers-newusers' => 'Wužiwarske konto $1 je so załožiło',
 'logentry-newusers-create' => 'Wužiwarske konto $1 je so załožiło',
 'logentry-newusers-create2' => '$1 załoži wužiwarske konto $3',
+'logentry-newusers-byemail' => 'Wužiwarske konto $3 je so wot $1 załožiło a hesło je so přez e-mejl pósłało.',
 'logentry-newusers-autocreate' => 'Konto $1 je so awtomatisce załožiło',
-'newuserlog-byemail' => 'Hesło z e-mejlku pósłane',
 'logentry-rights-rights' => '$1 změni skupinske čłonstwo za $3 z $4 do $5',
 'logentry-rights-rights-legacy' => '$1 změni skupinske čłonstwo za $3',
 'logentry-rights-autopromote' => '$1 powyši so awtomatisce wot $4 do $5',
@@ -3798,6 +3801,7 @@ Hewak móžeš slědowacy jednory formular wužiwać. Twój komentar přida so s
 'api-error-ok-but-empty' => 'Nutřkowny zmylk: žana wotmołwa wot serwera.',
 'api-error-overwrite' => 'Přepisowanje eksistowaceje dataje njeje dowolene.',
 'api-error-stashfailed' => 'Nutřkowny zmylk: Serwer njemóžeše nachwilnu dataju składować.',
+'api-error-publishfailed' => 'Nutřkowny zmylk: Serwer njemóžeše nachwilnu dataju wozjewić.',
 'api-error-timeout' => 'Serwer njeje znutřka wočakowaneho časa wotmołwił.',
 'api-error-unclassified' => 'Njeznaty zmylk je wustupił.',
 'api-error-unknown-code' => 'Njeznaty zmylk: "$1"',
index 8c180d1..33548dd 100644 (file)
@@ -1384,6 +1384,5 @@ Nenpòt lòt lyen nan menm liy nan konsidere kòm yon eksèpsyon, i.e. paj kote
 
 # New logging system
 'revdelete-restricted' => 'aplike restriksyon sa yo pou administratè yo',
-'newuserlog-byemail' => 'mopas an voye pa imèl',
 
 );
index ecbcb8a..fdb1293 100644 (file)
@@ -16,6 +16,7 @@
  * @author BáthoryPéter
  * @author CERminator
  * @author Cerasus
+ * @author Csigabi
  * @author Dani
  * @author Dj
  * @author Dorgan
@@ -319,7 +320,7 @@ $messages = array(
 'tog-hidepatrolled' => 'Az ellenőrzött szerkesztések elrejtése a friss változtatások lapon',
 'tog-newpageshidepatrolled' => 'Ellenőrzött lapok elrejtése az új lapok listájáról',
 'tog-extendwatchlist' => 'A figyelőlistán az összes változtatás látszódjon, ne csak az utolsó',
-'tog-usenewrc' => 'Fejlettebb friss változások használata (JavaScript-alapú)',
+'tog-usenewrc' => 'Szerkesztések csoportosítása oldal szerint a friss változtatásokban és a figyelőlistán (JavaScript-alapú)',
 'tog-numberheadings' => 'Fejezetcímek automatikus számozása',
 'tog-showtoolbar' => 'Szerkesztőeszközsor megjelenítése (JavaScript-alapú)',
 'tog-editondblclick' => 'A lapok szerkesztése dupla kattintásra (JavaScript-alapú)',
@@ -445,6 +446,7 @@ $messages = array(
 'newwindow' => '(új ablakban nyílik meg)',
 'cancel' => 'Mégse',
 'moredotdotdot' => 'Tovább…',
+'morenotlisted' => 'Tovább…',
 'mypage' => 'Lapom',
 'mytalk' => 'Vitalap',
 'anontalk' => 'Az IP-címhez tartozó vitalap',
@@ -743,7 +745,7 @@ Ne felejtsd el módosítani a [[Special:Preferences|{{SITENAME}} beállításaid
 'gotaccount' => "Ha már korábban regisztráltál, '''$1'''!",
 'gotaccountlink' => 'Bejelentkezés',
 'userlogin-resetlink' => 'Elfelejtetted a bejelentkezési adataidat?',
-'createaccountmail' => 'e-mailben',
+'createaccountmail' => 'Átmeneti, véletlenszerű jelszó használata és kiküldése az alábbi e-mail címre',
 'createaccountreason' => 'Indoklás:',
 'badretype' => 'A megadott jelszavak nem egyeznek.',
 'userexists' => 'A megadott felhasználónév már foglalt.
@@ -816,6 +818,7 @@ Várj egy kicsit, mielőtt újra próbálkozol.',
 # E-mail sending
 'php-mail-error-unknown' => 'Ismeretlen hiba a PHP mail() függvényében',
 'user-mail-no-addy' => 'E-mail üzenetet próbáltál küldeni e-mail cím megadása nélkül.',
+'user-mail-no-body' => 'Üres vagy nagyon rövid email-t próbáltál küldeni.',
 
 # Change password dialog
 'resetpass' => 'Jelszó módosítása',
@@ -847,7 +850,7 @@ Lehet, hogy már sikeresen megváltoztattad a jelszavad, vagy pedig időközben
 'passwordreset-capture-help' => 'Ha kipipálod a dobozt, amellett, hogy kiküldődik az üzenet a felhasználónak, megjelenik számodra (az ideiglenes jelszavakkal együtt)',
 'passwordreset-email' => 'E-mail cím:',
 'passwordreset-emailtitle' => 'A(z) {{SITENAME}}-fiók adatai',
-'passwordreset-emailtext-ip' => 'Valaki (vélhetően Te, a $1 IP-címrő)l emlékeztetők kért a {{SITENAME}} ($4) oldalon felvett fiókokról. A következő felhasználói {{PLURAL:$3|fiók van|fiókok vannak}} hozzárendelve ehhez az e-mail címhez:
+'passwordreset-emailtext-ip' => 'Valaki (vélhetően Te, a $1 IP-címről) emlékeztetőt kért a {{SITENAME}} ($4) oldalon felvett fiókokról. A következő felhasználói {{PLURAL:$3|fiók van|fiókok vannak}} hozzárendelve ehhez az e-mail címhez:
 
 $2
 
@@ -857,7 +860,7 @@ $2
 $2
 
 {{PLURAL:$3|Ez az ideiglenes jelszó|Ezek az ideiglenes jelszavak}} $5 nap múlva {{PLURAL:$3|jár|járnak}} le. Jelentkezz be, és cseréld le a jelszavadat. Ha valaki más kérte az emlékeztetőt, vagy eszedbe jutott a régi jelszó, és nem akarod lecserélni a jelszavadat, hagyd figyelmen kívül ezt az üzenetet, és használd a régi jelszavadat.',
-'passwordreset-emailelement' => 'Felhaználónév: $1
+'passwordreset-emailelement' => 'Felhasználónév: $1
 Ideiglenes jelszó: $2',
 'passwordreset-emailsent' => 'Emlékeztető e-mail elküldve.',
 'passwordreset-emailsent-capture' => 'Az alább látható emlékeztető e-mail elküldve.',
@@ -1034,8 +1037,8 @@ Azt is megígéred, hogy ezt magadtól írtad, vagy egy közkincsből vagy más
 '''NE KÜLDJ BE JOGVÉDETT MUNKÁT ENGEDÉLY NÉLKÜL!'''",
 '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}}.
 A szerkesztést nem lehet elmenteni.'''",
-'readonlywarning' => "'''FIGYELMEZTETÉS: A wiki adatbázisát karbantartás miatt zárolták, ezért most nem fogod tudni elmenteni a szerkesztéseidet.
-A lap szöveget kimásolhatod egy szövegfájlba, amit elmenthetsz későbbre.'''
+'readonlywarning' => "FIGYELMEZTETÉS: A wiki adatbázisát karbantartás miatt zárolták, ezért most nem fogod tudni elmenteni a szerkesztéseidet!
+A lap szövegét másold egy szövegfájlba, amit később felhasználhatsz!'''
 
 Az adatbázist lezáró adminisztrá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.'''
@@ -1333,7 +1336,7 @@ Ezt általában egy elavult, törölt oldalra mutató laptörténeti hivatkozás
 'search-interwiki-default' => '$1 találat',
 'search-interwiki-more' => '(több)',
 'search-relatedarticle' => 'Kapcsolódó',
-'mwsuggest-disable' => 'AJAX-alapú keresési javaslatok letiltása',
+'mwsuggest-disable' => 'Keresési javaslatok letiltása',
 'searcheverything-enable' => 'Keresés az összes névtérben',
 'searchrelated' => 'kapcsolódó',
 'searchall' => 'mind',
@@ -2229,7 +2232,7 @@ Támogatott {{PLURAL:$2|protokoll|protokollok}}: <code>$1</code> (http:// az ala
 # Special:ActiveUsers
 'activeusers' => 'Aktív szerkesztők listája',
 'activeusers-intro' => 'Ez a lap azon felhasználók listáját tartalmazza, akik csináltak valamilyen tevékenységet az elmúlt {{PLURAL:$1|egy|$1}} napban.',
-'activeusers-count' => '{{PLURAL:$1|egy|$1}} szerkesztés az utolsó {{PLURAL:$3|egy|$3}} napban',
+'activeusers-count' => '$1 szerkesztés az utolsó $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',
@@ -2759,11 +2762,11 @@ ha nem teszed, ellenőrizd a [[Special:DoubleRedirects|dupla]] vagy [[Special:Br
 Neked kell biztosítanod, hogy a linkek továbbra is oda mutassanak, ahová mutatniuk kell.
 
 A lap '''nem''' nevezhető át, ha már van egy ugyanilyen című lap, hacsak nem üres vagy átirányítás, és nincs laptörténete.
-Ez azt jelenti, hogy vissza tudsz nevezni egy tévedésből átnevezett lapot, és nem tudsz egy már létező lapot véletlenül felülírni.
+Ez azt jelenti, hogy vissza tudsz nevezni egy tévedésből átnevezett lapot, és nem tudsz létező lapot véletlenül felülírni.
 
 '''FIGYELEM!'''
 Népszerű oldalak esetén ez drasztikus és nem várt változtatás lehet;
-győződj meg a folytatás előtt arról, hogy tisztában vagy-e a következményekkel.",
+győződj meg a folytatás előtt arról, hogy tisztában vagy a következményekkel.",
 'movepagetext-noredirectfixer' => "Az alábbi űrlap használatával nevezhetsz át egy lapot, és helyezheted át teljes laptörténetét az új nevére.
 A régi cím az új címre való átirányítás lesz.
 Ellenőrizd a [[Special:DoubleRedirects|dupla]] és a [[Special:BrokenRedirects|hibás átirányításoknál]], hogy a linkek továbbra is oda mutatnak, ahová mutatniuk kell.
@@ -3109,6 +3112,7 @@ Ez valószínűleg egy olyan link miatt van, ami egy feketelistán lévő oldalr
 'pageinfo-robot-noindex' => 'Nem indexelhető',
 'pageinfo-views' => 'Megtekintések száma',
 'pageinfo-watchers' => 'Figyelők száma',
+'pageinfo-few-watchers' => 'Kevesebb mint $1 szerkesztő figyeli',
 'pageinfo-redirects-name' => 'Átirányítások erre a lapra',
 'pageinfo-subpages-name' => 'Az lap allapjai',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|átirányítás}}; $3 {{PLURAL:$3|nem átirányítás}})',
@@ -3129,6 +3133,7 @@ Ez valószínűleg egy olyan link miatt van, ami egy feketelistán lévő oldalr
 'pageinfo-contentpage' => 'Tartalmi lapnak számít',
 'pageinfo-contentpage-yes' => 'Igen',
 'pageinfo-protect-cascading-yes' => 'Igen',
+'pageinfo-category-info' => 'Kategória információk',
 'pageinfo-category-pages' => 'Lapok száma',
 'pageinfo-category-subcats' => 'Alkategóriák száma',
 'pageinfo-category-files' => 'Fájlok száma',
@@ -3970,8 +3975,8 @@ A képek teljes méretben jelennek meg, más fájltípusok közvetlenül a hozz
 'logentry-newusers-newusers' => '$1 felhasználói fiók létrehozva',
 'logentry-newusers-create' => '$1 felhasználói fiók létrehozva',
 'logentry-newusers-create2' => '$1 létrehozta $3 felhasználói fiókját',
+'logentry-newusers-byemail' => 'Szerkesztői lap $3 néven létrehozva $1 által, jelszó kiküldve emailben.',
 'logentry-newusers-autocreate' => '$1 fiók automatikusan létrehozva',
-'newuserlog-byemail' => 'a jelszót kiküldtük a megadott e-mail címre',
 'logentry-rights-rights' => '$1 megváltoztatta $3 csoport tagságát erről: $4 erre: $5',
 'logentry-rights-rights-legacy' => '$1 megváltoztatta $3 csoport tagságát',
 'logentry-rights-autopromote' => '$1 automatikusan előléptetve erről: $4 erre: $5',
@@ -4028,6 +4033,7 @@ A képek teljes méretben jelennek meg, más fájltípusok közvetlenül a hozz
 'api-error-ok-but-empty' => 'Belső hiba: nem érkezett válasz a kiszolgálótól.',
 'api-error-overwrite' => 'Létező fájlok felülírására nem engedélyezett.',
 'api-error-stashfailed' => 'Belső hiba: a kiszolgálünak nem sikerült eltárolni az ideiglenes fájlt.',
+'api-error-publishfailed' => 'Belső hiba: a kiszolgálónak nem sikerült közzétennie az ideiglenes fájlt.',
 'api-error-timeout' => 'A kiszolgáló nem adott választ a várt időn belül.',
 'api-error-unclassified' => 'Ismeretlen hiba történt',
 'api-error-unknown-code' => 'Ismeretlen hiba: „$1”',
index adfda36..c26eab9 100644 (file)
@@ -202,7 +202,7 @@ $specialPageAliases = array(
        'Allmessages'               => array( 'Բոլորուղերձները' ),
        'Allpages'                  => array( 'Բոլորէջերը' ),
        'Ancientpages'              => array( 'Ամենահինէջերը' ),
-       'Block'                     => array( 'Արգելափակելip' ),
+       'Block'                     => array( 'Արգելափակել այփին' ),
        'Blockme'                   => array( 'Արգելափակել' ),
        'Booksources'               => array( 'Գրքայինաղբյուրները' ),
        'BrokenRedirects'           => array( 'Կոտրվածվերահղումները' ),
@@ -216,7 +216,7 @@ $specialPageAliases = array(
        'Export'                    => array( 'Արտահանելէջերը' ),
        'FileDuplicateSearch'       => array( 'Կրկնօրինակֆայլերիորոնում' ),
        'Import'                    => array( 'Ներմուծել' ),
-       'BlockList'                 => array( 'ԱրգելափակվածIPները' ),
+       'BlockList'                 => array( 'Արգելափակված այփի ները' ),
        'Listadmins'                => array( 'Ադմիններիցանկը' ),
        'Listfiles'                 => array( 'Պատկերներիցանկը' ),
        'Listredirects'             => array( 'Ցույցտալվերահղումները' ),
@@ -486,7 +486,7 @@ $messages = array(
 'categorypage' => 'Դիտել կատեգորիայի էջը',
 'viewtalkpage' => 'Դիտել քննարկումը',
 'otherlanguages' => 'Այլ լեզուներով',
-'redirectedfrom' => '(Վերահղված է $1-ից)',
+'redirectedfrom' => '(Վերահղված է $1ից)',
 'redirectpagesub' => 'Վերահղման էջ',
 'lastmodifiedat' => 'Այս էջը վերջին անգամ փոփոխվել է $2, $1։',
 'viewcount' => 'Այս էջին դիմել են {{PLURAL:$1|մեկ անգամ|$1 անգամ}}։',
@@ -539,7 +539,7 @@ $1',
 'youhavenewmessagesmulti' => 'Դուք նոր ուղերձներ եք ստացել $1 վրա',
 'editsection' => 'խմբագրել',
 'editold' => 'խմբագրել',
-'viewsourceold' => 'Õ¤Õ«Õ¿Õ¥Õ¬ Õ¥Õ¬Õ¡Õ¿Õ¥Ö\84Õ½Õ¿ը',
+'viewsourceold' => 'Õ¤Õ«Õ¿Õ¥Õ¬ Õ¾Õ«Ö\84Õ«Õ¯Õ¸Õ¤Õ¥Ö\80ը',
 'editlink' => 'խմբագրել',
 'viewsourcelink' => 'դիտել ելատեքստը',
 'editsectionhint' => 'Խմբագրել բաժինը. $1',
@@ -615,7 +615,7 @@ $1',
 'missingarticle-diff' => '(Տարբ. $1, $2)',
 'readonly_lag' => 'Տվյալների բազան ավտոմատիկ կողպվել է ժամանակավորապես՝ մինչև ՏԲ-ի երկրորդական սերվերը չհամաժամանակեցվի առաջնայինի հետ։',
 'internalerror' => 'Ներքին սխալ',
-'internalerror_info' => 'Ներքին սխալ. $1',
+'internalerror_info' => 'Ներքին սխալ՝ $1',
 'fileappenderror' => 'Չհաջողվեց ավելացնել «$1» «$2»-ին։',
 'filecopyerror' => 'Չհաջողվեց պատճենել «$1» նիշքը «$2» նիշքի մեջ։',
 'filerenameerror' => 'Չհաջողվեց «$1» նիշքը վերանվանել «$2»։',
@@ -635,9 +635,9 @@ $1',
 'perfcachedts' => 'Հետևյալ տվյալները վերցված են քեշից և վերջին անգամ թարմացվել են $1։ A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.',
 'querypage-no-updates' => 'Այս էջի փոփոխությունները ներկայումս արգելված են։ Այստեղի տվյալները այժմ չեն թարմացվի։',
 'wrong_wfQuery_params' => 'Անթույլատրելի պարամետրեր wfQuery() ֆունկցիայի համար<br />
-Ֆունկցիա. $1<br />
-Հայցում. $2',
-'viewsource' => 'Ô´Õ«Õ¿Õ¥Õ¬ Õ¥Õ¬Õ¡Õ¿Õ¥Ö\84Õ½Õ¿ը',
+Ֆունկցիա՝ $1<br />
+Հայցում՝ $2',
+'viewsource' => 'Ô´Õ«Õ¿Õ¥Õ¬ Õ¾Õ«Ö\84Õ«Õ¯Õ¸Õ¤Õ¥Ö\80ը',
 'viewsource-title' => 'Դիտել $1 էջի աղբյուրը',
 'actionthrottled' => 'Գործողությունը արգելափակվեց',
 'actionthrottledtext' => 'Որպես հակա-սպամային միջոց, այս գործողության չափից շատ կատարումը կարճ ժամանակահատվածի ընթացքում սահմանափակված է։ Խնդրում ենք փորձել կրկին մի քանի րոպե անց։',
@@ -645,8 +645,8 @@ $1',
 'viewsourcetext' => 'Դուք կարող եք դիտել և պատճենել այս էջի ելատեքստը.',
 'viewyourtext' => 'Դուք կարող եք դիտել «ձեր ներդրումների» աղբյուրը և պատճենել այս էջ',
 'protectedinterface' => 'Այս էջը պարունակում է ծրագրային ապահովման ինտերֆեյսի ուզերձ և կողպված է չարաշահումների կանխարգելման նպատակով։.',
-'editinginterface' => "'''Զգուշացում.''' Դուք խմբագրում եք ծրագրային ապահովման ինտերֆեյսի տեքստ պարունակող էջ։ Այս էջի փոփոխությունը կանդրադառնա այլ մասնակիցներին տեսանելի ինտերֆեյսի տեսքի վրա։
-Թարգմանությունների համար նախընտրելի է օգտագործել [//translatewiki.net/wiki/Main_Page?setlang=hy translatewiki.net]՝ MediaWiki ծրագրի տեղայնացման նախագիծը։",
+'editinginterface' => "'''Զգուշացում՝''' Դուք խմբագրում եք ծրագրային ապահովման ինտերֆեյսի տեքստ պարունակող էջ։ Այս էջի փոփոխությունը կանդրադառնա այլ մասնակիցներին տեսանելի ինտերֆեյսի տեսքի վրա։
+Թարգմանությունների համար նախընտրելի է օգտագործել [//translatewiki.net/wiki/Main_Page?setlang=hy translatewiki.net]՝ Մեդիավիքի ծրագրի տեղայնացման նախագիծը։",
 'sqlhidden' => '(SQL հայցումը թաքցված է)',
 'cascadeprotected' => 'Այս էջը պաշտպանված է խմբագրումից, քանի որ ընդգրկված է հետևյալ {{PLURAL:$1|էջի|էջերի}} տեքստում, {{PLURAL:$1|որը|որոնք}} պաշտպանվել {{PLURAL:$1|է|են}} կասկադային հնարավորությամբ.
 $2',
@@ -662,7 +662,7 @@ $2',
 # Virus scanner
 'virus-badscanner' => "Սխալ կարգավորւմ։ Անծանոթ վիրուսների զննիչ. ''$1''",
 'virus-scanfailed' => 'զննման սխալ (կոդ $1)',
-'virus-unknownscanner' => 'անծանոթ հակավիրուս.',
+'virus-unknownscanner' => 'անծանոթ հակավիրուս՝',
 
 # Login and logout pages
 'logouttext' => "'''Դուք դուրս եկաք համակարգից։'''
@@ -671,11 +671,11 @@ $2',
 'welcomeuser' => 'Բարի գալո՜ւստ, $1',
 'welcomecreation-msg' => 'Ձեր հաշիվն ստեղծված է։
 Չմոռանաք փոփոխել ձեր [[Special:Preferences|նախընտրությունները]]։',
-'yourname' => 'Մասնակցի անուն.',
+'yourname' => 'Մասնակցի անուն՝',
 'yourpassword' => 'Գաղտնաբառ.',
-'yourpasswordagain' => 'Կրկնեք գաղտնաբառը.',
+'yourpasswordagain' => 'Կրկնեք գաղտնաբառը',
 'remembermypassword' => 'Հիշել իմ մուտքագրված տվյալները այս համակարգչում ($1 {{PLURAL:$1|օրից|օրից}} ոչ ավել ժամկետով)',
-'yourdomainname' => 'Ձեր դոմենը.',
+'yourdomainname' => 'Ձեր դոմենը՝',
 'password-change-forbidden' => 'Այս վիքիում չեք կարող փոխել գաղտնաբառ։',
 'externaldberror' => 'Տեղի է ունեցել վավերացման արտաքին տվյալների բազայի սխալ, կամ դուք չունեք բավարար իրավունքներ ձեր արտաքին հաշվի փոփոխման համար։',
 'login' => 'Մտնել համակարգ',
@@ -693,7 +693,7 @@ $2',
 'gotaccountlink' => 'Մուտք գործեք համակարգ',
 'userlogin-resetlink' => 'Մոռացե՞լ եք Ձեր լոգին տվյալները։',
 'createaccountmail' => 'էլ-փոստով',
-'createaccountreason' => 'Պատճառ.',
+'createaccountreason' => 'Պատճառը՝',
 'badretype' => 'Ձեր մուտքագրած գաղտնաբառերը չեն համընկնում։',
 'userexists' => 'Այս մասնակցի անունը արդեն զբաղված է։ Խնդրում ենք ընտրել մեկ այլ անուն։',
 'loginerror' => 'Մուտքի սխալ',
@@ -730,7 +730,7 @@ $2',
 'eauthentsent' => 'Նոր էլ-հասցեին ուղարկվել է վավերացման նամակ։
 Հետևե՛ք նամակի ցուցումներին՝ հաստատելու համար, որ այդ հասցեն ձեզ է պատկանում։ Մինչ այդ նոր հասցեին այլ նամակներ չեն կարող ուղարկվել։',
 'throttled-mailpassword' => 'Գաղտնաբառի հիշեցման ուղերձ արդեն ուղարկվել է վերջին {{PLURAL:$1|ժամվա|$1 ժամվա}} ընթացքում։ Չարաշահման կանխարգելման նպատակով թույլատրվում է միայն մեկ գաղտնաբառի հիշեցում ամեն {{PLURAL:$1|ժամվա|$1 ժամվա}} ընթացքում։',
-'mailerror' => 'Փոստի ուղարկման սխալ. $1',
+'mailerror' => 'Փոստի ուղարկման սխալ՝ $1',
 'acct_creation_throttle_hit' => 'Վերջին օրվա ընթացքում ձեր IP-հասցեից ստեղծվել է {{PLURAL:$1|1 մասնակցի հաշվիվ|$1 մասնակցի հաշվիվ}}, ինչը այս ժամանակաշրջանում առավելագույն թույլատրելի քանակն է։
 Այս պատճառով այդ IP-հասցեից այցելուները չեն կարող այլևս հաշիվ ստեղծել այս պահին։',
 'emailauthenticated' => 'Ձեր էլ-փոստի հասցեն վավերացվել է $2, $3-ին։',
@@ -748,7 +748,7 @@ $2',
 'usernamehasherror' => 'Մասնակցի անունը չի կարող պարունակել «#» նիշը։',
 'login-throttled' => 'Դուք կատարել եք չափից շատ մուտքի փորձ։
 Խնդրում ենք սպասել որոշ ժամանակ կրկին փորձելուց առաջ։',
-'loginlanguagelabel' => 'Լեզու $1',
+'loginlanguagelabel' => 'Լեզու՝ $1',
 
 # E-mail sending
 'php-mail-error-unknown' => 'Անհայտ սխալ PHP-ի mail() ֆունկցիայում',
@@ -777,10 +777,10 @@ $2',
 'passwordreset-text' => 'Լրացրեք ձևը՝ էլ-փոստով ձեր տվյալների մասին հիշեցում ստանալու համար։',
 'passwordreset-legend' => 'Վերականգնել գաղտնաբառը',
 'passwordreset-disabled' => 'Գաղտնաբառի վերականգնումը այս վիքիում թույլատրված չէ։',
-'passwordreset-username' => 'Մասնակցի անուն.',
+'passwordreset-username' => 'Մասնակցի անուն՝',
 'passwordreset-email' => 'Էլ-փոստի հասցեն՝',
-'passwordreset-emailelement' => 'Մասնակցային անուն. $1
-Ժամանակավոր գաղտնաբառ. $2',
+'passwordreset-emailelement' => 'Մասնակցային անունը՝ $1
+Ժամանակավոր գաղտնաբառը՝ $2',
 'passwordreset-emailsent' => 'Ուղարկվեց հիշեցնող էլ․ նամակ։',
 'passwordreset-emailsent-capture' => 'Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։',
 'passwordreset-emailerror-capture' => 'Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։ Սակայն մասնակցին ուղարկելը չհաջողվեց․',
@@ -791,6 +791,7 @@ $2',
 'changeemail-oldemail' => 'Ներկա էլ․ հասցե․',
 'changeemail-newemail' => 'Նոր էլ․ հասցե․',
 'changeemail-none' => '(ոչ մի)',
+'changeemail-password' => 'Քո {{SITENAME}} գաղտնաբառը՝',
 'changeemail-submit' => 'Փոխել էլ․ հասցեն',
 'changeemail-cancel' => 'Չեղարկել',
 
@@ -919,10 +920,10 @@ $2',
 
 '''Եթե սա բարեխիղճ խմբագրման փորձ է, խնդրում ենք փորձել կրկին։ Սխալի կրկնման դեպքում՝ փորձեք [[Special:UserLogout|դուրս գալ]], ապա կրկին մտնել համակարգ։'''",
 'token_suffix_mismatch' => "'''Ձեր խմբագրումը մերժվել է, քանի որ ձեր օգտագործած ծրագիրը աղավաղել է կետադրության նշանները խմբագրման դաշտում։ Խմբագրումը մերժվել է էջի տեքստի խաթարումը կանխելու նպատակով։ Սա երբեմն պայմանավորված է սխալներ պարունակող անանվանեցնող վեբ-փոխարինորդ (proxy) ծառայության օգտագործմամբ։'''",
-'editing' => 'Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´ $1',
-'creating' => 'Õ\8dÕ¿Õ¥Õ²Õ®Õ¸Ö\82Õ´ $1',
-'editingsection' => 'Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´Õ\9d $1 (Õ¢Õ¡ÕªÕ«Õ¶)',
-'editingcomment' => 'Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´Õ\9d $1 (Õ¶Õ¸Ö\80 Õ¢Õ¡ÕªÕ«Õ¶)',
+'editing' => 'Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¾Õ¸Ö\82Õ´ Õ§Õ\9d $1 Õ§Õ»Õ¨',
+'creating' => 'Õ\8dÕ¿Õ¥Õ²Õ®Õ¾Õ¸Ö\82Õ´ Õ§Õ\9d $1 Õ§Õ»Õ¨',
+'editingsection' => 'Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¾Õ¸Ö\82Õ´ Õ§Õ\9d $1 Õ§Õ»Õ« (Õ¢Õ¡ÕªÕ«Õ¶Õ¨)',
+'editingcomment' => 'Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¾Õ¸Ö\82Õ´ Õ§Õ\9d $1 Õ§Õ»Õ« (Õ¶Õ¸Ö\80 Õ¢Õ¡ÕªÕ«Õ¶Õ¨)',
 'editconflict' => 'Խմբագրման ընդհարում. $1',
 'explainconflict' => "Մեկ այլ մասնակից փոփոխել է այս տեքստը ձեր խմբագրման ընթացքում։
 Վերին խմբագրման դաշտում ընդգրկված է ընթացիկ տեքստը, որն ենթակա է հիշման։
@@ -952,8 +953,8 @@ $2',
 'templatesused' => 'Այս էջում օգտագործված {{PLURAL:$1|կաղապարը|կաղապարները}}.',
 'templatesusedpreview' => 'Այս նախադիտման մեջ օգտագործված {{PLURAL:$1|կաղապարը|կաղապարները}}.',
 'templatesusedsection' => 'Այս բաժնում օգտագործված {{PLURAL:$1|կաղապարը|կաղապարները}}.',
-'template-protected' => '(պաշտպանված)',
-'template-semiprotected' => '(կիսապաշտպանված)',
+'template-protected' => '(պաշտպանված է)',
+'template-semiprotected' => '(կիսա-պաշտպանված է)',
 'hiddencategories' => 'Այս էջը պատկանում է հետևյալ {{PLURAL:$1|1 թաքնված կատեգորիային|$1 թաքնված կատեգորիաներին}}.',
 'edittools' => '<!-- Այստեղ տեղադրված տեքստը կցուցադրվի խմբագրման և բեռնման ձևերի տակ։ -->
 <div id="Հատուկ նիշ:" class="toccolours specialchars" style="margin-top:.5em; padding: .3em .5em; font-size: 100%; color:#aaa; text-align:left;" title="{{int:bw-edittools-tooltip}}">
@@ -1004,10 +1005,13 @@ $2',
 'edit-no-change' => 'Ձեր խմբագրումը անտեսվել է, քանի որ ոչ մի փոփոխություն չի կատարվել տեքստի մեջ։',
 'defaultmessagetext' => 'Լռելյան տեքստը',
 
+# Content models
+'content-model-wikitext' => 'վիքիտեքստ',
+
 # "Undo" feature
 'undo-success' => 'Խմբագրումը կարող է հետ շրջվել։ Ստուգեք տարբերակների համեմատությունը ստորև, որպեսզի համոզվեք, որ դա է ձեզ հետաքրքրող փոփոխությունը և մատնահարեք «Հիշել էջը»՝ գործողությունն ավարտելու համար։',
 'undo-failure' => 'Խմբագրումը չի կարող հետ շրջվել միջանկյալ խմբագրումների ընդհարման պատճառով։',
-'undo-summary' => 'Հետ է շրջվում $1 խմբագրումը, որի հեղինակն է՝ [[Special:Contributions/$2|$2]] ([[User talk:$2|քննարկում]])',
+'undo-summary' => 'Հետ է շրջվում $1 խմբագրումը, որի հեղինակն է՝ [[Special:Contributions/$2|$2]] ([[User talk:$2|քննարկում]]) {{GENDER:$2|մասնակիցը|մասնակցուհին}}',
 
 # Account creation failure
 'cantcreateaccounttitle' => 'Չհաջողվեց ստեղծել մասնակցային հաշիվ',
@@ -1038,7 +1042,7 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'histfirst' => 'Առաջին',
 'histlast' => 'Վերջին',
 'historysize' => '({{PLURAL:$1|1 բայթ|$1 բայթ}})',
-'historyempty' => '(դատարկ)',
+'historyempty' => '(դատարկ է)',
 
 # Revision feed
 'history-feed-title' => 'Փոփոխությունների պատմություն',
@@ -1306,7 +1310,7 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'editinguser' => '<b>$1</b> մասնակցի համար ([[User talk:$1|{{int:talkpagelinktext}}]] | [[Special:Contributions/$1|{{int:contribslink}}]])',
 'userrights-editusergroup' => 'Խմբագրել մասնակցի խմբերը',
 'saveusergroups' => 'Հիշել մասնակցի խմբերը',
-'userrights-groupsmember' => 'Անդամ է.',
+'userrights-groupsmember' => 'Անդամ է՝ $2-ին',
 'userrights-reason' => 'Պատճառ.',
 'userrights-changeable-col' => 'Խմբեր, որոնք դուք կարող եք ձևափոխել',
 
@@ -1359,6 +1363,8 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 # Associated actions - in the sentence "You do not have permission to X"
 'action-edit' => 'խմբագրել այս էջը',
 'action-createpage' => 'Ստեղծել էջ',
+'action-move-rootuserpages' => 'տեղափոխել մասնակցի էջի արմատը',
+'action-movefile' => 'տեղափոխել այս ֆայլը',
 'action-upload' => 'Բեռնել այս ֆայլը',
 'action-upload_by_url' => 'Բեռնել այս ֆայլը URL-ից',
 'action-delete' => 'Ջնջել այս էջը',
@@ -1470,6 +1476,7 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'uploadvirus' => 'Նիշքը պարունակում է վիրո՜ւս։ Տես $1',
 'upload-source' => 'Աղբյուրը ֆայլի',
 'sourcefilename' => 'Սկզբնական նիշք՝',
+'sourceurl' => 'Այդ Տեղի URL-ն՝',
 'destfilename' => 'Նիշքի նոր անվանում՝',
 'upload-description' => 'Ֆայլի մեկնաբանություն',
 'upload-options' => 'Բեռնման ընտրանքներ',
@@ -1477,6 +1484,8 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'filewasdeleted' => 'Այս անվանմամբ նիշք նախկինում բեռնվել է և հետագայում ջնջվել։ Այն կրկին բեռնելուց առաջ խնդրում ենք ստուգել $1։',
 'filename-bad-prefix' => "Բեռնվող նիշքի անվանումը սկսվում է '''<tt>«$1»</tt>''' արտահայտությամբ, որը ոչ-նկարագրական է և սովորաբար տրվում է թվային լուսանկարչական ապարատների կողմից։ Խնդրում ենք ընտրել ավելի նկարագրական անվանում ձեր նիշքի համար։",
 'upload-success-subj' => 'Բեռնումը կատարված է',
+'upload-failure-subj' => 'Ներբեռնման սխալ',
+'upload-warning-subj' => 'Ներբեռնման զգուշացում',
 
 'upload-proto-error' => 'Սխալ պրոտոկոլ',
 'upload-proto-error-text' => 'Հեռավոր բեռնումը պահանջում է URL-հասցե, որը սկսվում է <code>http://</code> կամ <code>ftp://</code> նախածանցով։',
@@ -1484,6 +1493,7 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'upload-file-error-text' => 'Տեղի ունեցավ ներքին սխալ՝ սերվերի վրա ժամանակավոր նիշք ստեղծելիս։ Խնդրում ենք կապվել համակարգային [[Special:ListUsers/sysop|ադմինիստրատորի]] հետ։',
 'upload-misc-error' => 'Բեռնման անհայտ սխալ',
 'upload-misc-error-text' => 'Տեղի ունեցավ անհայտ սխալ բեռնման ընթացքում։ Խնդրում ենք ստուգել URL-հասցեի ճշտությունն ու հասանելիությունը և փորձել կրկին։ Սխալի կրկնման դեպքում կապնվեք համակարգային ադմինիստրատորի հետ։',
+'upload-unknown-size' => 'Անհնար չափս',
 
 # Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
 'upload-curl-error6' => 'URL-հասցեն անհասանելի է',
@@ -1533,10 +1543,11 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'filepage-nofile' => 'Այս անունով նիշք գոյություն չունի։',
 'filepage-nofile-link' => 'Այս անունով նիշք գոյություն չունի, դուք կարող եք [$1 բեռնել այն]:',
 'uploadnewversion-linktext' => 'Բեռնել այս նիշքի նոր տարբերակ',
+'shared-repo-from' => '$1-ից',
 
 # File reversion
-'filerevert' => 'Հետ շրջել $1',
-'filerevert-legend' => 'Հետ շրջել նիշք',
+'filerevert' => 'Հետ շրջել $1',
+'filerevert-legend' => 'Հետ շրջել նիշքը',
 'filerevert-intro' => "Դուք հետ եք շրջում '''[[Media:$1|$1]]''' նիշքը [$4 տարբերակի՝ $3, $2 պահով]։",
 'filerevert-comment' => 'Մեկնաբանություն.',
 'filerevert-defaultcomment' => 'Հետ է շրջվում հին տարբերակին՝ $2, $1 պահով',
@@ -1669,6 +1680,9 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'protectedpagesempty' => 'Ներկայումս չկան պաշտպանված էջեր նշված պարամետրերով։',
 'protectedtitles' => 'Պաշտպանված անվանումներ',
 'listusers' => 'Մասնակիցների ցանկ',
+'usereditcount' => ' 
+$1 {{PLURAL:$1|խմբագրում|խմբագրումներ}}',
+'usercreated' => '{{GENDER:$3|Ստեղծվել է}} $1-ին, ժամը $2-ին',
 'newpages' => 'Նոր էջեր',
 'newpages-username' => 'Մասնակից՝',
 'ancientpages' => 'Ամենահին էջերը',
@@ -1729,6 +1743,8 @@ Also see [[Special:WantedCategories|wanted categories]].',
 # Special:LinkSearch
 'linksearch' => 'Արտաքին հղումներ',
 'linksearch-ok' => 'Որոնել',
+'linksearch-line' => ' 
+$1-ը հղվել է $2 ից',
 
 # Special:ListUsers
 'listusersfrom' => 'Ցուցադրել մասնակիցներին՝ սկսած.',
@@ -1738,9 +1754,11 @@ Also see [[Special:WantedCategories|wanted categories]].',
 
 # Special:ActiveUsers
 'activeusers' => 'Ակտիվ մասնակիցների ցանկ',
+'activeusers-noresult' => 'Այդպիսի մասնակիցներ չեն գտնվել։',
 
 # Special:ListGroupRights
 'listgrouprights-members' => '(անդամների ցանկ)',
+'listgrouprights-addgroup' => 'Ավելացնեել {{PLURAL:$2|խումբ|խմբեր}}՝  $1',
 
 # E-mail user
 'mailnologin' => 'Ուղարկման հասցե չկա',
@@ -1759,8 +1777,9 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'noemailtitle' => 'Չկա էլ-փոստի հասցե',
 'noemailtext' => 'Այս մասնակիցը չի նշել էլ-փոստի հասցե կամ նախընտրել է չստանալ էլ-նամակներ այլ մասնակիցներից։',
 'emailusername' => 'Մասնակցի անուն՝',
+'emailusernamesubmit' => 'Հաշվել',
 'email-legend' => 'Ուղարկել էլ․ նամակ {{SITENAME}}յի այլ մասնակցի',
-'emailfrom' => 'Ումից.',
+'emailfrom' => 'Ումից',
 'emailto' => 'Ում.',
 'emailsubject' => 'Թեմա.',
 'emailmessage' => 'Ուղերձ.',
@@ -1773,6 +1792,7 @@ Also see [[Special:WantedCategories|wanted categories]].',
 # Watchlist
 'watchlist' => 'Իմ հսկողության ցանկը',
 'mywatchlist' => 'Հսկացանկ',
+'watchlistfor2' => '$1 $2-ի համար',
 'nowatchlist' => 'Ձեր հսկողության ցանկը դատարկ է։',
 'watchlistanontext' => 'Անհրաժեշտ է $1՝ հսկացանկը դիտելու կամ խմբագրելու համար։',
 'watchnologin' => 'Չեք մտել համակարգ',
@@ -1807,6 +1827,10 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'enotif_mailer' => '{{grammar:genitive|{{SITENAME}}}} Տեղեկացման ծառայություն',
 'enotif_reset' => 'Նշել բոլոր էջերը այցելված',
 'enotif_impersonal_salutation' => '{{grammar:genitive|{{SITENAME}}}} մասնակից',
+'enotif_subject_deleted' => '{{SITENAME}} էջը $1 {{GENDER:$2|ջնջվել է}} $2-ի կողմից',
+'enotif_subject_created' => '{{SITENAME}} էջը $1 {{GENDER:$2|ստեղծվել է}} $2-ի կողմից',
+'enotif_subject_moved' => '{{SITENAME}} էջը $1 {{GENDER:$2|վերահղվել է}} $2-ի կողմից',
+'enotif_body_intro_created' => '{{SITENAME}} էջը $1 {{GENDER:$2|ստեղծվել է}} ժամը $PAGEEDITDATE-ին $2-ի կողմից, նայիր $3 ընդացիկ տարբերակը:',
 'enotif_lastvisited' => 'Տես $1՝ ձեր վերջին այցից ի վեր կատարված փոփոխությունների համար։',
 'enotif_lastdiff' => 'Տես $1՝ այս փոփոխությունը դիտելու համար։',
 'enotif_anon_editor' => 'անանուն մասնակից $1',
@@ -1995,7 +2019,7 @@ $1',
 'blanknamespace' => '(Գլխավոր)',
 
 # Contributions
-'contributions' => 'Մասնակցի ներդրում',
+'contributions' => ' {{GENDER:$1|Մասնակցի}} ներդրում',
 'contributions-title' => '$1 մասնակցի ներդրումը',
 'mycontris' => 'Ներդրում',
 'contribsub2' => '$1-ի ներդրումները ($2)',
@@ -2176,6 +2200,7 @@ $1',
 
 Այսպիսի դեպքերում հարկավոր է տեղափոխել կամ միաձուլել էջերը ձեռքով, եթե դա ցանկանաք։",
 'movearticle' => 'Տեղափոխել էջը',
+'moveuserpage-warning' => "'''Զգուշացո՜ւմ՝ '''You are about to move a user page. Please note that only the page will be moved and the user will ''not'' be renamed.",
 'movenologin' => 'Դուք չեք մտել համակարգ',
 'movenologintext' => 'Անհրաժեշտ է [[Special:UserLogin|մտնել համակարգ]]՝ էջը տեղափոխելու համար։',
 'movenotallowed' => 'Դուք չունեք էջերի տեղափոխման իրավունք։',
@@ -2270,6 +2295,7 @@ Please visit [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] and
 'importhistoryconflict' => 'Գոյություն ունեցող տարբերակների ընդհարում (հավանաբար այս էջն արդեն ներմուծվել է նախկինում)',
 'importnosources' => 'Միջվիքի ներմուծման աղբյուր ընտրված չէ, իսկ փոփոխումների պատմության ուղիղ ներմուծումը անջատված է։',
 'importnofile' => 'Ներմուծման նիշք չի բեռնվել։',
+'import-upload' => 'Բեռնված է XML-ի դատան',
 
 # Import log
 'importlogpage' => 'Ներմուծման տեղեկամատյան',
@@ -2520,6 +2546,8 @@ $1',
 
 'exif-componentsconfiguration-0' => 'գոյություն չունի',
 
+'exif-urgency-normal' => 'Նորմալ ($1)',
+
 # External editor support
 'edit-externally' => 'Խմբագրել այս նիշքը արտաքին խմբագրիչով',
 'edit-externally-help' => '(Մանրամասնությունների համար տես [//www.mediawiki.org/wiki/Manual:External_editors տեղակայման հրահանգները])',
@@ -2705,6 +2733,10 @@ $3
 'dberr-problems' => 'Այս կայքում առաջացել են տեխնիկական խնդիրներ։ Հայցում ենք ձեր ներողությունը։',
 'dberr-again' => 'Փորձեք մի քանի րոպե սպասել և վերաբեռնել էջը։',
 
+# HTML forms
+'htmlform-submit' => ' 
+Հաշվել',
+
 # New logging system
 'logentry-delete-delete' => '$1 ջնջեց էջը $3',
 'logentry-delete-restore' => '$1 վերականգնեց էջը $3',
@@ -2727,7 +2759,6 @@ $3
 'logentry-newusers-newusers' => '$1 մասնակիցը ստեղծեց նոր հաշիվ',
 'logentry-newusers-create' => '$1 մասնակիցը ստեղծեց նոր հաշիվ',
 'logentry-newusers-create2' => '$1 Ստեղծեց նոր հաշիվ $3',
-'newuserlog-byemail' => 'Գաղտնաբառն ուղարկված է էլ․ փոստով',
 'rightsnone' => '(ոչ մի)',
 
 # Feedback
index cb21211..aafbd4c 100644 (file)
@@ -276,6 +276,7 @@ $messages = array(
 'newwindow' => '(se aperi in un nove fenestra)',
 'cancel' => 'Cancellar',
 'moredotdotdot' => 'Plus...',
+'morenotlisted' => 'Alteres non listate…',
 'mypage' => 'Pagina',
 'mytalk' => 'Discussion',
 'anontalk' => 'Discussion pro iste adresse IP',
@@ -520,7 +521,7 @@ Consulta: $2',
 'actionthrottled' => 'Action limitate',
 'actionthrottledtext' => 'Como mesura anti-spam, tu es limitate de executar iste action troppo de vices durante un curte periodo de tempore, e tu ha excedite iste limite.
 Per favor reprova post alcun minutas.',
-'protectedpagetext' => 'Iste pagina ha essite protegite contra modificationes.',
+'protectedpagetext' => 'Iste pagina ha essite protegite pro impedir le modification o altere actiones.',
 'viewsourcetext' => 'Tu pote vider e copiar le codice-fonte de iste pagina:',
 'viewyourtext' => "Tu pote vider e copiar le fonte de '''tu modificationes''' de iste pagina:",
 'protectedinterface' => 'Iste pagina contine texto pro le interfacie del software de iste wiki, e es protegite pro impedir le abuso. Pro adder o modificar traductiones pro tote le wikis, per favor usa [//translatewiki.net/ translatewiki.net], le projecto de traduction de MediaWiki.',
@@ -579,7 +580,7 @@ Non oblida personalisar tu [[Special:Preferences|preferentias in {{SITENAME}}]].
 'gotaccount' => "Tu jam ha un conto? '''$1'''.",
 'gotaccountlink' => 'Aperir session',
 'userlogin-resetlink' => 'Datos de authentication oblidate?',
-'createaccountmail' => 'per e-mail',
+'createaccountmail' => 'Usar un contrasigno aleatori temporari e inviar lo al adresse de e-mail specificate hic infra',
 'createaccountreason' => 'Motivo:',
 'badretype' => 'Le duo contrasignos que tu scribeva non es identic.',
 'userexists' => 'Iste nomine de usator es jam in uso.
@@ -660,6 +661,7 @@ Per favor attende ante de probar lo novemente.',
 # E-mail sending
 'php-mail-error-unknown' => 'Error incognite in le function mail() de PHP',
 'user-mail-no-addy' => 'Tentava inviar e-mail sin adresse de e-mail.',
+'user-mail-no-body' => 'Tentava inviar e-mail con texto vacue o multo curte.',
 
 # Change password dialog
 'resetpass' => 'Cambiar contrasigno',
@@ -727,6 +729,7 @@ Contrasigno temporari: $2',
 'changeemail-oldemail' => 'Adresse de e-mail actual:',
 'changeemail-newemail' => 'Adresse de e-mail nove:',
 'changeemail-none' => '(nulle)',
+'changeemail-password' => 'Contrasigno de {{SITENAME}}:',
 'changeemail-submit' => 'Cambiar e-mail',
 'changeemail-cancel' => 'Cancellar',
 
@@ -901,10 +904,10 @@ In addition, tu nos garanti que tu es le autor de isto, o que tu lo ha copiate d
 '''Non submitte material subjecte a copyright sin autorisation expresse!'''",
 'longpageerror' => "'''Error: Le texto que tu submitteva occupa {{PLURAL:$1|un kilobyte|$1 kilobytes}}, excedente le maximo de {{PLURAL:$2|un kilobyte|$2 kilobytes}}.'''
 Illo non pote esser salveguardate.",
-'readonlywarning' => "'''Attention: Le base de datos ha essite blocate pro mantenentia, ergo tu non pote salveguardar tu modificationes in iste momento.'''
-Nos recommenda copiar-e-collar le texto in un file de texto e salveguardar lo pro plus tarde.
+'readonlywarning' => "'''Attention: Le base de datos ha essite blocate pro mantenentia. Tu non pote salveguardar tu modificationes in iste momento.'''
+Nos recommenda copiar-e-collar le texto in un file e salveguardar lo pro plus tarde.
 
-Le administrator qui lo blocava dava iste explication: $1",
+Le administrator qui ha blocate le base de datos ha fornite iste explication: $1",
 'protectedpagewarning' => "'''Attention:  Iste pagina ha essite protegite de sorta que solmente usatores con privilegios de administrator pote modificar lo.''' Le ultime entrata del registro es fornite hic infra pro referentia:",
 'semiprotectedpagewarning' => "'''Nota:''' Iste pagina ha essite protegite de maniera que solmente usatores registrate pote modificar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
 'cascadeprotectedwarning' => "'''Attention:''' Iste pagina ha essite protegite de maniera que solmente administratores pote modificar lo, proque illo es includite in le protection in cascada del sequente {{PLURAL:$1|pagina|paginas}}:",
@@ -1320,9 +1323,9 @@ Le operation non pote esser disfacite.',
 'prefs-emailconfirm-label' => 'Confirmation del e-mail:',
 'prefs-textboxsize' => 'Dimension del fenestra de modification',
 'youremail' => 'E-mail:',
-'username' => 'Nomine de usator:',
-'uid' => 'ID del usator:',
-'prefs-memberingroups' => 'Membro de {{PLURAL:$1|gruppo|gruppos}}:',
+'username' => '{{GENDER:$1|Nomine de usator}}:',
+'uid' => 'ID del {{GENDER:$1|usator}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Membro}} de {{PLURAL:$1|gruppo|gruppos}}:',
 'prefs-registration' => 'Data de registration:',
 'yourrealname' => 'Nomine real:',
 'yourlanguage' => 'Lingua:',
@@ -2117,7 +2120,7 @@ Vide etiam le [[Special:WantedCategories|categorias desirate]].',
 'linksearch-ok' => 'Cercar',
 'linksearch-text' => 'Es possibile usar metacharacteres como in "*.wikipedia.org".
 Isto necessita specificar al minus le dominio de nivello superior, per exemplo "*.org".<br />
-Protocollos supportate: <code>$1</code> (http:// es assumite si nulle protocollo es specificate).',
+{{PLURAL:$2|Le protocollo|Protocollos}} supportate: <code>$1</code> (http:// es assumite si nulle protocollo es specificate).',
 'linksearch-line' => '$1 ligate ab $2',
 'linksearch-error' => 'Le metacharacteres pote apparer solmente al initio del nomine de host.',
 
@@ -2130,7 +2133,7 @@ Protocollos supportate: <code>$1</code> (http:// es assumite si nulle protocollo
 # Special:ActiveUsers
 'activeusers' => 'Lista de usatores active',
 '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|modification|modificationes}} in le ultime {{PLURAL:$3|die|$3 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',
@@ -2196,7 +2199,7 @@ como le adresse del expeditor, de sorta que le destinatario potera responder te
 'usermessage-editor' => 'Messagero del systema',
 
 # Watchlist
-'watchlist' => 'Mi observatorio',
+'watchlist' => 'Observatorio',
 'mywatchlist' => 'Observatorio',
 'watchlistfor2' => 'De $1 $2',
 'nowatchlist' => 'Tu non ha paginas sub observation.',
@@ -2204,10 +2207,8 @@ como le adresse del expeditor, de sorta que le destinatario potera responder te
 'watchnologin' => 'Tu non ha aperite un session',
 'watchnologintext' => 'Tu debe [[Special:UserLogin|aperir un session]] pro modificar tu observatorio.',
 'addwatch' => 'Adder al observatorio',
-'addedwatchtext' => "Le pagina \"[[:\$1]]\" ha essite addite a tu [[Special:Watchlist|observatorio]].
-Le modificationes futur in iste pagina e in su pagina de discussion essera listate ibi,
-e le pagina apparera '''in litteras grasse''' in le [[Special:RecentChanges|lista de modificationes recente]] pro
-render lo plus facile de deteger.",
+'addedwatchtext' => 'Le pagina "[[:$1]]" ha essite addite a tu [[Special:Watchlist|observatorio]].
+Le modificationes futur in iste pagina e in le pagina de discussion associate essera listate in illo.',
 'removewatch' => 'Remover del observatorio',
 'removedwatchtext' => 'Le pagina "[[:$1]]" ha essite removite de [[Special:Watchlist|tu observatorio]].',
 'watch' => 'Observar',
@@ -2236,6 +2237,11 @@ render lo plus facile de deteger.",
 'enotif_mailer' => 'Systema de notification via e-mail de {{SITENAME}}',
 'enotif_reset' => 'Marcar tote le paginas como visitate',
 'enotif_impersonal_salutation' => 'Usator de {{SITENAME}}',
+'enotif_subject_deleted' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|delite}} per $2',
+'enotif_subject_created' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|create}} per $2',
+'enotif_subject_moved' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|renominate}} per $2',
+'enotif_subject_restored' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|restaurate}} per $2',
+'enotif_subject_changed' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|modificate}} per $2',
 'enotif_lastvisited' => 'Vide $1 pro tote le modificationes depost tu ultime visita.',
 'enotif_lastdiff' => 'Vide $1 pro revider iste modification.',
 'enotif_anon_editor' => 'usator anonyme $1',
@@ -2361,9 +2367,9 @@ Ecce le configurationes actual del pagina '''$1''':",
 'protect-cascadeon' => 'Iste pagina es actualmente protegite proque illo es includite in le sequente {{PLURAL:$1|pagina, le qual|paginas, le quales}} ha activate le protection in cascada.
 Tu pote cambiar le nivello de protection de iste pagina, ma isto non cambiara le effecto del protection in cascada.',
 'protect-default' => 'Permitter tote le usatores',
-'protect-fallback' => 'Requirer permission de "$1"',
-'protect-level-autoconfirmed' => 'Blocar usatores nove e non registrate',
-'protect-level-sysop' => 'Administratores solmente',
+'protect-fallback' => 'Permitter solmente usatores con le permission de "$1"',
+'protect-level-autoconfirmed' => 'Permitter solmente usatores autoconfirmate',
+'protect-level-sysop' => 'Permitter solmente administratores',
 'protect-summary-cascade' => 'in cascada',
 'protect-expiring' => 'expira le $1 (UTC)',
 'protect-expiring-local' => 'expira le $1',
@@ -2464,7 +2470,7 @@ $1',
 'blanknamespace' => '(Principal)',
 
 # Contributions
-'contributions' => 'Contributiones del usator',
+'contributions' => 'Contributiones del {{GENDER:$1|usator}}',
 'contributions-title' => 'Contributiones del usator $1',
 'mycontris' => 'Contributiones',
 'contribsub2' => 'Pro $1 ($2)',
@@ -2671,16 +2677,16 @@ Pro blocar o disblocar le base de datos, le servitor web debe poter scriber a is
 # Move page
 'move-page' => 'Renominar $1',
 'move-page-legend' => 'Renominar pagina',
-'movepagetext' => "Per medio del formulario infra tu pote renominar un pagina, transferente tote su historia al nove nomine.
+'movepagetext' => "Per medio del formulario hic infra tu pote renominar un pagina, transferente tote su historia al nove nomine.
 Le titulo anterior devenira un pagina de redirection verso le nove titulo.
 Tu pote actualisar automaticamente le redirectiones que puncta verso le titulo original.
-Si tu prefere non facer isto, assecura te de reparar omne redirectiones [[Special:DoubleRedirects|duple]] o [[Special:BrokenRedirects|rupte]].
+Si tu prefere non facer isto, non oblida de reparar omne redirectiones [[Special:DoubleRedirects|duple]] o [[Special:BrokenRedirects|rupte]].
 Tu ha le responsabilitate de assecurar que le ligamines continua a punctar verso le paginas correcte.
 
-Nota que le pagina '''non''' essera renominate si existe ja un pagina sub le nove titulo, salvo si illo es vacue o un redirection e non ha un historia de modificationes passate.
-Isto vole dicer que tu pote renominar un pagina retro a su titulo original si tu ha committite un error, ben que tu non pote superscriber un pagina existente.
+Nota que le pagina '''non''' essera renominate si existe jam un pagina sub le nove titulo, excepte si iste es un redirection sin historia de modificationes passate.
+Isto te lassa le possibilitate de restaurar le titulo original de un pagina si tu ha committite un error, sin permitter te de supplantar un pagina existente.
 
-'''ATTENTION!'''
+'''Attention!'''
 Isto pote esser un cambio drastic e inexpectate pro un pagina popular;
 per favor assecura te de haber comprendite le consequentias de isto ante de continuar.",
 'movepagetext-noredirectfixer' => "Per medio del formulario infra tu pote renominar un pagina, transferente tote su historia al nove nomine.
@@ -3886,7 +3892,6 @@ Le imagines se monstra in plen resolution, le altere typos de file se executa di
 'logentry-newusers-create' => 'Le conto de usator $1 ha essite create',
 'logentry-newusers-create2' => 'Le conto de usator $3 ha essite create per $1',
 'logentry-newusers-autocreate' => 'Le conto $1 ha essite create automaticamente',
-'newuserlog-byemail' => 'contrasigno inviate per e-mail',
 'logentry-rights-rights' => '$1 cambiava le appertinentia a gruppos pro $3 de $4 a $5',
 'logentry-rights-rights-legacy' => '$1 cambiava le appertinentia a gruppos pro $3',
 'logentry-rights-autopromote' => '$1 ha essite automaticamente promovite de $4 a $5',
index c3df096..7df415a 100644 (file)
@@ -464,12 +464,16 @@ $messages = array(
 'index-category' => 'Halaman yang diindeks',
 'noindex-category' => 'Halaman yang tidak diindeks',
 'broken-file-category' => 'Halaman dengan gambar rusak',
+'categoryviewer-pagedlinks' => '($1) ($2)',
+
+'linkprefix' => '/^(.*?)([a-zA-Z\\x80-\\xff]+)$/sD',
 
 'about' => 'Tentang',
 'article' => 'Halaman isi',
 'newwindow' => '(buka di jendela baru)',
 'cancel' => 'Batalkan',
 'moredotdotdot' => 'Lainnya...',
+'morenotlisted' => 'Selanjutnya...',
 'mypage' => 'Halaman',
 'mytalk' => 'Pembicaraan',
 'anontalk' => 'Pembicaraan IP ini',
@@ -596,6 +600,9 @@ $1',
 'versionrequiredtext' => 'MediaWiki versi $1 dibutuhkan untuk menggunakan halaman ini. Lihat [[Special:Version|halaman versi]]',
 
 'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'pagetitle-view-mainpage' => '{{SITENAME}}',
+'backlinksubtitle' => '← $1',
 'retrievedfrom' => 'Diperoleh dari "$1"',
 'youhavenewmessages' => 'Anda mempunyai $1 ($2).',
 'newmessageslink' => 'pesan baru',
@@ -606,6 +613,7 @@ $1',
 'newmessagesdifflinkplural' => '{{PLURAL:$1||}}perubahan terakhir',
 'youhavenewmessagesmulti' => 'Anda mendapat beberapa pesan baru pada $1',
 'editsection' => 'sunting',
+'editsection-brackets' => '[$1]',
 'editold' => 'sunting',
 'viewsourceold' => 'lihat sumber',
 'editlink' => 'sunting',
@@ -627,6 +635,7 @@ $1',
 'page-rss-feed' => 'Umpan RSS "$1"',
 'page-atom-feed' => 'Umpan Atom "$1"',
 'feed-atom' => 'Atom',
+'feed-rss' => 'RSS',
 'red-link-title' => '$1 (halaman belum tersedia)',
 'sort-descending' => 'Urutkan menurun',
 'sort-ascending' => 'Urutkan menaik',
@@ -763,7 +772,7 @@ Perhatikan bahwa beberapa halaman mungkin masih terus menunjukkan bahwa Anda mas
 'gotaccount' => "Sudah terdaftar sebagai pengguna? '''$1'''.",
 'gotaccountlink' => 'Masuk log',
 'userlogin-resetlink' => 'Lupa detail info masuk Anda?',
-'createaccountmail' => 'melalui surel',
+'createaccountmail' => 'Gunakan kata sandi acak sementara dan kirimkan ke surel yang tercantum di bawah',
 'createaccountreason' => 'Alasan:',
 'badretype' => 'Kata sandi yang Anda masukkan salah.',
 'userexists' => 'Nama pengguna yang dimasukkan telah digunakan.
@@ -774,6 +783,7 @@ Silakan tentukan nama yang lain.',
 'nocookieslogin' => "{{SITENAME}} menggunakan ''cookies'' untuk log penggunanya. ''Cookies'' pada penjelajah web Anda dimatikan. Silakan aktifkan dan coba lagi.",
 'nocookiesfornew' => 'Akun pengguna tidak dibuat karena kami tidak dapat memastikan sumbernya.
 Pastikan Anda telah mengaktifkan kuki, lalu muat ulang halaman ini dan coba lagi.',
+'nocookiesforlogin' => '{{int:nocookieslogin}}',
 'noname' => 'Nama pengguna yang Anda masukkan tidak sah.',
 'loginsuccesstitle' => 'Berhasil masuk log',
 'loginsuccess' => "'''Anda sekarang masuk log di {{SITENAME}} sebagai \"\$1\".'''",
@@ -830,6 +840,7 @@ Silakan menunggu sebelum mencoba lagi.',
 # E-mail sending
 'php-mail-error-unknown' => 'Kesalahan yang tidak dikenal dalam fungsi mail() PHP',
 'user-mail-no-addy' => 'Mencoba mengirimkan surel tanpa alamat surel.',
+'user-mail-no-body' => 'Mencoba untuk mengirim surel kosong atau terlalu pendek.',
 
 # Change password dialog
 'resetpass' => 'Ganti kata sandi',
@@ -1053,8 +1064,8 @@ Jika Anda menyimpannya, perubahan-perubahan yang dibuat sejak revisi ini akan hi
 'copyrightwarning' => "Perhatikan bahwa semua kontribusi terhadap {{SITENAME}} dianggap dilisensikan sesuai dengan $2 (lihat $1 untuk informasi lebih lanjut). Jika Anda tidak ingin tulisan Anda disunting dan disebarkan ke halaman web yang lain, jangan kirimkan ke sini.<br />Anda juga berjanji bahwa ini adalah hasil karya Anda sendiri, atau disalin dari sumber milik umum atau sumber bebas yang lain. '''JANGAN KIRIMKAN KARYA YANG DILINDUNGI HAK CIPTA TANPA IZIN!'''",
 'copyrightwarning2' => "Perhatikan bahwa semua kontribusi terhadap {{SITENAME}} dapat disunting, diubah, atau dihapus oleh penyumbang lainnya. Jika Anda tidak ingin tulisan Anda disunting orang lain, jangan kirimkan ke sini.<br />Anda juga berjanji bahwa ini adalah hasil karya Anda sendiri, atau disalin dari sumber milik umum atau sumber bebas yang lain (lihat $1 untuk informasi lebih lanjut). '''JANGAN KIRIMKAN KARYA YANG DILINDUNGI HAK CIPTA TANPA IZIN!'''",
 'longpageerror' => "'''KESALAHAN: Teks yang Anda kirimkan sebesar $1 kilobita, yang berarti lebih besar daripada jumlah maksimum $2 kilobita. Teks tidak dapat disimpan.'''",
-'readonlywarning' => "'''PERINGATAN: Basis data sedang dikunci karena pemeliharaan, sehingga saat ini Anda tidak dapat menyimpan hasil suntingan Anda.
-Anda mungkin perlu menyalin teks suntingan Anda ini dan menyimpannya ke sebuah berkas teks dan memuatkannya lagi setelah pemeliharaan selesai.'''
+'readonlywarning' => "'''PERINGATAN: Basis data sedang dikunci karena pemeliharaan, sehingga saat ini Anda tidak dapat menyimpan hasil suntingan Anda.'''
+Anda mungkin perlu menyalin teks suntingan Anda ini dan menyimpannya ke sebuah berkas teks dan memuatkannya lagi kemudian.
 
 Pengurus yang mengunci basis data memberikan penjelasan berikut: $1",
 'protectedpagewarning' => "'''Peringatan: Halaman ini sedang dilindungi sehingga hanya pengguna dengan hak akses pengurus yang dapat menyuntingnya.'''
@@ -1071,6 +1082,7 @@ Entri catatan terakhir disediakan di bawah untuk referensi:",
 'template-semiprotected' => '(pelindungan semi)',
 'hiddencategories' => 'Halaman ini adalah anggota dari {{PLURAL:$1|1 kategori tersembunyi|$1 kategori tersembunyi}}:',
 'edittools' => '<!-- Teks di sini akan dimunculkan di bawah isian suntingan dan pemuatan.-->',
+'edittools-upload' => '-',
 'nocreatetext' => '{{SITENAME}} telah membatasi pembuatan halaman-halaman baru.
 Anda dapat kembali dan menyunting halaman yang telah ada, atau silakan [[Special:UserLogin|masuk log atau membuat akun]].',
 'nocreate-loggedin' => 'Anda tak memiliki hak akses untuk membuat halaman baru.',
@@ -1130,7 +1142,7 @@ Beberapa templat akan diabaikan.',
 'undo-success' => 'Suntingan ini dapat dibatalkan. Tolong cek perbandingan di bawah untuk meyakinkan bahwa benar itu yang Anda ingin lakukan, lalu simpan perubahan tersebut untuk menyelesaikan pembatalan suntingan.',
 'undo-failure' => 'Suntingan ini tidak dapat dibatalkan karena konflik penyuntingan antara.',
 'undo-norev' => 'Suntingan ini tidak dapat dibatalkan karena halaman tidak ditemukan atau telah dihapuskan.',
-'undo-summary' => 'Membatalkan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[Pembicaraan pengguna:$2|bicara]])',
+'undo-summary' => 'Membatalkan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|bicara]])',
 
 # Account creation failure
 'cantcreateaccounttitle' => 'Akun tak dapat dibuat',
@@ -1292,6 +1304,7 @@ Pastikan bahwa perubahan ini tetap mempertahankan kontinuitas versi terdahulu ha
 'mergehistory-comment' => '[[:$1]] telah digabungkan ke [[:$2]]: $3',
 'mergehistory-same-destination' => 'Nama halaman sumber dan tujuan tidak boleh sama',
 'mergehistory-reason' => 'Alasan:',
+'mergehistory-revisionrow' => '$1 ($2) $3 . . $4 $5 $6',
 
 # Merge log
 'mergelog' => 'Log penggabungan',
@@ -1357,7 +1370,7 @@ Rinciannya dapat ditemukan di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGE
 'search-interwiki-default' => 'Hasil $1:',
 'search-interwiki-more' => '(selanjutnya)',
 'search-relatedarticle' => 'Berkaitan',
-'mwsuggest-disable' => 'Non-aktifkan saran AJAX',
+'mwsuggest-disable' => 'Non-aktifkan saran pencarian',
 'searcheverything-enable' => 'Cari di semua ruang nama',
 'searchrelated' => 'berkaitan',
 'searchall' => 'semua',
@@ -1468,7 +1481,9 @@ Pengembalian preferensi tidak dapat dibatalkan.',
 'username' => '{{GENDER:$1|Nama pengguna}}:',
 'uid' => 'ID {{GENDER:$1|pengguna}}:',
 'prefs-memberingroups' => '{{GENDER:$2|Anggota}} {{PLURAL:$1|kelompok|kelompok}}:',
+'prefs-memberingroups-type' => '$1',
 'prefs-registration' => 'Waktu pendaftaran:',
+'prefs-registration-date-time' => '$1',
 'yourrealname' => 'Nama asli:',
 'yourlanguage' => 'Bahasa:',
 'yourvariant' => 'Varian bahasa isi:',
@@ -1518,6 +1533,7 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'saveusergroups' => 'Simpan kelompok pengguna',
 'userrights-groupsmember' => 'Anggota dari:',
 'userrights-groupsmember-auto' => 'Anggota implisit dari:',
+'userrights-groupsmember-type' => '$1',
 'userrights-groups-help' => 'Anda dapat mengubah kelompok pengguna ini:
 * Kotak dengan tanda cek merupakan kelompok pengguna yang bersangkutan
 * Kotak tanpa tanda cek berarti pengguna ini bukan anggota kelompok tersebut
@@ -1529,6 +1545,7 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'userrights-notallowed' => 'Akun Anda tidak berhak untuk menambahkan atau membuang hak pengguna.',
 'userrights-changeable-col' => 'Kelompok yang dapat Anda ubah',
 'userrights-unchangeable-col' => 'Kelompok yang tidak dapat Anda ubah',
+'userrights-irreversible-marker' => '$1*',
 
 # Groups
 'group' => 'Kelompok:',
@@ -1689,9 +1706,11 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'minoreditletter' => 'k',
 'newpageletter' => 'B',
 'boteditletter' => 'b',
+'unpatrolledletter' => '!',
 'number_of_watching_users_pageview' => '[$1 {{PLURAL:$1|pemantau|pemantau}}]',
 'rc_categories' => 'Batasi sampai kategori (dipisah dengan "|")',
 'rc_categories_any' => 'Apa pun',
+'rc-change-size' => '$1',
 'rc-change-size-new' => '$1 {{PLURAL:$1|bita|bita}} setelah perubahan',
 'newsectionsummary' => '/* $1 */ bagian baru',
 'rc-enhanced-expand' => 'Tampilkan rincian (memerlukan JavaScript)',
@@ -1815,6 +1834,20 @@ Penggunggahan berkas Java tidak diperbolehkan karena dapat menyebabkan pengabaia
 'watchthisupload' => 'Pantau berkas ini',
 'filewasdeleted' => 'Suatu berkas dengan nama ini pernah dimuat dan selanjutnya dihapus. Harap cek $1 sebelum memuat lagi berkas tersebut.',
 'filename-bad-prefix' => "Nama berkas yang Anda muat diawali dengan '''\"\$1\"''', yang merupakan nama non-deskriptif yang biasanya diberikan secara otomatis oleh kamera digital. Harap pilih nama lain yang lebih deskriptif untuk berkas Anda.",
+'filename-prefix-blacklist' => ' #<!-- biarkan baris ini seperti adanya --> <pre>
+# Contohnya sebagai berikut:
+#   * Semuanya dari karekter "#" sampai akhir baris ini adalah komentar
+#   * Setiap garis "_" adalah awalan untuk nama file khas yang diberikan secara otomatis oleh kamera digital
+CIMG # Casio
+DSC_ # Nikon
+DSCF # Fuji
+DSCN # Nikon
+DUW # beberapa model telpon seluler
+IMG # generik
+JD # Jenoptik
+MGP # Pentax
+PICT # lainnya.
+ #</pre> <!-- biarkan baris ini seperti adanya -->',
 'upload-success-subj' => 'Berhasil dimuat',
 'upload-success-msg' => 'Pengunggahan Anda dari [$2] berhasil. Hasilnya tersedia di sini: [[:{{ns:file}}:$1]]',
 'upload-failure-subj' => 'Masalah pengunggahan',
@@ -1993,7 +2026,8 @@ Mungkin Anda ingin menyunting keterangan pada [$2 halaman deskripsi berkas] di s
 'uploadnewversion-linktext' => 'Muatkan versi yang lebih baru dari berkas ini',
 'shared-repo-from' => 'dari $1',
 'shared-repo' => 'suatu repositori bersama',
-'filepage.css' => '/* CSS yang ditempatkan di sini disertakan pada halaman deskripsi berkas, juga disertakan pada klien wiki asing */',
+'shared-repo-name-wikimediacommons' => 'Wikimedia Commons',
+'filepage.css' => '/* CSS yang ditempatkan di sini disertakan pada halaman deskripsi berkas, juga disertakan pada klien wiki lain */',
 'upload-disallowed-here' => 'Anda tidak bisa menimpa berkas ini.',
 
 # File reversion
@@ -2172,6 +2206,7 @@ Harap perhatikan bahwa situs web lain mungkin memiliki pranala ke suatu berkas d
 # Book sources
 'booksources' => 'Sumber buku',
 'booksources-search-legend' => 'Cari di sumber buku',
+'booksources-isbn' => 'ISBN:',
 'booksources-go' => 'Tuju ke',
 'booksources-text' => 'Di bawah ini adalah daftar pranala ke situs lain yang menjual buku baru dan bekas, dan mungkin juga mempunyai informasi lebih lanjut mengenai buku yang sedang Anda cari:',
 'booksources-invalid-isbn' => 'ISBN yang diberikan tampaknya tidak valid; periksa kesalahan penyalinan dari sumber asli.',
@@ -2244,7 +2279,7 @@ Perlu sedikitnya satu domain tingkat atas, misalnya "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Daftar pengguna aktif',
 '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||}}suntingan selama {{PLURAL:$3||}}$3 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',
@@ -2259,6 +2294,8 @@ Perlu sedikitnya satu domain tingkat atas, misalnya "*.org".<br />
 'listgrouprights-rights' => 'Hak',
 'listgrouprights-helppage' => 'Help:Hak akses',
 'listgrouprights-members' => '(daftar anggota)',
+'listgrouprights-right-display' => '<span class="listgrouprights-granted">$1 <code>($2)</code></span>',
+'listgrouprights-right-revoked' => '<span class="listgrouprights-revoked">$1 <code>($2)</code></span>',
 'listgrouprights-addgroup' => 'Menambahkan {{PLURAL:$2|kelompok|kelompok}}: $1',
 'listgrouprights-removegroup' => 'Menghapus {{PLURAL:$2|kelompok|kelompok}}: $1',
 'listgrouprights-addgroup-all' => 'Menambahkan semua kelompok',
@@ -2304,6 +2341,7 @@ Alamat surel yang Anda masukkan di [[Special:Preferences|preferensi akun Anda]]
 # User Messenger
 'usermessage-summary' => 'Tinggalkan pesan sistem.',
 'usermessage-editor' => 'Penyampai pesan sistem',
+'usermessage-template' => 'MediaWiki:UserMessage',
 
 # Watchlist
 'watchlist' => 'Daftar pantauan',
@@ -2359,10 +2397,7 @@ Perubahan-perubahan berikutnya pada halaman tersebut dan halaman pembicaraan ter
 'enotif_anon_editor' => 'pengguna anonim $1',
 'enotif_body' => 'Halo $WATCHINGUSERNAME,
 
-
-Halaman $PAGETITLE di {{SITENAME}} telah $CHANGEDORCREATED pada $PAGEEDITDATE oleh $PAGEEDITOR, lihat $PAGETITLE_URL untuk revisi terakhir.
-
-$NEWPAGE
+$PAGEINTRO $NEWPAGE
 
 Ringkasan suntingan: $PAGESUMMARY $PAGEMINOREDIT
 
@@ -2373,7 +2408,7 @@ wiki: $PAGEEDITOR_WIKI
 Kami tidak akan mengirim pemberitahuan lain bila ada perubahan lebih lanjut sampai Anda mengunjungi halaman ini.
 Anda juga dapat menyetel ulang tanda pemberitahuan untuk semua halaman pantauan pada daftar pantauan Anda.
 
-             Sistem pemberitahuan situs {{SITENAME}}
+Sistem pemberitahuan situs {{SITENAME}}
 
 --
 Untuk mengubah setelan pemberitahuan surel, kunjungi
@@ -2456,6 +2491,8 @@ Lihat [[Special:ProtectedPages|daftar halaman terlindungi]] untuk daftar perlind
 'prot_1movedto2' => '[[$1]] dipindahkan ke [[$2]]',
 'protect-badnamespace-title' => 'Ruang nama yang tidak dapat dilindungi',
 'protect-badnamespace-text' => 'Halaman dalam ruang nama ini tidak dapat dilindungi.',
+'protect-norestrictiontypes-text' => 'Halaman ini tidak dapat dilindungi karena tidak ada tipe pembatasan yang tersedia.',
+'protect-norestrictiontypes-title' => 'Halaman tak-dilindungi',
 'protect-legend' => 'Konfirmasi pelindungan',
 'protectcomment' => 'Alasan:',
 'protectexpiry' => 'Kedaluwarsa:',
@@ -2468,9 +2505,10 @@ Lihat [[Special:ProtectedPages|daftar halaman terlindungi]] untuk daftar perlind
 'protect-locked-access' => "Akun Anda tidak dapat memiliki hak untuk mengganti tingkat pelindungan halaman. Berikut adalah konfigurasi saat ini untuk halaman '''$1''':",
 'protect-cascadeon' => 'Halaman ini sedang dilindungi karena disertakan dalam {{PLURAL:$1|halaman|halaman-halaman}} berikut yang telah dilindungi dengan pilihan pelindungan runtun diaktifkan. Anda dapat mengganti tingkat pelindungan untuk halaman ini, tapi hal tersebut tidak akan mempengaruhi pelindungan runtun.',
 'protect-default' => 'Izinkan semua pengguna',
-'protect-fallback' => 'Memerlukan hak akses "$1"',
-'protect-level-autoconfirmed' => 'Blokir pengguna baru dan tak terdaftar',
-'protect-level-sysop' => 'Hanya pengurus',
+'protect-fallback' => 'Hanya untuk pengguna dengan izin  "$1"',
+'protect-level-autoconfirmed' => 'Hanya untuk pengguna terdaftar otomatis',
+'protect-level-sysop' => 'Hanya untuk pengurus',
+'protect-summary-desc' => '[$1=$2] ($3)',
 'protect-summary-cascade' => 'runtun',
 'protect-expiring' => 'kedaluwarsa $1 (UTC)',
 'protect-expiring-local' => 'kedaluwarsa $1',
@@ -2555,6 +2593,7 @@ Lihat [[Special:Log/delete|log penghapusan]] untuk data penghapusan dan pengemba
 $1',
 'undelete-show-file-confirm' => 'Apakah Anda yakin ingin melihat revisi yang telah dihapus dari berkas "<nowiki>$1</nowiki>" per $3, $2?',
 'undelete-show-file-submit' => 'Ya',
+'undelete-revisionrow' => '$1 $2 ($3) $4 . . $5 $6 $7',
 
 # Namespace form on various pages
 'namespace' => 'Ruang nama:',
@@ -2701,9 +2740,9 @@ Alasan yang diberikan untuk pemblokiran $1 adalah: "$2"',
 'blocklog-showsuppresslog' => 'Pengguna ini telah diblokir dan disembunyikan sebelumnya. Log supresi disediakan di bawah untuk referensi:',
 'blocklogentry' => 'memblokir [[$1]] dengan waktu kedaluwarsa $2 $3',
 'reblock-logentry' => 'mengubah pemblokiran [[$1]] dengan waktu kedaluwarsa $2 $3',
-'blocklogtext' => 'Di bawah ini adalah log pemblokiran dan pembukaan blokir terhadap pengguna.
-Alamat IP yang diblokir secara otomatis tidak terdapat di dalam daftar ini.
-Lihat [[Special:BlockList|daftar pemblokiran]] untuk semua pengguna yang saat ini diblokir.',
+'blocklogtext' => 'Di bawah ko adolah log panyakek jo pambukaan sakek pado pangguno.
+Alamaik IP nan kanai sakek sacaro otomatis indak nampak dalam dafta ko.
+Lihek [[Special:BlockList|dafta panyakek]] untuak kasado pangguno nan koni kanai sakek.',
 'unblocklogentry' => 'menghilangkan blokir "$1"',
 'block-log-flags-anononly' => 'hanya pengguna anonim',
 'block-log-flags-nocreate' => 'pembuatan akun dimatikan',
@@ -2729,6 +2768,7 @@ Lihat [[Special:BlockList|daftar pemblokiran]] untuk semua pengguna yang saat in
 'proxyblocker-disabled' => 'Fitur ini sedang tidak diakfifkan.',
 'proxyblockreason' => 'Alamat IP Anda telah diblokir karena alamat IP Anda adalah proxy terbuka. Silakan hubungi penyedia jasa internet Anda atau dukungan teknis dan beritahukan mereka masalah keamanan serius ini.',
 'proxyblocksuccess' => 'Selesai.',
+'sorbs' => 'DNSBL',
 'sorbsreason' => 'Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL.',
 'sorbs_create_account_reason' => 'Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL. Anda tidak dapat membuat akun.',
 'cant-block-while-blocked' => 'Anda tidak dapat memblokir pengguna lain ketika Anda sendiri sedang diblokir.',
@@ -2758,11 +2798,18 @@ Pastikan Anda [[Special:UnlockDB|membuka kuncinya]] setelah pemeliharaan selesai
 # Move page
 'move-page' => 'Pindahkan $1',
 'move-page-legend' => 'Pindahkan halaman',
-'movepagetext' => "Formulir di bawah ini digunakan untuk mengubah nama suatu halaman dan memindahkan semua data sejarah ke nama baru. Judul yang lama akan menjadi halaman peralihan menuju judul yang baru. Pranala kepada judul lama tidak akan berubah. Pastikan untuk memeriksa terhadap peralihan halaman yang rusak atau berganda setelah pemindahan. Anda bertanggung jawab untuk memastikan bahwa pranala terus menyambung ke halaman yang seharusnya.
+'movepagetext' => "Menggunakan formulir di bawah ini akan mengubah nama suatu halaman dan memindahkan semua data sejarah ke nama baru.
+Judul lama akan menjadi halaman pengalihan ke judul baru.
+Anda dapat memperbarui pengalihan yang menuju ke judul asli secara otomatis.
+Jika Anda memilih tidak, pastikan untuk memeriksa
+[[Special:DoubleRedirects|pengalihan ganda]] atau [[Special:BrokenRedirects|pengalihan rusak]].
+Anda bertanggung jawab untuk memastikan bahwa pranala terhubung ke tempat seharusnya.
 
-Perhatikan bahwa halaman '''tidak''' akan dipindah apabila telah ada halaman yang menggunakan judul yang baru, kecuali bila halaman tersebut kosong atau merupakan halaman peralihan dan tidak mempunyai sejarah penyuntingan. Ini berarti Anda dapat mengubah nama halaman kembali seperti semula apabila Anda membuat kesalahan, dan Anda tidak dapat menimpa halaman yang telah ada.
+Perhatikan bahwa halaman '''tidak''' akan dipindah apabila telah ada halaman pada judul yang baru, kecuali bila halaman peralihan dan tidak mempunyai sejarah penyuntingan. 
+Ini berarti Anda dapat mengubah kembali nama halaman seperti semula apabila Anda membuat kesalahan, dan Anda tidak dapat menimpa halaman yang telah ada.
 
-'''Peringatan:''' Ini dapat mengakibatkan perubahan yang tak terduga dan drastis  bagi halaman yang populer. Pastikan Anda mengerti konsekuensi dari perbuatan ini sebelum melanjutkan.",
+'''Peringatan:'''
+Ini dapat mengakibatkan perubahan drastis dan tak terduga bagi halaman yang populer; pastikan Anda mengerti konsekuensinya sebelum melanjutkan.",
 'movepagetext-noredirectfixer' => "Formulir di bawah ini digunakan untuk mengubah nama suatu halaman dan memindahkan semua data sejarah ke nama baru.
 Judul yang lama akan menjadi halaman peralihan menuju judul yang baru.
 Pastikan untuk memeriksa pengalihan [[Special:DoubleRedirects|ganda]] atau [[Special:BrokenRedirects|rusak]].
@@ -2824,6 +2871,7 @@ Halaman yang dituju, "[[:$1]]", telah mempunyai isi. Apakah Anda hendak menghapu
 'immobile-target-namespace-iw' => 'Pranala interwiki bukanlah target yang valid untuk pemindahan halaman.',
 'immobile-source-page' => 'Halaman ini tidak dapat dipindahkan.',
 'immobile-target-page' => 'Tidak dapat memindahkan ke judul tujuan tersebut.',
+'bad-target-model' => 'Tujuan yang diinginkan menggunakan model konten yang berbeda. Tidak dapat mengkonversi dari  $1  untuk  $2 .',
 'imagenocrossnamespace' => 'Tidak dapat memindahkan berkas ke ruang nama non-berkas',
 'nonfile-cannot-move-to-file' => 'Tidak dapat memindahkan non-berkas ke ruang nama berkas',
 'imagetypemismatch' => 'Ekstensi yang diberikan tidak cocok dengan tipe berkas',
@@ -2937,6 +2985,7 @@ Simpan ke komputer Anda dan unggah ke sini.',
 'import-error-interwiki' => 'Halaman " $1 " tidak diimpor karena namanya dicadangkan untuk pranala eksternal (interwiki).',
 'import-error-special' => 'Halaman " $1 " tidak diimpor karena milik ruang nama khusus yang tidak mengizinkan adanya halaman.',
 'import-error-invalid' => 'Halaman "$1" tidak diimpor karena namanya tidak valid.',
+'import-error-unserialize' => 'Revisi  $2  halaman " $1 " tidak bisa diurutkan. Revisi dilaporkan untuk menggunakan konten model $3 urutan sebagai $4 .',
 'import-options-wrong' => '{{PLURAL:$2|Opsi|Opsi}} salah: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Halaman turunan yang diberikan adalah judul yang salah.',
 'import-rootpage-nosubpage' => 'Ruang nama "$1" di halaman turunan tidak mengizinkan subhalaman.',
@@ -3029,18 +3078,23 @@ Simpan ke komputer Anda dan unggah ke sini.',
 'tooltip-summary' => 'Masukkan sebuah ringkasan pendek',
 
 # Stylesheets
-'common.css' => '/* CSS yang ada di sini akan diterapkan untuk semua kulit. */',
-'standard.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Standard. */',
-'nostalgia.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Nostalgia. */',
-'cologneblue.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Cologne Blue. */',
-'monobook.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Monobook. */',
-'myskin.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit MySkin. */',
-'chick.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Chick. */',
-'simple.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Simple. */',
-'modern.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Modern. */',
-'vector.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Vector. */',
-'print.css' => '/* CSS yang ada di sini akan diterapkan untuk tampilan cetak. */',
+'common.css' => '/* CSS yang ada di sini akan diterapkan pada semua kulit. */',
+'standard.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Standar. */',
+'nostalgia.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Nostalgia. */',
+'cologneblue.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Cologne Blue. */',
+'monobook.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Monobook. */',
+'myskin.css' => '/* CSS yang ada di sini akan diterapkan pada kulit MySkin. */',
+'chick.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Chick. */',
+'simple.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Sederhana. */',
+'modern.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Modern. */',
+'vector.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Vektor. */',
+'print.css' => '/* CSS yang ada di sini akan diterapkan pada tampilan cetak. */',
 'handheld.css' => '/* CSS yang ada di sini akan diterapkan untuk tampilan piranti genggam yang dikonfigurasi di $wgHandheldStyle. */',
+'noscript.css' => '/* CSS di sini akan mempengaruhi pengguna dengan skrip Java non-aktif */',
+'group-autoconfirmed.css' => '/* CSS di sini hanya mempengaruhi pengguna terkonfirmasi otomatis */',
+'group-bot.css' => '/* CSS di sini hanya mempengaruhi bot */',
+'group-sysop.css' => '/* CSS di sini hanya mempengaruhi pengurus */',
+'group-bureaucrat.css' => '/* CSS di sini hanya mempengaruhi birokrat */',
 
 # Scripts
 'common.js' => '/* JavaScript yang ada di sini akan diterapkan untuk semua kulit. */',
@@ -3053,6 +3107,10 @@ Simpan ke komputer Anda dan unggah ke sini.',
 'simple.js' => '/* Semua JavaScript di sini akan dimuatkan untuk para pengguna yang menggunakan kulit Simple */',
 'modern.js' => '/* Semua JavaScript di sini akan dimuatkan untuk para pengguna yang menggunakan kulit Modern */',
 'vector.js' => '/* Semua JavaScript di sini akan dimuatkan untuk para pengguna yang menggunakan kulit Vector */',
+'group-autoconfirmed.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk pengguna terkonfirmasi otomatis */',
+'group-bot.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk bot */',
+'group-sysop.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk pengurus */',
+'group-bureaucrat.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk birokrat */',
 
 # Metadata
 'notacceptable' => 'Server wiki tidak dapat menyediakan data dalam format yang dapat dibaca oleh client Anda.',
@@ -3096,7 +3154,9 @@ Ini mungkin disebabkan oleh pranala ke situs luar yang termasuk dalam daftar hit
 'pageinfo-robot-noindex' => 'Tidak dapat diindeks',
 'pageinfo-views' => 'Jumlah penampilan',
 'pageinfo-watchers' => 'Jumlah pemantau halaman',
+'pageinfo-few-watchers' => 'Kurang dari $1 {{PLURAL:$1|pengunjung}}',
 'pageinfo-redirects-name' => 'Pengalihan ke halaman ini',
+'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Subhalaman halaman ini',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|pengalihan|pengalihan}}; $3 {{PLURAL:$3|non-pengalihan|non-pengalihan}})',
 'pageinfo-firstuser' => 'Pembuat halaman',
@@ -3110,16 +3170,30 @@ Ini mungkin disebabkan oleh pranala ke situs luar yang termasuk dalam daftar hit
 'pageinfo-magic-words' => '{{PLURAL:$1|Kata|Kata}} ajaib ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Kategori|Kategori}} tersembunyi ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Templat|Templat}} yang ditransklusi ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Halaman|Halaman}} ditransklusikan pada ( $1 )',
 'pageinfo-toolboxlink' => 'Informasi halaman',
 'pageinfo-redirectsto' => 'Beralih ke',
 'pageinfo-redirectsto-info' => 'Info',
 'pageinfo-contentpage' => 'Dihitung sebagai halaman konten',
 'pageinfo-contentpage-yes' => 'Ya',
+'pageinfo-protect-cascading' => 'Perlindungan berurutan dari sini',
 'pageinfo-protect-cascading-yes' => 'Ya',
+'pageinfo-protect-cascading-from' => 'Perlindungan mulai dari',
+'pageinfo-category-info' => 'Kategori informasi',
+'pageinfo-category-pages' => 'Jumlah halaman',
+'pageinfo-category-subcats' => 'Jumlah subkategori',
+'pageinfo-category-files' => 'Jumlah berkas',
 
 # Skin names
 'skinname-standard' => 'Klasik',
+'skinname-nostalgia' => 'Nostalgia',
+'skinname-cologneblue' => 'Biru Köln',
+'skinname-monobook' => 'MonoBook',
+'skinname-myskin' => 'MySkin',
+'skinname-chick' => 'Chick',
 'skinname-simple' => 'Sederhana',
+'skinname-modern' => 'Modern',
+'skinname-vector' => 'Vektor',
 
 # Patrolling
 'markaspatrolleddiff' => 'Tandai telah dipatroli',
@@ -3131,6 +3205,8 @@ Ini mungkin disebabkan oleh pranala ke situs luar yang termasuk dalam daftar hit
 'markedaspatrollederror' => 'Tidak dapat menandai telah dipatroli',
 'markedaspatrollederrortext' => 'Anda harus menentukan satu revisi untuk ditandai sebagai yang dipatroli.',
 'markedaspatrollederror-noautopatrol' => 'Anda tidak diizinkan menandai suntingan Anda sendiri dipatroli.',
+'markedaspatrollednotify' => 'Perubahan ini untuk $1 telah ditandai terpatroli.',
+'markedaspatrollederrornotify' => 'Menandai sebagai terpatroli gagal.',
 
 # Patrol log
 'patrol-log-page' => 'Log patroli',
@@ -3157,6 +3233,7 @@ $1',
 Jika dijalankan, sistem Anda akan berisiko terserang.",
 'imagemaxsize' => "Batas ukuran gambar:<br />''(untuk halaman deskripsi berkas)''",
 'thumbsize' => 'Ukuran miniatur:',
+'widthheight' => '$1 × $2',
 'widthheightpage' => '$1 × $2, $3 {{PLURAL:$3|halaman|halaman}}',
 'file-info' => 'ukuran berkas: $1, tipe MIME: $2',
 'file-info-size' => '$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4',
@@ -3190,13 +3267,17 @@ Jika dijalankan, sistem Anda akan berisiko terserang.",
 'sp-newimages-showfrom' => 'Tampilkan berkas baru dimulai dari $2, $1',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
-'seconds-abbrev' => '$1d',
-'minutes-abbrev' => '$1m',
-'hours-abbrev' => '$1j',
+'video-dims' => '$1, $2 × $3',
+'seconds-abbrev' => '$1 d',
+'minutes-abbrev' => '$1 mnt',
+'hours-abbrev' => '$1 j',
+'days-abbrev' => '$1 h',
 'seconds' => '{{PLURAL:$1|$1 detik|$1 detik}}',
 'minutes' => '{{PLURAL:$1|$1 menit|$1 menit}}',
 'hours' => '{{PLURAL:$1|$1 jam|$1 jam}}',
 'days' => '{{PLURAL:$1|$1 hari|$1 hari}}',
+'months' => '{{PLURAL:$1|$1 bulan|$1 bulan}}',
+'years' => '{{PLURAL:$1|$1 tahun|$1 tahun}}',
 'ago' => '$1 yang lalu',
 'just-now' => 'baru saja',
 
@@ -3207,6 +3288,37 @@ Hanya butir daftar (baris yang diawali dengan tanda *) yang diperhitungkan.
 Pranala pertama pada suatu baris haruslah pranala ke berkas yang buruk.
 Pranala-pranala selanjutnya pada baris yang sama dianggap sebagai pengecualian, yaitu halaman yang dapat menampilkan berkas tersebut.',
 
+/*
+Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language
+*/
+'variantname-zh-hans' => 'hans',
+'variantname-zh-hant' => 'hant',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-mo' => 'mo',
+'variantname-zh-sg' => 'sg',
+'variantname-zh-my' => 'my',
+'variantname-zh' => 'zh',
+
+# Variants for Gan language
+'variantname-gan-hans' => 'hans',
+'variantname-gan-hant' => 'hant',
+'variantname-gan' => 'gan',
+
+# Variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr' => 'sr',
+
+# Variants for Kazakh language
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-cn' => 'kk-cn',
+
 # Metadata
 'metadata' => 'Metadata',
 'metadata-help' => 'Berkas ini mengandung informasi tambahan yang mungkin ditambahkan oleh kamera digital atau pemindai yang digunakan untuk membuat atau mendigitalisasi berkas. Jika berkas ini telah mengalami modifikasi, rincian yang ada mungkin tidak secara penuh merefleksikan informasi dari gambar yang sudah dimodifikasi ini.',
@@ -3227,6 +3339,8 @@ Data lain akan disembunyikan secara bawaan.
 * gpslatitude
 * gpslongitude
 * gpsaltitude',
+'metadata-langitem' => "'''$2:''' $1",
+'metadata-langitem-default' => '$1',
 
 # EXIF tags
 'exif-imagewidth' => 'Lebar',
@@ -3274,6 +3388,7 @@ Data lain akan disembunyikan secara bawaan.
 'exif-exposuretime' => 'Waktu pajanan',
 'exif-exposuretime-format' => '$1 detik ($2)',
 'exif-fnumber' => 'Nilai F',
+'exif-fnumber-format' => 'f/$1',
 'exif-exposureprogram' => 'Program pajanan',
 'exif-spectralsensitivity' => 'Sensitivitas spektral',
 'exif-isospeedratings' => 'Rating kecepatan ISO',
@@ -3287,6 +3402,7 @@ Data lain akan disembunyikan secara bawaan.
 'exif-lightsource' => 'Sumber cahaya',
 'exif-flash' => 'Kilas',
 'exif-focallength' => 'Jarak fokus lensa',
+'exif-focallength-format' => '$1 mm',
 'exif-subjectarea' => 'Wilayah subjek',
 'exif-flashenergy' => 'Energi kilas',
 'exif-focalplanexresolution' => 'Resolusi bidang fokus X',
@@ -3341,6 +3457,7 @@ Data lain akan disembunyikan secara bawaan.
 'exif-gpsareainformation' => 'Nama wilayah GPS',
 'exif-gpsdatestamp' => 'Tanggal GPS',
 'exif-gpsdifferential' => 'Koreksi diferensial GPS',
+'exif-coordinate-format' => '$1° $2′ $3″ $4',
 'exif-jpegfilecomment' => 'Komentar berkas JPEG',
 'exif-keywords' => 'Kata kunci',
 'exif-worldregioncreated' => 'Wilayah dunia tempat pengambilan gambar',
@@ -3406,15 +3523,37 @@ Data lain akan disembunyikan secara bawaan.
 'exif-originalimageheight' => 'Tinggi gambar sebelum dipotong',
 'exif-originalimagewidth' => 'Lebar gambar sebelum dipotong',
 
+# Make & model, can be wikified in order to link to the camera and model name
+'exif-contact-value' => '$1
+
+$2
+<div class="adr">
+$3
+
+$4, $5 - $6, $7
+</div>
+$8',
+'exif-subjectnewscode-value' => '$2 ($1)',
+
 # EXIF attributes
 'exif-compression-1' => 'Tak terkompresi',
 'exif-compression-2' => 'CCITT Group 3 1-Dimensional Modified Huffman RLE',
 'exif-compression-3' => 'CCITT Group 3 fax encoding',
 'exif-compression-4' => 'CCITT Group 4 fax encoding',
+'exif-compression-5' => 'LZW',
+'exif-compression-6' => 'JPEG (lama)',
+'exif-compression-7' => 'JPEG',
+'exif-compression-8' => 'Turunan (Adobe)',
+'exif-compression-32773' => 'PackBits (Macintosh RLE)',
+'exif-compression-32946' => 'Turunan (PKZIP)',
+'exif-compression-34712' => 'JPEG2000',
 
 'exif-copyrighted-true' => 'Berhak cipta',
 'exif-copyrighted-false' => 'Domain publik',
 
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
 'exif-unknowndate' => 'Tanggal tak diketahui',
 
 'exif-orientation-1' => 'Normal',
@@ -3429,9 +3568,19 @@ Data lain akan disembunyikan secara bawaan.
 'exif-planarconfiguration-1' => 'format chunky',
 'exif-planarconfiguration-2' => 'format planar',
 
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
 'exif-colorspace-65535' => 'Tidak dikalibrasi',
 
 'exif-componentsconfiguration-0' => 'tak tersedia',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
 
 'exif-exposureprogram-0' => 'Tak terdefinisi',
 'exif-exposureprogram-1' => 'Manual',
@@ -3469,6 +3618,10 @@ Data lain akan disembunyikan secara bawaan.
 'exif-lightsource-17' => 'Cahaya standar A',
 'exif-lightsource-18' => 'Cahaya standar B',
 'exif-lightsource-19' => 'Cahaya standar C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
 'exif-lightsource-24' => 'studio ISO tungsten',
 'exif-lightsource-255' => 'Sumber cahaya lain',
 
@@ -3594,6 +3747,8 @@ Data lain akan disembunyikan secara bawaan.
 
 'exif-isospeedratings-overflow' => 'Lebih dari 65535',
 
+'exif-maxaperturevalue-value' => '$1 APEX (f/$2)',
+
 'exif-iimcategory-ace' => 'Seni, budaya, dan hiburan',
 'exif-iimcategory-clj' => 'Kejahatan dan hukum',
 'exif-iimcategory-dis' => 'Bencana dan kecelakaan',
@@ -3705,6 +3860,8 @@ Silakan konfirmasi jika Anda ingin membuat ulang halaman ini.",
 'confirmrecreate-noreason' => 'Pengguna [[User:$1|$1]] ([[User talk:$1|bicara]]) telah menghapus halaman ini setelah Anda mulai menyunting. Harap konfirmasikan bahwa Anda ingin membuat ulang halaman ini.',
 'recreate' => 'Buat ulang',
 
+'unit-pixel' => 'px',
+
 # action=purge
 'confirm_purge_button' => 'OK',
 'confirm-purge-top' => 'Hapus singgahan halaman ini?',
@@ -3716,6 +3873,15 @@ Silakan konfirmasi jika Anda ingin membuat ulang halaman ini.",
 'confirm-unwatch-button' => 'OK',
 'confirm-unwatch-top' => 'Hapus halaman ini dari daftar pantauan Anda?',
 
+# Separators for various lists, etc.
+'semicolon-separator' => ';&#32;',
+'comma-separator' => ',&#32;',
+'colon-separator' => ':&#32;',
+'autocomment-prefix' => '-&#32;',
+'pipe-separator' => '&#32;|&#32;',
+'word-separator' => '&#32;',
+'ellipsis' => '...',
+
 # Multipage image navigation
 'imgmultipageprev' => '&larr; halaman sebelumnya',
 'imgmultipagenext' => 'halaman selanjutnya &rarr;',
@@ -3821,6 +3987,7 @@ Anda juga dapat [[Special:EditWatchlist|menggunakan penyunting standar Anda]].',
 
 # Signatures
 'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|bicara]])',
+'timezone-utc' => 'UTC',
 
 # Core parser functions
 'unknown_extension_tag' => 'Tag ekstensi tidak dikenal "$1"',
@@ -3834,6 +4001,7 @@ Anda juga dapat [[Special:EditWatchlist|menggunakan penyunting standar Anda]].',
 'version-variables' => 'Variabel',
 'version-antispam' => 'Pencegahan spam',
 'version-skins' => 'Kulit',
+'version-api' => 'API',
 'version-other' => 'Lain-lain',
 'version-mediahandlers' => 'Penanganan media',
 'version-hooks' => 'Kait',
@@ -3843,6 +4011,7 @@ Anda juga dapat [[Special:EditWatchlist|menggunakan penyunting standar Anda]].',
 'version-hook-name' => 'Nama kait',
 'version-hook-subscribedby' => 'Dilanggani oleh',
 'version-version' => '(Versi $1)',
+'version-svn-revision' => '(r$2)',
 'version-license' => 'Lisensi',
 'version-poweredby-credits' => "Wiki ini didukung oleh '''[//www.mediawiki.org/ MediaWiki]''', hak cipta © 2001-$1 $2.",
 'version-poweredby-others' => 'lainnya',
@@ -3858,6 +4027,8 @@ Anda seharusnya telah menerima [{{SERVER}}{{SCRIPTPATH}}/COPYING salinan Lisensi
 'version-entrypoints' => 'URL titik entri',
 'version-entrypoints-header-entrypoint' => 'Titik entri',
 'version-entrypoints-header-url' => 'URL',
+'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath Artikel path]',
+'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath Skrip path]',
 
 # Special:FilePath
 'filepath' => 'Lokasi berkas',
@@ -3892,7 +4063,7 @@ Gambar ditampilkan dalam resolusi penuh dan tipe lain berkas akan dibuka langsun
 'specialpages-group-highuse' => 'Frekuensi tinggi',
 'specialpages-group-pages' => 'Daftar halaman',
 'specialpages-group-pagetools' => 'Peralatan halaman',
-'specialpages-group-wiki' => 'Data dan peralatan wiki',
+'specialpages-group-wiki' => 'Data dan peralatan',
 'specialpages-group-redirects' => 'Pencarian dan pengalihan',
 'specialpages-group-spam' => 'Peralatan spam',
 
@@ -3981,15 +4152,15 @@ Gambar ditampilkan dalam resolusi penuh dan tipe lain berkas akan dibuka langsun
 'revdelete-unrestricted' => 'pembatasan akses opsis dihapuskan',
 'logentry-move-move' => '$1 memindahkan halaman $3 ke $4',
 'logentry-move-move-noredirect' => '$1 memindahkan halaman $3 ke $4 tanpa membuat pengalihan',
-'logentry-move-move_redir' => '$1 memindahkan halaman $3 ke $4 melalui pengalihan',
-'logentry-move-move_redir-noredirect' => '$1 memindahkan halaman $3 ke $4 melalui pengalihan tanpa membuat pengalihan',
+'logentry-move-move_redir' => '$1 memindahkan halaman $3 ke $4 menimpa pengalihan lama',
+'logentry-move-move_redir-noredirect' => '$1 memindahkan halaman $3 ke $4 menimpa pengalihan lama tanpa membuat pengalihan',
 'logentry-patrol-patrol' => '$1 menandai revisi $4 dari halaman $3 terpatroli',
 'logentry-patrol-patrol-auto' => '$1 secara otomatis menandai revisi $4 dari halaman $3 terpatroli',
 'logentry-newusers-newusers' => 'Akun pengguna $1 telah dibuat',
 'logentry-newusers-create' => '$1 membuat akun pengguna',
 'logentry-newusers-create2' => '$1 membuat akun pengguna $3',
+'logentry-newusers-byemail' => 'Akun pengguna  $3  diciptakan oleh  $1  dan password dikirim melalui surel',
 'logentry-newusers-autocreate' => 'Akun $1 dibuat secara otomatis',
-'newuserlog-byemail' => 'kata sandi dikirim melalui surel',
 'logentry-rights-rights' => '$1 mengubah keanggotaan grup $3 dari $4 menjadi $5',
 'logentry-rights-rights-legacy' => '$1 mengubah keanggotaan grup $3',
 'logentry-rights-autopromote' => '$1 secara otomatis dipromosikan dari $4 menjadi $5',
@@ -4047,6 +4218,7 @@ Jika tidak, Anda dapat menggunakan formulir mudah di bawah ini. Komentar Anda ak
 'api-error-ok-but-empty' => 'Kesalahan internal: tidak ada tanggapan dari peladen.',
 'api-error-overwrite' => 'Tidak diizinkan untuk menimpa berkas yang sudah ada.',
 'api-error-stashfailed' => 'Kesalahan internal: server gagal menyimpan berkas sementara.',
+'api-error-publishfailed' => 'Kesalahan internal: server gagal menyimpan berkas sementara.',
 'api-error-timeout' => 'Peladen tidak merespons dalam waktu yang diharapkan.',
 'api-error-unclassified' => 'Terjadi galat yang tidak diketahui',
 'api-error-unknown-code' => 'Kesalahan tidak dikenal: "$1"',
index 0fdee86..51f3ea6 100644 (file)
@@ -152,7 +152,7 @@ $messages = array(
 'category-empty' => "''Daytoy a kategoria ket agdama a saan nga aglaon kadagiti panid wenno midia.''",
 'hidden-categories' => '{{PLURAL:$1|Nailemmeng a kategoria|Nailemmeng a katkategoria}}',
 'hidden-category-category' => 'Nailemmeng a katkategoria',
-'category-subcat-count' => '{{PLURAL:$2|Daytoy a kategoria ket adda laeng ti sumaganad nga apo ti kategoria.|Daytoy a kategoria ket adda kadagiti sumaganad nga {{PLURAL:$1|nga apo ti kategoria|$1 nga apo dagiti kategoria}}, manipud ti dagup nga $2.}}',
+'category-subcat-count' => '{{PLURAL:$2|Daytoy a kategoria ket adda laeng ti sumaganad a subkategoria.|Daytoy a kategoria ket adda ti sumaganad {{PLURAL:$1|a subkategoria|$1 a dagiti subkategoria}}, manipud ti dagup nga $2.}}',
 'category-subcat-count-limited' => 'Daytoy a kategoria ket adda ti sumaganad  {{PLURAL:$1|nga apo ti kategoria|$1 nga apo dagiti kategoria}}.',
 'category-article-count' => '{{PLURAL:$2|Daytoy a kategoria ket aglaon laeng ti sumaganad a panid.|Ti sumaganad  {{PLURAL:$1|a panid|$1 a pampanid}} ket adda iti daytoy a kategoria, manipud ti dagup nga $2.}}',
 'category-article-count-limited' => 'Ti sumaganad {{PLURAL:$1|a panid |$1 a pampanid}} ket adda iti agdama a kategoria.',
@@ -168,6 +168,7 @@ $messages = array(
 'newwindow' => '(aglukat iti sabali a tawa)',
 'cancel' => 'Ukasen',
 'moredotdotdot' => 'Adu pay...',
+'morenotlisted' => 'Adu a saan a nailista...',
 'mypage' => 'Panid',
 'mytalk' => 'Tungtungan',
 'anontalk' => 'Tungtungan para iti daytoy a pagtaengan ti IP',
@@ -473,7 +474,7 @@ Dimo liplipatan a sukatan dagiti kakaykayatam idiay [[Special:Preferences|{{SITE
 'gotaccount' => "Addaanka kadin ti pakabilangam? '''$1'''.",
 'gotaccountlink' => 'Sumrek',
 'userlogin-resetlink' => 'Nalipatam dagiti salaysay ti pagserrek mo?',
-'createaccountmail' => 'Babaen ti e-surat',
+'createaccountmail' => 'Agusar ti maysa a temporario a pugto a kontrasenias ken ipatulod idiay e-surat a pagtaengan a nainganan dita baba',
 'createaccountreason' => 'Rason:',
 'badretype' => 'Saan nga agpada dagiti impanmo a kontrasenias.',
 'userexists' => 'Maus-usaren ti nagan a kayatmo.
@@ -555,6 +556,7 @@ Pangaasi nga agurayka sakbay nga agipadas manen.',
 # E-mail sending
 'php-mail-error-unknown' => 'Di am-ammo a biddut iti surat ti PHP  () a pamay-an.',
 'user-mail-no-addy' => 'Pinadas nga impatulod ti e-surat nga awan ti e-surat a pagtaengan.',
+'user-mail-no-body' => 'Nangpadaska a nangipatulod ti e-surat nga awan linaonna wenno ababa laeng a bagi.',
 
 # Change password dialog
 'resetpass' => 'Sukatan ti kontrasenias',
@@ -622,6 +624,7 @@ Temporario a kontrasenias: $2',
 'changeemail-oldemail' => 'Agdama nga E-surat a pagtaengam:',
 'changeemail-newemail' => 'Baro nga e-surat a pagtaengan:',
 'changeemail-none' => '(awan)',
+'changeemail-password' => 'Ti bukodmo a kontrasenias ti {{SITENAME}}:',
 'changeemail-submit' => 'Sukatan ti e-surat',
 'changeemail-cancel' => 'Ukasen',
 
@@ -793,10 +796,10 @@ Kasta met nga ikarim kadakami a bukodmo a sinurat wenno gapuanan daytoy, wenno t
 '''Saan a mangipan iti adda ti karbenganna a panagpablaak nga obra no awan ti  pammalubos!'''",
 'longpageerror' => "'''Biddut: Ti testo nga intedmo ket {{PLURAL:$1|maysa a kilobyte|$1 kil-kilobyte}} a katiddog, nga at-atiddog ngem ti kangatuan iti  {{PLURAL:$2|maysa a kilobyte|$2 kil-kilobyte}}.'''
 Isu ti gapuna a saan a maidulin.",
-'readonlywarning' => "'''Ballaag: Narikepan ti database para iti panagtaripatu, saanmo a mabalin nga idulin dagita inurnosmo tattan.'''
-No kayatmo i \"cut-n-paste\" mo dagiti testo iti testo a papeles ken idulinmo no madamdama.
+'readonlywarning' => "'''Ballaag: Narikepan ti database tapno mataripatu, isu a saanmo a mabalin nga idulin dagita inurnosmo tattan.'''
+Mabalinmo ti agkopia ken agikabil ti testom iti maysa a testo a papeles ken idulinmo para iti panagusar no madamdama.
 
-Ti administrador a nangrikep ket saan a nangted ti palawag: \$1",
+Ti administrador a nangrikep ket nangited iti daytoy a palawag: $1",
 'protectedpagewarning' => "'''Ballaag:  Daytoy a panid ket nasalakniban tapno dagiti laeng agar-aramat nga adda ti gundaway nga administrador ti makaurnos ditoy.'''
 Ti nakaudi a naikabil a listaan ket adda dita baba tapno usaren a  reperensia:",
 'semiprotectedpagewarning' => "'''Pakaammo:'''Nasalakniban daytoy a panid tapno dagiti laeng nakarehistro nga agar-aramat ti makaurnos ditoy.
@@ -1103,7 +1106,7 @@ Dagiti salaysay ket mabalin a mabirukan idiay [{{fullurl:{{#Special:Log}}/delete
 'search-interwiki-default' => '$1 dagiti nagbanagan:',
 'search-interwiki-more' => '(adu pay)',
 'search-relatedarticle' => 'Mainaig',
-'mwsuggest-disable' => 'Pagsardengen dagiti AJAX a naisingasing',
+'mwsuggest-disable' => 'Ibaldado dagiti singasing ti panagbiruk',
 'searcheverything-enable' => 'Agbirukka kadagiti amin a nagan ti lugar',
 'searchrelated' => 'mainaig',
 'searchall' => 'amin',
@@ -1214,9 +1217,9 @@ Ngem saanto a mabalinen nga ipasubli.',
 'prefs-emailconfirm-label' => 'Pagsingkedan ti e-surat:',
 'prefs-textboxsize' => 'Ti kadakkel ti pagurnosan a tawa',
 'youremail' => 'E-surat:',
-'username' => 'Nagan ti agar-aramat:',
-'uid' => 'ID ti agar-aramat:',
-'prefs-memberingroups' => 'Kameng {{PLURAL:$1|ti grupo|dagiti grupo}}:',
+'username' => '{{GENDER:$1|Nagan ti agar-aramat}}:',
+'uid' => 'ID ti {{GENDER:$1|Agar-aramat}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Kameng}} ti {{PLURAL:$1|a grupo|a grupgrupo}}:',
 'prefs-registration' => 'Oras a nagrehistro:',
 'yourrealname' => 'Pudno a nagan:',
 'yourlanguage' => 'Pagsasao:',
@@ -2001,7 +2004,7 @@ Kitaen met [[Special:WantedCategories|dagiti makidkiddaw a kategoria]].',
 'linksearch-ok' => 'Biruken',
 'linksearch-text' => 'Ti naataap a tarheta a kas ti "*.wikipedia.org" ket mabalin nga usaren.
 Masapul ti kangatuan a pagturayan, a kaspagarigan "*.org".<br />
-{PLURAL:$2|Ti protokol|Dagiti protokol}} a nasuportaran: <code>$1</code> (naipakasigud ti http:// no awan ti protokol a nainaganan).',
+{{PLURAL:$2|Ti protokol|Dagiti protokol}} a nasuportaran: <code>$1</code> (naipakasigud ti http:// no awan ti protokol a nainaganan).',
 'linksearch-line' => 'Ti $1 ket nakasilpo idiay $2',
 'linksearch-error' => 'Ti naatap a tarheta ket agparang laeng iti pinagrugi ti nagan ti agsangaili.',
 
@@ -2014,7 +2017,7 @@ Masapul ti kangatuan a pagturayan, a kaspagarigan "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Listaan dagiti nasiglat nga agar-aramat',
 'activeusers-intro' => 'Daytoy ti listaan dagiti agar-aramat nga adda inararamidda kadagiti napalabas a $1 {{PLURAL:$1|nga aldaw|nga alaldaw}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|nga inurnos|kadagiti inurnos}} idi kalpasan ti  {{PLURAL:$3|nga aldaw|$3 nga alaldaw}}',
+'activeusers-count' => '$1 {{PLURAL:$1|a tignay|tigtignay}} idi kalpasan ti {{PLURAL:$3|nga aldaw|$3 nga alaldaw}}',
 'activeusers-from' => 'Iparang dagiti agar-aramat a mangrugi iti:',
 'activeusers-hidebots' => 'Ilemmeng dagiti bot',
 'activeusers-hidesysops' => 'Ilemmeng dagiti administrador',
@@ -2077,7 +2080,7 @@ Ti e-surat nga inkabilmo idiay  [[Special:Preferences|kakaykayatam]] ket agparan
 'usermessage-editor' => 'Mensahero iti sistema',
 
 # Watchlist
-'watchlist' => 'Bambantayak',
+'watchlist' => 'Bambantayan',
 'mywatchlist' => 'Bambantayan',
 'watchlistfor2' => 'Para iti $1 $2',
 'nowatchlist' => 'Awan ti banag iti listaan dagiti bambantayam.',
@@ -2085,8 +2088,8 @@ Ti e-surat nga inkabilmo idiay  [[Special:Preferences|kakaykayatam]] ket agparan
 'watchnologin' => 'Saan a nakastrek',
 'watchnologintext' => 'Masapul a [[Special:UserLogin|nakastrekka]] tapno mabaliwam dagiti bambantayam a panid.',
 'addwatch' => 'Inayon iti bambantayan',
-'addedwatchtext' => "Nainayonen ti panid iti \"[[:\$1]]\" iti [[Special:Watchlist|listaan ti bambantayam]].
-Mailistanto ditoy dagiti pinagsukat daytoy a panid iti masakbayan agraman ti kanaigna a panid-tungtongan, ket agparang ti panid a kas '''napuskol''' iti [[Special:RecentChanges|listaan ti naudi a balbaliw]] tapno nalaklaka a malasin.",
+'addedwatchtext' => 'Ti panid iti "[[:$1]]" ket nainayonen idiay [[Special:Watchlist|listaan ti bambantayam]].
+Dagiti masakbayan a panagsukat iti daytoy a panid ken dagiti mainaig a tungtunganna a panid ket mailistanto idiay.',
 'removewatch' => 'Ikkaten dita bambantayan',
 'removedwatchtext' => 'Daytoy a panid  "[[:$1]]" ket naikkat idiay [[Special:Watchlist|bambantayam]].',
 'watch' => 'bantayan',
@@ -2120,7 +2123,7 @@ Mailistanto ditoy dagiti pinagsukat daytoy a panid iti masakbayan agraman ti kan
 'enotif_subject_moved' => 'Ti {{SITENAME}} panid ti $1 ket naiyalis idin babaen ni {{gender:$2|$2}}',
 'enotif_subject_restored' => 'Ti {{SITENAME}} a panid ti $1 ket naipasubli idin babaen ni {{gender:$2|$2}}',
 'enotif_subject_changed' => 'Ti {{SITENAME}} a panid ti $1 ket nasukatan idin babaen ni {{gender:$2|$2}}',
-'enotif_body_intro_deleted' => 'Ti {{SITENAME}} a panid ti $1 ket naikkat idin idiay $PAGEEDITDATE babaen ni {{gender:$2|$2}}, kitaen ti $3 para iti agdama panagbaliw.',
+'enotif_body_intro_deleted' => 'Ti {{SITENAME}} a panid tie $1 ket {{GENDER:$2|naikkaten}} idiay $PAGEEDITDATE babaen ni $2, kitaen ti $3.',
 'enotif_body_intro_created' => 'Ti {{SITENAME}} a panid ti $1 ket napartuat idin idiay $PAGEEDITDATE babaen ni {{gender:$2|$2}}, kitaen ti $3 para iti agdama panagbaliw.',
 'enotif_body_intro_moved' => 'Ti {{SITENAME}} a panid ti $1 ket naiyalis idin idiay $PAGEEDITDATE babaen ni {{gender:$2|$2}}, kitaen ti $3 para iti agdama panagbaliw.',
 'enotif_body_intro_restored' => 'Ti {{SITENAME}} a panid ti $1 ket naipasubli idi idiay $PAGEEDITDATE babaen ni {{gender:$2|$2}}, kitaen ti $3 para iti agdama panagbaliw.',
@@ -2229,6 +2232,8 @@ Kitaen ti [[Special:ProtectedPages|listaan kadagiti nasalakniban a panid]] ti li
 'prot_1movedto2' => '[[$1]] naiyalis iti [[$2]]',
 'protect-badnamespace-title' => 'Saan a mabalin a salakniban a nagan ti lugar',
 'protect-badnamespace-text' => 'Dagiti panid ditoy  a nagan ti lugar ket saan a mabalin a masalakniban.',
+'protect-norestrictiontypes-text' => 'Daytoy a panid ket saan a mabalin a masalakniban gaputa awan dagiti maiparit a kita a magun-od.',
+'protect-norestrictiontypes-title' => 'Di masalakniban a panid',
 'protect-legend' => 'Pasingkedan ti panagsalaknib',
 'protectcomment' => 'Rason:',
 'protectexpiry' => 'Agpaso:',
@@ -2245,9 +2250,9 @@ Dagitoy dagiti agdama a kasasaad ti panid a '''$1''':",
 'protect-cascadeon' => 'Daytoy a panid ket agdama a  nasalakniban gapu ta nairaman kadagiti sumaganad a {{PLURAL:$1|panid, nga addaan|pampanid, nga addaan}} ti sipapakat a salaknib ti amin-amin.
 Mabalinmo a sukatan ti lessaad ti salaknib daytoy a panid, ngem saanna a tignayen ti salaknib nga amin-amin.',
 'protect-default' => 'Palubosan amin nga agar-aramat',
-'protect-fallback' => 'Masapul ti "$1" a pammalubos',
-'protect-level-autoconfirmed' => 'Serraan dagiti baro ken saan a nakarehistro nga agar-aramat',
-'protect-level-sysop' => 'Dagiti administrador laeng',
+'protect-fallback' => 'Palubosan laeng dagiti agar-aramat nga adda iti "$1" a pammalubos',
+'protect-level-autoconfirmed' => 'Palubosan laeng dagiti automatiko a napasingkedan nga agar-aramat',
+'protect-level-sysop' => 'Palubosan laeng dagiti administrador',
 'protect-summary-cascade' => 'agsariap',
 'protect-expiring' => 'agpaso inton $1 (UTC)',
 'protect-expiring-local' => 'agpaso $1',
@@ -2549,18 +2554,18 @@ Ti agserra ken aglukat iti database, masapul a masuratan ti web server.',
 # Move page
 'move-page' => 'Iyalis ti $1',
 'move-page-legend' => 'Iyalis ti panid',
-'movepagetext' => "Ti panagusar ti kinabuklan dita baba, ket panaganan ti panid, iyalis na amin ti pakasaritaan na idiay baro a nagan.
-Ti daan a titulo ket agbalin baw-ing a panid idiay baro a titulo.
-Mapabarom a kas automatiko dagiti baw-ing a nakatudo dita kasigud a titulo.
-No agpili ka a saan mo a kayat, pasaraduam nga kitaen ti [[Special:DoubleRedirects|doble]] wenno [[Special:BrokenRedirects|nadadael a baw-ing]].
-Rebbengem ti mangpatalged nga amin a panilpo ket agtultuloy a nakatudo iti nasken a papananda.
+'movepagetext' => "Ti panagusar ti kinabuklan dita baba, ket mangnagan manen ti panid, a mangiyalis amin ti pakasaritaanna idiay baro a nagan.
+Ti daan a titulo ket agbalin baw-ing a panid idiay baro a titulo.
+Mapabarom a kas automatiko dagiti baw-ing a nakatudo dita kasisigud a titulo.
+No agpilika a saanmo a kayat, pasaraduam a kitaen ti [[Special:DoubleRedirects|doble]] wenno [[Special:BrokenRedirects|nadadael a baw-ing]].
+Renbbengmo ti mangpatalged nga amin a silpo ket agtultuloy a nakatudo iti nasken a papananda.
 
-Laglagipen a ti panid ket '''saan''' a maiyalis no addan sigud a panid iti baro a titulo, malaksid no awan linaonna wenno no maysa a baw-ing a panid ken awan ti panagbaliw iti pakasaritaan ti napalabas. 
+Laglagipen a ti panid ket '''saan''' a maiyalis no addan sigud a panid iti baro a titulo, malaksid no ti kinaudi ket maysa a baw-ing ken awan ti napalabas a pakasaritaan ti panag-urnos. 
 Kayat a sawen daytoy a mabalinmo a suktan ti nagan ti maysa a panid manipud iti punto ti pannakasukat ti nagan no nagbiddutka, ken saan mo a mabalin a suratan manen ti addaan a panid.
 
 '''Ballaag!'''
 Mabalin a maysa daytoy a nakaro ken saan a bigla a panagbaliw iti maysa a nasikat a panid;
-pangngaasim ta pasingkedam a maawatam ti ibunga dayoty sakbay nga agtuloyka a mangbaliw.",
+pangngaasim a pasingkedam a maawatam ti ibunga daytoy sakbay nga agtuloyka a mangbaliw.",
 'movepagetext-noredirectfixer' => "Ti panagusar ti kinabuklan dita baba, ket panaganan ti panid, iyalis na amin ti pakasaritaan na idiay baro a nagan.
 Ti daan a titulo ket agbalin baw-ing a panid idiay baro a titulo.
 Pasaruduam a kitaen ti [[Special:DoubleRedirects|doble]] wenno [[Special:BrokenRedirects|nadadael a baw-ing]].
@@ -2741,6 +2746,7 @@ Pangngaasi a padasem manen.',
 'import-error-interwiki' => 'Ti panid ti "$1" ket saan a naala ngamin ket ti nagan ket nailasin para iti ruar a panagsilpo (interwiki).',
 'import-error-special' => 'Ti panid ti "$1" ket saan a naala ngamin ket bukod ti  espesial a nagan a lugar a saan nga agpalubos ti pampanid.',
 'import-error-invalid' => 'Ti panid ti "$1" ket saan a naala ngamin ket ti nagan ket imbalido.',
+'import-error-unserialize' => 'Ti panagbaliw ti $2 iti panid ti "$1" ket di maipagsasaruno. Ti panagbalbaliw ket naireporta idi nga agus-usar ti modelo ti $3 a naipagsasaruno a kas $4.',
 'import-options-wrong' => 'Saan nga husto {{PLURAL:$2|a pagpilian|a pagpilpilian}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Ti naited a ramut ti panid ket imbalido a titulo.',
 'import-rootpage-nosubpage' => 'Ti nagan ti lugar ti "$1" iti ramut ti panid ket saan amangpalubos kadagiti apo ti panid.',
@@ -2875,6 +2881,7 @@ Daytoy ket mabalin a gapuanan babaen ti panilpo a naiparit ti akin ruar a pagsaa
 'pageinfo-robot-noindex' => 'Saan a mabalin a maipasurotan',
 'pageinfo-views' => 'Bilang dagiti panagkita',
 'pageinfo-watchers' => 'Bilang dagiti agbuybuya ti panid',
+'pageinfo-few-watchers' => 'Basbassit ngem $1 {{PLURAL:$1|ti agbuybuya|dagiti agbuybuya}}',
 'pageinfo-redirects-name' => 'Maibaw-ing ti daytoy a panid',
 'pageinfo-subpages-name' => 'Apo dagiti panid ti daytoy a panid',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|baw-ing|bawbaw-ing}}; $3 {{PLURAL:$3|saan a baw-ing|saan a bawbaw-ing}})',
@@ -2889,6 +2896,7 @@ Daytoy ket mabalin a gapuanan babaen ti panilpo a naiparit ti akin ruar a pagsaa
 'pageinfo-magic-words' => 'Salamangka  {{PLURAL:$1|a balikas|a balbalikas}} ($1)',
 'pageinfo-hidden-categories' => 'Nailemmeng {{PLURAL:$1|a kategoria|a katkategoria}} ($1)',
 'pageinfo-templates' => 'Nailak-am  {{PLURAL:$1|a plantilia|a planplantilia}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|A panid|A pampanid}} ti nailak-an=m idiay ($1)',
 'pageinfo-toolboxlink' => 'Pakaammo ti panid',
 'pageinfo-redirectsto' => 'Maibaw-ing idiay',
 'pageinfo-redirectsto-info' => 'pakaammo',
@@ -2897,6 +2905,10 @@ Daytoy ket mabalin a gapuanan babaen ti panilpo a naiparit ti akin ruar a pagsaa
 'pageinfo-protect-cascading' => 'Dagiti panagsalaknib ket agsariap manipud ditoy',
 'pageinfo-protect-cascading-yes' => 'Wen',
 'pageinfo-protect-cascading-from' => 'Dagiti panagsalaknib ket agsariap manipud idiay',
+'pageinfo-category-info' => 'Pakaammo ti kategoria',
+'pageinfo-category-pages' => 'Bilang dagiti panid',
+'pageinfo-category-subcats' => 'Bilang dagiti subkategoria',
+'pageinfo-category-files' => 'Bilang dagiti papeles',
 
 # Patrolling
 'markaspatrolleddiff' => 'Markaan a kas napatruliaan',
@@ -2973,6 +2985,8 @@ No usarem daytoy, baka makompromiso ti sistema.",
 'minutes' => '{{PLURAL:$1|$1 minuto|$1 minutos}}',
 'hours' => '{{PLURAL:$1|$1 oras$1 oras}}',
 'days' => '{{PLURAL:$1|$1 aldaw|$1 al-aldaw}}',
+'months' => '{{PLURAL:$1|$1 a bulan|$1 a bulbulan}}',
+'years' => '{{PLURAL:$1|$1 a tawen|$1 a tawtawen}}',
 'ago' => '$1 nagtapos',
 'just-now' => 'tatta laeng',
 
@@ -3627,7 +3641,7 @@ Dagiti imahen ket agparang iti kadakkelan a resolusion, dagiti sabali a kita ti
 'specialpages-group-highuse' => 'Adu ti panaka-usar a pampanid',
 'specialpages-group-pages' => 'Listaan dagiti panid',
 'specialpages-group-pagetools' => 'Ramramit ti panid',
-'specialpages-group-wiki' => 'Linaon ti wiki ken ramramit',
+'specialpages-group-wiki' => 'Datos ken ramramit',
 'specialpages-group-redirects' => 'Maibawbaw-ing dagiti espesial a pampanid',
 'specialpages-group-spam' => 'Ramramit kontra spam',
 
@@ -3725,8 +3739,8 @@ Daytoy a pagsaadan ket agdadama ti teknikal a pagrigrigatan.',
 'logentry-newusers-newusers' => 'Nagpartuat idi ti $1 a pakabilangan ti agar-aramat',
 'logentry-newusers-create' => 'Nagpartuat idi ti $1 a pakabilangan ti agar-aramat',
 'logentry-newusers-create2' => 'Nagpartuat ni ti $3 a pakabilangan ti agar-aramat babaen ni $1',
+'logentry-newusers-byemail' => 'Ti pakabilangan a $3 ket pinartuat idi babaen ni $1 ken ti kontrasenias ket naipatulod idi babaen ti e-surat',
 'logentry-newusers-autocreate' => 'Ti pakabilangan ni $1 ket automatiko a napartuat',
-'newuserlog-byemail' => 'naipatulod ti kontrasenias ti e-surat',
 'logentry-rights-rights' => 'Ni $1 ket nangbaliw ti grupo a panakaikameng para kenni $3 manipud ti $4 iti $5',
 'logentry-rights-rights-legacy' => 'Ni $1 ket nangbaliw ti grupo a panakaikameng para kenni $3',
 'logentry-rights-autopromote' => 'Ni $1 ket automatiko idi a naipangato manipud ti $4 iti $5',
@@ -3784,6 +3798,7 @@ Nupay kasta, mau-sarmo ti nakabuklan dita baba. Ti komentario nga itedmo ket mai
 'api-error-ok-but-empty' => 'Kinauneg a biddut: Awan ti sungbat manipud idiay server.',
 'api-error-overwrite' => 'Saan a mabalin a suratan manen iti papeles nga adda ditan.',
 'api-error-stashfailed' => 'Kinauneg a biddut: Napaay ti server ti agidulin ti temporario a papeles',
+'api-error-publishfailed' => 'Kinauneg a biddut: Napaay ti server a nagipablaak ti temporario a papeles.',
 'api-error-timeout' => 'Saan a simmungbat ti server iti nanamnama nga oras.',
 'api-error-unclassified' => 'Adda di amammo a biddut a rumsua.',
 'api-error-unknown-code' => 'Di amamo a biddut: "$1"',
index a5dcde3..736b2ce 100644 (file)
@@ -261,9 +261,9 @@ $messages = array(
 'tog-enotifrevealaddr' => 'Gefa upp netfang mitt í tilkynningarpóstum',
 'tog-shownumberswatching' => 'Sýna fjölda vaktandi notenda',
 'tog-oldsig' => 'Núverandi undirskrift:',
-'tog-fancysig' => 'Meðhöndla undirskrift sem wikitexti (án sjálfvirks tengils)',
-'tog-externaleditor' => 'Nota utanaðkomandi ritil sjálfgefið (eingöngu fyrir reynda, þarfnast sérstakra stillinga á tölvunni þinni)',
-'tog-externaldiff' => 'Nota utanaðkomandi mismun sjálfgefið (eingöngu fyrir reynda, þarfnast sérstakra stillinga á tölvunni þinni)',
+'tog-fancysig' => 'Meðhöndla undirskrift sem wikimál (án sjálfvirks tengils)',
+'tog-externaleditor' => 'Nota utanaðkomandi ritil sjálfgefið (eingöngu fyrir reynda, þarfnast sérstakra stillinga á tölvunni þinni. [//www.mediawiki.org/wiki/Manual:External_editors Frekari upplýsingar.])',
+'tog-externaldiff' => 'Nota utanaðkomandi mismun sjálfgefið (eingöngu fyrir reynda, þarfnast sérstakra stillinga á tölvunni þinni. [//www.mediawiki.org/wiki/Manual:External_editors Frekari upplýsingar.])',
 'tog-showjumplinks' => 'Virkja „stökkva á“ aðgengitengla',
 'tog-uselivepreview' => 'Nota beina forskoðun (JavaScript) (Á tilraunastigi)',
 'tog-forceeditsummary' => 'Birta áminningu þegar breytingarágripið er tómt',
@@ -316,10 +316,10 @@ $messages = array(
 'october' => 'október',
 'november' => 'nóvember',
 'december' => 'desember',
-'january-gen' => 'janúar',
-'february-gen' => 'febrúar',
+'january-gen' => 'janúars',
+'february-gen' => 'febrúars',
 'march-gen' => 'mars',
-'april-gen' => 'apríl',
+'april-gen' => 'apríls',
 'may-gen' => 'maí',
 'june-gen' => 'júní',
 'july-gen' => 'júlí',
@@ -352,7 +352,7 @@ $messages = array(
 'category-subcat-count' => '{{PLURAL:$2|Þessi flokkur hefur einungis eftirfarandi undirflokk.|Þessi flokkur hefur eftirfarandi {{PLURAL:$1|undirflokk|$1 undirflokka}}, af alls $2.}}',
 'category-subcat-count-limited' => 'Þessi flokkur hefur eftirfarandi {{PLURAL:$1|undirflokk|$1 undirflokka}}.',
 'category-article-count' => '{{PLURAL:$2|Þessi flokkur inniheldur aðeins eftirfarandi síðu.|Eftirfarandi {{PLURAL:$1|síða er|síður eru}} í þessum flokki, af alls $1.}}',
-'category-article-count-limited' => 'Eftirfarndi {{PLURAL:$1|síða er|$1 síður eru}} í þessum flokki.',
+'category-article-count-limited' => 'Eftirfarandi {{PLURAL:$1|síða er|$1 síður eru}} í þessum flokki.',
 'category-file-count' => '{{PLURAL:$2|Þessi flokkur inniheldur einungis eftirfarandi skrá.|Eftirfarandi {{PLURAL:$1|skrá er|$1 skrár eru}} í þessum flokki, af alls $2.}}',
 'category-file-count-limited' => 'Eftirfarandi {{PLURAL:$1|skrá er|$1 skrár eru}} í þessum flokki.',
 'listingcontinuesabbrev' => 'frh.',
@@ -367,6 +367,7 @@ $messages = array(
 'newwindow' => '(opnast í nýjum glugga)',
 'cancel' => 'Hætta við',
 'moredotdotdot' => 'Meira...',
+'morenotlisted' => 'fleiri ekki skráð...',
 'mypage' => 'Síða',
 'mytalk' => 'Spjall',
 'anontalk' => 'Spjallsíða þessa vistfangs.',
@@ -668,7 +669,7 @@ Ekki gleyma að breyta [[Special:Preferences|{{SITENAME}} stillingunum]] þínum
 'gotaccount' => "Nú þegar með notandanafn? '''$1'''.",
 'gotaccountlink' => 'Skráðu þig inn',
 'userlogin-resetlink' => 'Gleymdir þú notendaupplýsingunum þínum?',
-'createaccountmail' => 'með tölvupósti',
+'createaccountmail' => 'Nota handahófsvalið bráðabirgðalykilorð og senda það á netfangið sem er tilgreint hér fyrir neðan',
 'createaccountreason' => 'Ástæða:',
 'badretype' => 'Lykilorðin sem þú skrifaðir eru ekki eins.',
 'userexists' => 'Þetta notandanafn er þegar í notkun.
@@ -742,6 +743,7 @@ Vinsamlegast reynið aftur síðar.',
 # E-mail sending
 'php-mail-error-unknown' => 'Óþekkt villa í PHP mail() aðgerð.',
 'user-mail-no-addy' => 'Gat ekki sent tölvupóst því ekkert tölvupóstfang fannst.',
+'user-mail-no-body' => 'Reyndi að senda tölvupóst með engu eða verulega stuttu meginmáli.',
 
 # Change password dialog
 'resetpass' => 'Breyta lykilorði',
@@ -963,8 +965,8 @@ Ef þú vilt ekki að textanum verði breytt skaltu ekki senda hann inn hér.<br
 Þú lofar okkur einnig að þú hafir skrifað þetta sjálfur, að efnið sé í almannaeigu eða að það heyri undir frjálst leyfi. (sjá $1).
 '''EKKI SENDA INN HÖFUNDARRÉTTARVARIРEFNI ÁN LEYFIS RÉTTHAFA!'''",
 'longpageerror' => "'''VILLA: Textinn sem þú sendir inn er {{PLURAL:$1|eitt kílóbæti|$1 kílóbæti}} að lengd, en hámarkið er {{PLURAL:$2|eitt kílóbæti|$2 kílóbæti}}. Ekki er hægt að vista textann.'''",
-'readonlywarning' => "'''AÐVÖRUN: Gagnagrunninum hefur verið læst til að unnt sé að framkvæma viðhaldsaðgerðir, svo þú getur ekki vistað breytingar þínar núna.
-Þú kannt að vilja að klippa og líma textann í textaskjal og vista hann fyrir síðar.'''
+'readonlywarning' => "'''AÐVÖRUN: Gagnagrunninum hefur verið læst til að unnt sé að framkvæma viðhaldsaðgerðir, svo þú getur ekki vistað breytingar þínar núna.'''
+Þú ættir að klippa og líma textann yfir í textaskjal til þess að geyma hann til seinni tíma.
 
 Stjórnandinn sem læsti honum gaf þessa skýringu: $1",
 'protectedpagewarning' => "'''Viðvörun: Þessari síðu hefur verið læst svo aðeins notendur með möppudýraréttindi geti breytt henni.'''
@@ -1026,6 +1028,15 @@ Hluti sniðsins verður ekki með.",
 Þeim hefur verið sleppt.",
 'post-expand-template-argument-category' => 'Síður sem innihalda frumbreytur sniða sem hefur verið sleppt',
 'parser-template-loop-warning' => 'Lykkja í sniði fundin: [[$1]]',
+'parser-template-recursion-depth-warning' => 'Sniðið er sjálkveðið of mörgum sinnum ($1)',
+'language-converter-depth-warning' => 'Farið út fyrir dýptarmörk tungumálabreytara ($1)',
+'node-count-exceeded-category' => 'Síður þar sem er umframfjöldi hnúta',
+'node-count-exceeded-warning' => 'Síðan fór fram yfir nóðutölu',
+'expansion-depth-exceeded-category' => 'Þær síður þar sem farið er út fyrir leyfða dýpt útvíkkunar',
+'expansion-depth-exceeded-warning' => 'Síðan fer út fyrir leyfða dýpt útvíkkunar',
+'parser-unstrip-loop-warning' => '"Unstrip" lykkja fannst',
+'parser-unstrip-recursion-limit' => 'Farið út fyrir „unstrip“ endurkvæmnismörk ($1)',
+'converter-manual-rule-error' => 'Villa í reglu handvirks tungumálabreytis',
 
 # "Undo" feature
 'undo-success' => 'Breytingin hefur verið tekin tilbaka. Vinsamlegast staðfestu og vistaðu svo.',
@@ -1107,6 +1118,10 @@ Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGE
 'revisiondelete' => 'Eyða/endurvekja breytingar',
 'revdelete-nooldid-title' => 'Ógild markbreyting',
 'revdelete-nooldid-text' => 'Annaðhvort hefur útgáfan sem á að fela ekki verið tilgreind, þessi útgáfa ekki verið til, eða að þú sért að reyna að fela núverandi útgáfu.',
+'revdelete-nologtype-title' => 'Engin skráargerð uppgefin',
+'revdelete-nologtype-text' => 'Þú tilgreindir ekki skráargerð til þess að framkvæma þessa aðgerð á.',
+'revdelete-nologid-title' => 'Ógild aðgerðarskráar færsla',
+'revdelete-nologid-text' => 'Þú hefur annaðhvort ekki tilgreint færslu í aðgerðarskrá til að framkvæma þessa aðgerð á, eða færslan er ekki til.',
 'revdelete-no-file' => 'Umbeðin skrá er ekki til.',
 'revdelete-show-file-confirm' => 'Ertu viss um að þú viljir sjá eydda breytingu af síðunni "<nowiki>$1</nowiki>" frá $2 $3?',
 'revdelete-show-file-submit' => 'Já',
@@ -1133,6 +1148,12 @@ Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGE
 'revdelete-unsuppress' => 'Fjarlægja takmarkanir á endurvöktum breytingum',
 'revdelete-log' => 'Ástæða:',
 'revdelete-submit' => 'Setja á {{PLURAL:$1|valda breytingu|valdar breytingar}}',
+'revdelete-success' => "'''Sýnileiki útgáfu er uppfærð.'''",
+'revdelete-failure' => "'''Mistókst að uppfæra sýnileika útgáfu:'''
+$1",
+'logdelete-success' => "'''Sýnleiki aðgerðarskráar uppfærður.'''",
+'logdelete-failure' => "'''Mistókst að uppfæra sýnileika aðgerðarskráar:'''
+$1",
 'revdel-restore' => 'Breyta sýn',
 'revdel-restore-deleted' => 'eyddar breytingar',
 'revdel-restore-visible' => 'sýnilegar breytingar',
@@ -1142,7 +1163,12 @@ Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGE
 Ekki er hægt að fela hana.',
 'revdelete-show-no-access' => 'Mistókst að sýna breytingu frá $1 $2: Þessi breyting hefur verið merkt sem "takmörkuð".
 Þú hefur ekki aðgang að henni.',
+'revdelete-modify-no-access' => 'Mistókst að breyta hlut frá $1 $2: Þessi breyting hefur verið merkt sem „takmörkuð”.
+Þú hefur ekki aðgang að henni.',
+'revdelete-modify-missing' => 'Mistókst að breyta hlut með auðkennið $1: Hann finnst ekki í gagnabankanum!',
 'revdelete-no-change' => "'''Viðvörun:''' Breytingin frá $1 $2 hefur þegar umbeðnar sýnileika stillingar.",
+'revdelete-concurrent-change' => 'Mistókst að breyta hlut frá $1 $2: Stöðu hans virðist hafa verið breytt af einhverjum öðrum á meðan þú reyndir að breyta honum.
+Vinsamlegast athugaðu í aðgerðarskránum.',
 'revdelete-only-restricted' => 'Mistókst að fela breytingu frá $1 $2: Þú getur ekki falið breytingu fyrir möppudýrum án þess að velja eina af hinum sýnileika stillingunum.',
 'revdelete-reason-dropdown' => '*Algengar eyðingarástæður
 **Höfundarréttarbrot
@@ -1152,9 +1178,12 @@ Ekki er hægt að fela hana.',
 'revdelete-otherreason' => 'Aðrar/fleiri ástæður:',
 'revdelete-reasonotherlist' => 'Önnur ástæða',
 'revdelete-edit-reasonlist' => 'Eyðingarástæður',
+'revdelete-offender' => 'Höfundur þessarar útgáfu:',
 
 # Suppression log
 'suppressionlog' => 'Bælingarskrá',
+'suppressionlogtext' => 'Hér fyrir neðan er listi af eyðingum og bönnum sem innihalda efni sem hefur verið falið fyrir stjórnendum.
+Sjáðu [[Special:BlockList|bannlistann]] fyrir lista yfir núverandi bönn.',
 
 # History merging
 'mergehistory' => 'Sameina breytingaskrár',
@@ -1164,6 +1193,21 @@ Sjáðu til þess að þessi breyting sameini breytingarskrárnar samfellt.',
 'mergehistory-from' => 'Heimildsíða:',
 'mergehistory-into' => 'Áætlunarsíða:',
 'mergehistory-list' => 'Breytingarskrá sem hægt er að sameina',
+'mergehistory-merge' => 'Eftirtaldar útgáfur [[:$1]] má sameina [[:$2]].
+Notaðu valtakkadálkinn til þess að sameina aðeins þær útgáfur sem stofnaðar voru fyrir uppgefið tímamark.
+Athugaðu að með því að nota flakktenglana er þessi dálkur endurstilltur.',
+'mergehistory-go' => 'Sýna breytingar sem hægt er að sameina',
+'mergehistory-submit' => 'Sameina útgáfur',
+'mergehistory-empty' => 'Engar útgáfur sem hægt er að sameina.',
+'mergehistory-success' => '$3 {{PLURAL:$3|útgáfa|útgáfur}} af [[:$1]] sameinaðar í [[:$2]].',
+'mergehistory-fail' => 'Gat ekki sameinað breytingasögur. Vinsamlegast athugaðu síðuna og tímabreyturnar.',
+'mergehistory-no-source' => 'Upprunasíðan $1 er ekki til.',
+'mergehistory-no-destination' => 'Marksíðan $1 er ekki til.',
+'mergehistory-invalid-source' => 'Upprunasíðan verður að hafa gildan titil.',
+'mergehistory-invalid-destination' => 'Marksíðan verður að hafa gildan titil.',
+'mergehistory-autocomment' => 'Sameinaði [[:$1]] inn í [[:$2]]',
+'mergehistory-comment' => 'Sameinaði [[:$1]] inn í [[:$2]]: $3',
+'mergehistory-same-destination' => 'Upprunasíðan og marksíðan mega ekki vera sú sama',
 'mergehistory-reason' => 'Ástæða:',
 
 # Merge log
@@ -1183,6 +1227,10 @@ Sjáðu til þess að þessi breyting sameini breytingarskrárnar samfellt.',
 'editundo' => 'Taka aftur þessa breytingu',
 'diff-multi' => '({{PLURAL:$1|Ein millibreyting ekki sýnd|$1 millibreytingar ekki sýndar}} frá {{PLURAL:$2|notanda|$2 notendum}}.)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Ein millibreyting ekki sýnd|$1 millibreytingar ekki sýndar}} frá fleiri en {{PLURAL:$2|einum notanda|$2 notendum}}.)',
+'difference-missing-revision' => '{{PLURAL:$2|Ein útgáfa|$2 útgáfur}} samanburðarins ($1) {{PLURAL:$2|fannst|fundust}} ekki.
+
+Þetta gerist oftast þegar úreldur samanburðartengill tengir á síðu sem hefur verið eytt.
+Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} eyðingarskránni].',
 
 # Search results
 'searchresults' => 'Leitarniðurstöður',
@@ -1226,7 +1274,7 @@ Sjáðu til þess að þessi breyting sameini breytingarskrárnar samfellt.',
 'search-interwiki-default' => '$1 útkomur:',
 'search-interwiki-more' => '(fleiri)',
 'search-relatedarticle' => 'Tengt',
-'mwsuggest-disable' => 'Gera AJAX-uppástungur óvirkar',
+'mwsuggest-disable' => 'Gera leitar uppástungur óvirkar',
 'searcheverything-enable' => 'Leita í öllum nafnrýmum',
 'searchrelated' => 'tengt',
 'searchall' => 'öllum',
@@ -1718,11 +1766,14 @@ Ef vandamálið lagast ekki, hafðu samband við [[Special:ListUsers/sysop|stjó
 'upload-copy-upload-invalid-domain' => 'Lokað er fyrir afritun skráa frá öðrum vefþjón á þessu vefsvæði.',
 
 # File backend
+'backend-fail-stream' => 'Gat ekki streymt skránni „$1“.',
 'backend-fail-backup' => 'Öryggisafritun skráarinnar $1 mistókst.',
 'backend-fail-notexists' => 'Skráin $1 er ekki til.',
+'backend-fail-hashes' => 'Gat ekki nálgast tætigildi skráanna til samanburðar.',
 'backend-fail-notsame' => 'Ólík skrá er þegar til á $1.',
 'backend-fail-invalidpath' => '$1 er ekki gildur geymslustaður.',
 'backend-fail-delete' => 'Mistókst að eyða skránni $1.',
+'backend-fail-describe' => 'Mistókst að breyta lýsisgögnum skráarinnar „$1“.',
 'backend-fail-alreadyexists' => 'Skráin $1 er þegar til.',
 'backend-fail-store' => 'Mistókst að vista skrá $1 á $2.',
 'backend-fail-copy' => 'Mistókst að afrita skjal $1 á $2.',
@@ -1734,8 +1785,28 @@ Ef vandamálið lagast ekki, hafðu samband við [[Special:ListUsers/sysop|stjó
 'backend-fail-create' => 'Mistókst að skrifa skrá $1.',
 'backend-fail-maxsize' => 'Mistókst að skrifa skránna $1 því hún er stærri en {{PLURAL:$2|eitt bæti|$2 bæti}}.',
 'backend-fail-readonly' => 'Gagnabankann "$1" er engöngu hægt að lesa í augnablikinu. Ástæðan sem var gefin er: "\'\'$2\'\'"',
+'backend-fail-synced' => 'Skráin $1 er í ósamkvæmu ástandi innan innri geymslubakenda',
 'backend-fail-connect' => 'Mistókst að tengjast gagnabankanum "$1".',
 'backend-fail-internal' => 'Óþekkt villa átti sér stað í gagnabankanum "$1".',
+'backend-fail-contenttype' => 'Gat ekki ákvarðað innihaldgerð skráarinnar til geymslu á „$1“.',
+'backend-fail-batchsize' => 'Geymslubakendinn fékk bunka af $1 {{PLURAL:$1|skráaraðgerð|skráaraðgerðum}}; mest eru leyfðar $2 {{PLURAL:$2|aðgerð|aðgerðir}}.',
+'backend-fail-usable' => 'Gat ekki lesið skrána „$1“ vegna ófullnægjandi aðgangsheimilda eða týndra mappa/íláta.',
+
+# File journal errors
+'filejournal-fail-dbconnect' => 'Gat ekki tengst dagbókargrunni fyrir geymslubakendann „$1“.',
+'filejournal-fail-dbquery' => 'Gat ekki uppfært dagbókargrunn vegna geymslubakendans „$1“.',
+
+# Lock manager
+'lockmanager-notlocked' => 'Gat ekki aflæst „$1“; það er ekki læst.',
+'lockmanager-fail-closelock' => 'Gat ekki lokað lásaskrá vegna „$1“.',
+'lockmanager-fail-deletelock' => 'Gat ekki eytt lásaskrá vegna „$1“.',
+'lockmanager-fail-acquirelock' => 'Gat ekki nálgast lás vegna „$1“.',
+'lockmanager-fail-openlock' => 'Gat ekki opnað lásaskrá vegna „$1“.',
+'lockmanager-fail-releaselock' => 'Gat ekki opnað lás vegna „$1“.',
+'lockmanager-fail-db-bucket' => 'Náði ekki sambandi við nógu marga lása í fötunni $1.',
+'lockmanager-fail-db-release' => 'Gat ekki opnað lása á gagnagrunninum $1.',
+'lockmanager-fail-svr-acquire' => 'Gat ekki nálgast lása á þjóninum $1.',
+'lockmanager-fail-svr-release' => 'Gat ekki opnað lása á þjóninum $1.',
 
 # ZipDirectoryReader
 'zip-file-open-error' => 'Mistök við opnun skráarinnar fyrir ZIP athuganir.',
@@ -1754,6 +1825,7 @@ Ekki er hægt að athuga öryggi skráarinnar almennilega.',
 Reyndu aftur.',
 'uploadstash-errclear' => 'Tæming listans mistókst.',
 'uploadstash-refresh' => 'Endurhlaða listann',
+'invalid-chunk-offset' => 'Ógild raðbreyting bunka',
 
 # img_auth script messages
 'img-auth-accessdenied' => 'Aðgangur óheimill',
@@ -1761,8 +1833,16 @@ Reyndu aftur.',
 Biðlarinn þínn er ekki stilltur til að gefa upp þessar upplýsingar.
 Þær mega vera CGI-byggðar og mega ekki styðja img_auth.
 https://www.mediawiki.org/wiki/Manual:Image_Authorization',
+'img-auth-notindir' => 'Umbeðin slóð var ekki í stilltri upphlaðsmöppu.',
+'img-auth-badtitle' => 'Mistókst að búa til gildan titil útfrá „$1”.',
+'img-auth-nologinnWL' => 'Þú ert ekki skráð(ur) inn og „$1“ er ekki á hvítlista.',
 'img-auth-nofile' => 'Skráin "$1" er ekki til.',
+'img-auth-isdir' => 'Þú ert að reyna að nálgast möppuna „$1“.
+Aðeins skráaraðgangur er leyfður.',
 'img-auth-streaming' => 'Streymi "$1".',
+'img-auth-public' => 'Virkni img_auth.php er að flytja út skrár frá einkawiki.
+Þessi wiki er stilltur sem opinber wiki.
+Vegna öryggissjónarmiða er img_auth.php óvirkt.',
 'img-auth-noread' => 'Notandinn hefur ekki rétt til að lesa "$1"',
 'img-auth-bad-query-string' => 'Vefslóðin hefur ógildan fyrirspurnar streng.',
 
@@ -1846,6 +1926,7 @@ Hentugra væri ef þú gætir breytt lýsingu skráarinnar á [$2 myndasíðu] h
 'uploadnewversion-linktext' => 'Hlaða inn nýrri útgáfu af þessari skrá',
 'shared-repo-from' => 'frá $1',
 'shared-repo' => 'sameiginlegu myndasafni',
+'upload-disallowed-here' => 'Þú getur ekki yfirskrifað þessa skrá.',
 
 # File reversion
 'filerevert' => 'Taka aftur $1',
@@ -2097,7 +2178,7 @@ Leitin þarf að minnsta kosti að innihalda rótarlén, eins og "*.org"
 # Special:ActiveUsers
 'activeusers' => 'Virkir notendur',
 '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|breyting|breytingar}} á {{PLURAL:$3|síðastliðnum degi|síðustu $3 dögum}}',
+'activeusers-count' => '$1 {{PLURAL:$1|aðgerð|aðgerðir}} á {{PLURAL:$3|síðastliðnum degi|síðustu $3 dögum}}',
 'activeusers-from' => 'Sýna notendur sem byrja á:',
 'activeusers-hidebots' => 'Fela vélmenni',
 'activeusers-hidesysops' => 'Fela möppudýr',
@@ -2329,8 +2410,8 @@ Núverandi staða síðunnar er '''$1''':",
 'protect-cascadeon' => 'Þessi síða er vernduð vegna þess að hún er innifalin í eftirfarandi {{PLURAL:$1|síðu, sem er keðjuvernduð|síðum, sem eru keðjuverndaðar}}.
 Þú getur breytt verndunarstigi þessarar síðu, en það mun ekki hafa áhrif á keðjuverndunina.',
 'protect-default' => 'Leyfa öllum notendum',
-'protect-fallback' => '„$1“ réttindi nauðsynleg',
-'protect-level-autoconfirmed' => 'Banna nýja og óinnskráða notendur',
+'protect-fallback' => 'Leyfa eingöngu notendur með „$1“ réttindi',
+'protect-level-autoconfirmed' => 'Leyfa aðeins sjálkrafa staðfesta notendur',
 'protect-level-sysop' => 'Leyfa aðeins stjórnendur',
 'protect-summary-cascade' => 'keðjuvörn',
 'protect-expiring' => 'rennur út $1 (UTC)',
@@ -2498,8 +2579,8 @@ Gefðu nákvæma skýringu að neðan (til dæmis, með því að vísa í þær
 ** Yfirþyrmandi framkoma/áreitni
 ** Misnotkun á fjölda notandanafna
 ** Óásættanlegt notandanafn',
-'ipb-hardblock' => 'Hindra innskráðum notendum frá því að breyta frá þessu vistfangi.',
-'ipbcreateaccount' => 'Banna nýskráningu notanda',
+'ipb-hardblock' => 'Banna innskráðum notendum að breyta frá þessu vistfangi.',
+'ipbcreateaccount' => 'Banna nýskráningu notandanafns',
 'ipbemailban' => 'Banna notanda að senda tölvupóst',
 'ipbenableautoblock' => 'Banna síðasta vistfang notanda sjálfkrafa; og þau vistföng sem viðkomandi notar til að breyta síðum',
 'ipbsubmit' => 'Banna notanda',
@@ -2509,7 +2590,7 @@ Gefðu nákvæma skýringu að neðan (til dæmis, með því að vísa í þær
 'ipbotherreason' => 'Önnur/auka ástæða:',
 'ipbhidename' => 'Fela notandanafn úr breytingarskrá og listum',
 'ipbwatchuser' => 'Vakta notanda- og spjallsíður þessa notanda',
-'ipb-disableusertalk' => 'Banna þessum notenda að breyta egin spjallsíðu',
+'ipb-disableusertalk' => 'Banna þessum notanda að breyta eigin spjallsíðu',
 'ipb-change-block' => 'Endurbanna notanda með þessum stillingum',
 'ipb-confirm' => 'Staðfesta bann',
 'badipaddress' => 'Ógilt vistfang',
@@ -2517,7 +2598,7 @@ Gefðu nákvæma skýringu að neðan (til dæmis, með því að vísa í þær
 'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] hefur verið bannaður/bönnuð.<br />
 Sjá [[Special:BlockList|bannaðir notendur og vistföng]] fyrir yfirlit yfir núverandi bönn.',
 'ipb-blockingself' => 'Þú ert í þann mund að banna sjálfan þig! Ertu viss um að þú viljir gera það?',
-'ipb-confirmhideuser' => 'Þú ert í þann mund að banna notenda sem er falinn. Notendanafn hans mun ekki birtast í listum og aðgerðarskrám. Ertu viss um að þú viljir gera það?',
+'ipb-confirmhideuser' => 'Þú ert í þann mund að banna notanda sem er falinn. Notandanafn hans mun ekki birtast í listum og aðgerðarskrám. Ertu viss um að þú viljir gera það?',
 'ipb-edit-dropdown' => 'Breyta ástæðu fyrir banni',
 'ipb-unblock-addr' => 'Afbanna $1',
 'ipb-unblock' => 'Afbanna notanda eða vistfang',
@@ -2610,6 +2691,10 @@ Vinsamlegast hafðu samband við internetþjónustuaðilann þinn eða netstjór
 # Developer tools
 'lockdb' => 'Læsa gagnagrunninum',
 'unlockdb' => 'Opna gagnagrunninn',
+'lockdbtext' => 'Læsing gagnagrunnsins mun hindra alla notendur í því að breyta síðum, stillingum, vaktlistum og öðrum möguleikum sem þarfnast aðgangs að gagnagrunninum.
+Staðfestu að þetta er það sem þú vilt gera og að þú munir aflæsa grunninum eftir að viðhaldsverki er lokið.',
+'unlockdbtext' => 'Aflæsing gagnagrunnsins mun gera öllum notendum kleift á ný að breyta síðum, stillingum, vaktlistum og öðrum möguleikum sem þarfnast aðgangs að gagnagrunninum.
+Staðfestu að þetta er það sem þú vilt gera.',
 'lockconfirm' => 'Já, ég vil læsa gagnagrunninum.',
 'unlockconfirm' => 'Já, ég vil aflæsa gagnagrunninum.',
 'lockbtn' => 'Læsa gagnagrunni',
@@ -2620,6 +2705,8 @@ Vinsamlegast hafðu samband við internetþjónustuaðilann þinn eða netstjór
 'lockdbsuccesstext' => 'Gagnagrunninum hefur verið læst.<br />
 Mundu að [[Special:UnlockDB|opna hann aftur]] þegar þú hefur lokið viðgerðum.',
 'unlockdbsuccesstext' => 'Gagnagrunnurinn hefur verið opnaður.',
+'lockfilenotwritable' => 'Skrá gagnagrunnslássins er ekki skrifanleg.
+Til þess að læsa eða aflæsa gagnagrunni þarf vefþjónninn að geta skrifað í skrána.',
 'databasenotlocked' => 'Gagnagrunnurinn er ekki læstur.',
 'lockedbyandtime' => '(af {{GENDER:$1|$1}} kl. $3, $2)',
 
@@ -2694,6 +2781,7 @@ Síðan „[[:$1]]“ er þegar til. Viltu eyða henni til þess að rýma til f
 'immobile-target-namespace-iw' => 'Óheimilt er að færa síðu með tungumálatengli.',
 'immobile-source-page' => 'Þessi síða er ekki færanleg.',
 'immobile-target-page' => 'Get ekki fært á áætlaðan titil.',
+'bad-target-model' => 'Markstaðurinn sem þú valdir notast við annað innihaldslíkan. Get ekki umbreytt frá $1 í $2.',
 'imagenocrossnamespace' => 'Get ekki fært skrá í skrálaust nafnrými',
 'nonfile-cannot-move-to-file' => 'Get ekki fært annað en skrár í nafnrými skráa.',
 'imagetypemismatch' => 'Nýi nafnaukinn passar ekki við tegund hennar',
@@ -2718,6 +2806,7 @@ Til þess að flytja út síður, skrifaðu titla þeirra í reitina hér fyrir
 
 Ef síðari möguleikinn á við getur þú einnig notað tengil, til dæmis
 [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] fyrir síðuna "[[{{MediaWiki:Mainpage}}]]".',
+'exportall' => 'Flytja út allar síður',
 'exportcuronly' => 'Aðeins núverandi útgáfu án breytingaskrár',
 'exportnohistory' => "----
 '''Athugaðu:''' Að flytja út alla breytingasögu síðna á þennan hátt hefur verið óvirkjað vegna ástæðna afkasta.",
@@ -2752,10 +2841,14 @@ Vinsamlegast heimsæktu [//www.mediawiki.org/wiki/Localisation MediaWiki-staðf
 'thumbnail-more' => 'Stækka',
 'filemissing' => 'Skrá vantar',
 'thumbnail_error' => 'Villa við gerð smámyndar: $1',
+'djvu_page_error' => 'DjVu-blaðsíða er utan marka',
+'djvu_no_xml' => 'Mistókst að sækja XML-gögn fyrir DjVu skrá',
 'thumbnail-temp-create' => 'Mistókst að búa til tímabundna smámynd.',
+'thumbnail-dest-create' => 'Gat ekki vistað smámynd á markstað',
 'thumbnail_invalid_params' => 'Breytur smámyndarinnar eru rangar',
 'thumbnail_dest_directory' => 'Mistókst að búa til niðurhals möppu',
 'thumbnail_image-type' => 'Enginn stuðningur er við þetta skráarsnið',
+'thumbnail_gd-library' => 'Ófullkomin stilling GD-safns: Skortir aðgerðina $1',
 'thumbnail_image-missing' => 'Skránna vantar: $1',
 
 # Special:Import
@@ -2769,6 +2862,7 @@ Allir innflutningar eru skráð í [[Special:Log/import|innflutningsskránna]].'
 'import-interwiki-templates' => 'Innifala öll snið með',
 'import-interwiki-submit' => 'Flytja inn',
 'import-interwiki-namespace' => 'Ákvörðunarnafnrými:',
+'import-interwiki-rootpage' => 'Markmóðursíða (valfrjáls):',
 'import-upload-filename' => 'Skráarnafn:',
 'import-comment' => 'Athugasemdir:',
 'importtext' => 'Vinsamlegast fluttu út skránna frá upprunalegum wiki með því að nota [[Special:Export|Flytja út síður]].
@@ -2778,6 +2872,7 @@ Vistaðu skránna á tölvunni þinni og hladdu henni inn hér.',
 'importnopages' => 'Engar síður til innflutnings.',
 'imported-log-entries' => '$1 {{PLURAL:$1|breytingar færsla|breytingar færslur}} hafa verið fluttar inn',
 'importfailed' => 'Innhlaðning mistókst: $1',
+'importunknownsource' => 'Óþekkt innflutningstilfangsgerð',
 'importcantopen' => 'Get ekki opnað innflutt skjal',
 'importbadinterwiki' => 'Villa í tungumálatengli',
 'importnotext' => 'Tómt eða enginn texti',
@@ -2804,6 +2899,10 @@ Vinsamlegast reyndu aftur.',
 'import-error-interwiki' => 'Síðan "$1" var ekki flutt inn því nafn hennar er frátekið fyrir ytri tengla (tungumálatengla).',
 'import-error-special' => 'Síðan "$1" var ekki flutt inn því hún tilheyrir ákveðnu nafnrými sem leyfir ekki síður.',
 'import-error-invalid' => 'Síðan "$1" var ekki flutt inn því nafn hennar er ógilt.',
+'import-error-unserialize' => 'Ekki unnt að afraða útgáfu $2 af síðunni „$1“. Útgáfan var sögð nota innihaldslíkan $3 raðað sem $4.',
+'import-options-wrong' => '{{PLURAL:$2|Rangur möguleiki|Rangir möguleikar}}: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'Uppgefin móðursíða hefur ógildan titil.',
+'import-rootpage-nosubpage' => 'Nafnrými „$1“ móðursíðunnar leyfir ekki undirsíður.',
 
 # Import log
 'importlogpage' => 'Innflutningsskrá',
@@ -2815,7 +2914,12 @@ Vinsamlegast reyndu aftur.',
 
 # JavaScriptTest
 'javascripttest' => 'JavaScript prófun',
+'javascripttest-title' => 'Keyri $1 prófun',
+'javascripttest-pagetext-noframework' => 'Þessi síða er frátekin fyrir JavaScript prófanir.',
+'javascripttest-pagetext-unknownframework' => 'Óþekktur prófunarrammi „$1“.',
+'javascripttest-pagetext-frameworks' => 'Veldu einn eftirtalinna prófunarramma: $1',
 'javascripttest-pagetext-skins' => 'Veldu þema sem á að keyra prófanirnar á:',
+'javascripttest-qunit-intro' => 'Sjá [$1 tilraunaskjölun] á mediawiki.org.',
 
 # Tooltip help for the actions
 'tooltip-pt-userpage' => 'Notandasíðan þín',
@@ -2905,6 +3009,8 @@ Vinsamlegast reyndu aftur.',
 'others' => 'aðrir',
 'siteusers' => '{{SITENAME}} {{PLURAL:$2|notandi|notendur}} $1',
 'anonusers' => '{{SITENAME}} {{PLURAL:$2|nafnlaus notandi|nafnlausir notendur}} $1',
+'creditspage' => 'Höfundar síðunnar',
+'nocredits' => 'Engar höfundarupplýsingar eru til um þessa síðu',
 
 # Spam protection
 'spamprotectiontitle' => 'Amapósts sía',
@@ -2918,6 +3024,7 @@ Vinsamlegast reyndu aftur.',
 
 # Info page
 'pageinfo-title' => 'Upplýsingar um $1',
+'pageinfo-not-current' => 'Því miður er ekki hægt að veita þessar upplýsingar um gamlar útgáfur.',
 'pageinfo-header-basic' => 'Grunnupplýsingar',
 'pageinfo-header-edits' => 'Breytingarskrá',
 'pageinfo-header-restrictions' => 'Verndunarstig síðunnar',
@@ -2932,6 +3039,7 @@ Vinsamlegast reyndu aftur.',
 'pageinfo-robot-noindex' => 'Óskráanleg',
 'pageinfo-views' => 'Fjöldi innlita',
 'pageinfo-watchers' => 'Fjöldi notenda, sem vakta síðuna',
+'pageinfo-few-watchers' => 'Vöktuð af færri en $1 {{PLURAL:$1|notanda|notendum}}',
 'pageinfo-redirects-name' => 'Tilvísanir til þessarar síðu',
 'pageinfo-subpages-name' => 'Undirsíður þessarar síðu',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|tilvísun|tilvísanir}}; $3 {{PLURAL:$3|ekki tilvísun|ekki tilvísanir}})',
@@ -2946,6 +3054,7 @@ Vinsamlegast reyndu aftur.',
 'pageinfo-magic-words' => 'Töfra {{PLURAL:$1|orð}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Falinn flokkur|Faldir flokkar}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Innifalið snið|Innifalin snið}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Síða|Síður}} innfelldar á ($1)',
 'pageinfo-toolboxlink' => 'Síðuupplýsingar',
 'pageinfo-redirectsto' => 'Vísar til',
 'pageinfo-redirectsto-info' => 'upplýsingar',
@@ -2954,6 +3063,10 @@ Vinsamlegast reyndu aftur.',
 'pageinfo-protect-cascading' => 'Keðjuvörn hefst hér',
 'pageinfo-protect-cascading-yes' => 'Já',
 'pageinfo-protect-cascading-from' => 'Keðjuvörn stafar frá',
+'pageinfo-category-info' => 'Flokkaupplýsingar',
+'pageinfo-category-pages' => 'Fjöldi síðna',
+'pageinfo-category-subcats' => 'Fjöldi undirflokka',
+'pageinfo-category-files' => 'Fjöldi skráa',
 
 # Skin names
 'skinname-standard' => 'Sígilt',
@@ -2975,6 +3088,8 @@ Vinsamlegast reyndu aftur.',
 'markedaspatrollederror' => 'Get ekki merkt sem yfirfarið',
 'markedaspatrollederrortext' => 'Þú verður að velja breytingu til að merkja sem yfirfarið.',
 'markedaspatrollederror-noautopatrol' => 'Þú hefur ekki réttindi til að merkja eigin breytingar sem yfirfarnar.',
+'markedaspatrollednotify' => 'Þessi breyting á $1 hefur verið merkt sem yfirfarin.',
+'markedaspatrollederrornotify' => 'Mistókst að merkja síðuna sem yfirfarna.',
 
 # Patrol log
 'patrol-log-page' => 'Yfirferðarskrá',
@@ -3004,6 +3119,8 @@ Vinsamlegast reyndu aftur.',
 'file-info-size-pages' => '$1 x $2 dílar, skráarstærð: $3, MIME-gerð: $4, $5 {{PLURAL:$5|síða|síður}} tengja í skránna.',
 'file-nohires' => 'Það er engin hærri upplausn til.',
 'svg-long-desc' => 'SVG-skrá, að nafni til $1 × $2 dílar, skráarstærð: $3',
+'svg-long-desc-animated' => 'SVG-hreyfimynd, að nafni til $1 × $2 dílar, skráarstærð: $3',
+'svg-long-error' => 'Ógild SVG skrá: $1',
 'show-big-image' => 'Mesta upplausn',
 'show-big-image-preview' => 'Stærð þessarar forskoðunar: $1',
 'show-big-image-other' => '{{PLURAL:$2|Önnur upplausn|Aðrar upplausnir}}: $1.',
@@ -3013,6 +3130,8 @@ Vinsamlegast reyndu aftur.',
 'file-info-png-looped' => 'síendurtekin hreyfimynd',
 'file-info-png-repeat' => 'spilað {{PLURAL:$1|einu sinni|$1 sinnum}}',
 'file-info-png-frames' => '$1 {{PLURAL:$1|rammi|rammar}}',
+'file-no-thumb-animation' => "'''Athugið: Vegna tæknilegra takmarkanna birtast smámyndir af þessari skrá aðeins sem kyrrmyndir.'''",
+'file-no-thumb-animation-gif' => "'''Athugið:Vegna tæknilegra takmarkanna munu smámyndir af GIF-myndum í hárri upplausn eins og þessari ekki birtast sem hreyfimyndir.'''",
 
 # Special:NewFiles
 'newimages' => 'Myndasafn nýlegra skráa',
@@ -3027,11 +3146,14 @@ Vinsamlegast reyndu aftur.',
 'sp-newimages-showfrom' => 'Leita af nýjum skráum frá $2, $1',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
-'seconds' => '{{PLURAL:$1|ein sekúnda|$1 sekúndur}}',
-'minutes' => '{{PLURAL:$1|ein mínúta|$1 mínútur}}',
-'hours' => '{{PLURAL:$1|einn klukkutími|$1 klukkutímar}}',
-'days' => '{{PLURAL:$1|einn dagur|$1 dagar}}',
+'seconds' => '{{PLURAL:$1|einni sekúndu|$1 sekúndum}}',
+'minutes' => '{{PLURAL:$1|einni mínútu|$1 mínútum}}',
+'hours' => '{{PLURAL:$1|einum klukkutíma|$1 klukkutímum}}',
+'days' => '{{PLURAL:$1|einum degi|$1 dögum}}',
+'months' => '{{PLURAL:$1|$1 mánuði|$1 mánuðum}}',
+'years' => '{{PLURAL:$1|$1 ári|$1 árum}}',
 'ago' => '$1 síðan',
+'just-now' => 'akkúrat núna',
 
 # Bad image list
 'bad_image_list' => 'Sniðið er eftirfarandi:
@@ -3071,15 +3193,18 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-orientation' => 'Lega',
 'exif-samplesperpixel' => 'Fjöldi eininga',
 'exif-planarconfiguration' => 'Tilhögun gagna',
+'exif-ycbcrsubsampling' => 'Undirstökunarsnið Y gagnvart C',
 'exif-ycbcrpositioning' => 'Staðsetning Y og C',
 'exif-xresolution' => 'Lárétt upplausn',
 'exif-yresolution' => 'Lóðrétt upplausn',
 'exif-stripoffsets' => 'Staðsetning gagna',
 'exif-rowsperstrip' => 'Fjöldi raða á ræmu',
 'exif-stripbytecounts' => 'Bæti á hverri þjappaðri ræmu',
+'exif-jpeginterchangeformat' => 'Jöfnun JPEG SOI',
 'exif-jpeginterchangeformatlength' => 'bæti af JPEG gögnum',
 'exif-whitepoint' => 'Krómatísmi hvíta punkts',
 'exif-primarychromaticities' => 'Krómatísmi grunnlita',
+'exif-ycbcrcoefficients' => 'Litarýmisumbreytingargfylkistuðlar',
 'exif-referenceblackwhite' => 'Pör svartra og hvítra tilvísana gilda',
 'exif-datetime' => 'Dagsetning og tími breytingar',
 'exif-imagedescription' => 'Titill myndar',
@@ -3100,15 +3225,21 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-datetimeoriginal' => 'Upprunaleg dagsetning',
 'exif-datetimedigitized' => 'Dagsetning stafrænnar myndar',
 'exif-subsectime' => 'DagsetningTími sekúndubrot',
+'exif-subsectimeoriginal' => 'DagurTímiUpprunaleg sekúndubrot',
+'exif-subsectimedigitized' => 'DagurTímiStafrænt sekúndubrot',
 'exif-exposuretime' => 'Lýsingartími',
 'exif-exposuretime-format' => '$1 sekúnda ($2)',
+'exif-fnumber' => 'F-tala',
 'exif-exposureprogram' => 'Ljósastilling',
 'exif-spectralsensitivity' => 'Litrófsnæmni',
 'exif-isospeedratings' => 'ISO filmuhraði',
 'exif-shutterspeedvalue' => 'APEX lokunarhraði',
 'exif-aperturevalue' => 'APEX ljósop',
 'exif-brightnessvalue' => 'APEX birtustig',
+'exif-exposurebiasvalue' => 'APEX lýsingarbjagi',
+'exif-maxaperturevalue' => 'Hámarksvídd ljósops innra byrðis linsu',
 'exif-subjectdistance' => 'Lengd að viðfangsefni',
+'exif-meteringmode' => 'Mælingarhamur',
 'exif-lightsource' => 'Uppspretta ljóssins',
 'exif-flash' => 'Leifturljós',
 'exif-focallength' => 'Brennivídd',
@@ -3139,6 +3270,7 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-gpslatitude' => 'Breiddargráða',
 'exif-gpslongituderef' => 'Austur- eða vestur lengdargráða',
 'exif-gpslongitude' => 'Lengdargráða',
+'exif-gpsaltituderef' => 'Hæðarviðmið',
 'exif-gpsaltitude' => 'Stjörnuhæð',
 'exif-gpstimestamp' => 'GPS tími (atómklukka)',
 'exif-gpssatellites' => 'Gervihnettir sem voru notaðir við mælingu',
@@ -3230,6 +3362,8 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 
 'exif-planarconfiguration-2' => 'planar snið',
 
+'exif-colorspace-65535' => 'Ókvarðað',
+
 'exif-componentsconfiguration-0' => 'er ekki til',
 
 'exif-exposureprogram-0' => 'Ekki skilgreind',
@@ -3248,6 +3382,7 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-meteringmode-3' => 'Blettur',
 'exif-meteringmode-4' => 'Margir-blettir',
 'exif-meteringmode-5' => 'Mynstur',
+'exif-meteringmode-6' => 'Að hluta',
 'exif-meteringmode-255' => 'Annað',
 
 'exif-lightsource-0' => 'Óþekkt',
@@ -3258,9 +3393,14 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-lightsource-9' => 'Gott veður',
 'exif-lightsource-10' => 'Skýjað',
 'exif-lightsource-11' => 'Skuggi',
+'exif-lightsource-12' => 'Dagsljós flúrlýsing (D 5700 - 7100K)',
+'exif-lightsource-13' => 'Dagur hvít flúrlýsing (N 4600 - 5400K)',
+'exif-lightsource-14' => 'Köld hvít flúrlýsing (W 3900 - 4500K)',
+'exif-lightsource-15' => 'Hvít flúrlýsing (WW 3200 - 3700K)',
 'exif-lightsource-17' => 'Staðaljós A',
 'exif-lightsource-18' => 'Staðaljós B',
 'exif-lightsource-19' => 'Staðaljós C',
+'exif-lightsource-24' => 'ISO stúdíótungsten',
 'exif-lightsource-255' => 'Önnur ljósuppspretta',
 
 # Flash modes
@@ -3280,6 +3420,8 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-sensingmethod-4' => 'Þriggja-kísilflögu litsviðs skynjari',
 'exif-sensingmethod-5' => 'Raðbundinn litsviðs skynjari',
 
+'exif-filesource-3' => 'Stafræn ljósmyndavél',
+
 'exif-customrendered-0' => 'Venjuleg vinnsla',
 'exif-customrendered-1' => 'Sérstök vinnsla',
 
@@ -3355,6 +3497,10 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-objectcycle-p' => 'að kvöldi',
 'exif-objectcycle-b' => 'að morgni og kvöldi',
 
+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
+'exif-gpsdirection-t' => 'Raunátt',
+'exif-gpsdirection-m' => 'Segulátt',
+
 'exif-ycbcrpositioning-1' => 'Miðjuð',
 
 'exif-dc-contributor' => 'Framleggjendur',
@@ -3363,6 +3509,7 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-dc-relation' => 'Tengd margmiðlunargögn',
 'exif-dc-rights' => 'Réttindi',
 'exif-dc-source' => 'Uppruni margmiðlunarskrár',
+'exif-dc-type' => 'Gerð miðlunarefnis',
 
 'exif-rating-rejected' => 'Hafnað',
 
@@ -3375,6 +3522,7 @@ Ef skránni hefur verið breytt, kann að vera að einhverjar upplýsingar eigi
 'exif-iimcategory-edu' => 'Menntun',
 'exif-iimcategory-evn' => 'Umhverfi',
 'exif-iimcategory-hth' => 'Heilsa',
+'exif-iimcategory-hum' => 'Maðurinn',
 'exif-iimcategory-lab' => 'Verkamennska',
 'exif-iimcategory-lif' => 'Lífstíll og tómstundagaman',
 'exif-iimcategory-pol' => 'Pólitík',
@@ -3604,7 +3752,7 @@ Myndir eru sýndar í fullri upplausn og önnur skráarsnið eru ræst í sjálf
 'specialpages-group-highuse' => 'Mest notuðu síðurnar',
 'specialpages-group-pages' => 'Listar yfir síður',
 'specialpages-group-pagetools' => 'Síðuverkfæri',
-'specialpages-group-wiki' => 'Wiki gögn og tól',
+'specialpages-group-wiki' => 'Gögn og tól',
 'specialpages-group-redirects' => 'Tilvísaðar kerfisíður',
 'specialpages-group-spam' => 'Amapósts sía',
 
@@ -3702,9 +3850,12 @@ Tæknilegir örðugleikar eru á þessari síðu.',
 'logentry-newusers-newusers' => 'Notandaaðgangurinn $1 var stofnaður',
 'logentry-newusers-create' => 'Notandaaðgangurinn $1 var stofnaður',
 'logentry-newusers-create2' => '$1 stofnaði notandaaðganginn $3',
+'logentry-newusers-byemail' => 'Notandaaðgangurinn $3 var búinn til af $1 og lykilorðið var sent með tölvupósti',
 'logentry-newusers-autocreate' => 'Aðgangurinn $1 var stofnaður sjálfvirkt',
-'newuserlog-byemail' => 'lykilorð sent með tölvupósti',
-'rightsnone' => '(engin)',
+'logentry-rights-rights' => '$1 breytti réttindum $3 frá $4 í $5',
+'logentry-rights-rights-legacy' => '$1 breytti réttindum $3',
+'logentry-rights-autopromote' => '$1 fékk sjálfvirkt aukin réttindi frá $4 til $5',
+'rightsnone' => '(engum)',
 
 # Feedback
 'feedback-bugornote' => 'Ef þú ert reiðubúinn að lýsa tæknilegri villu í smáatriðum, vinsamlegast [$1 tilkynntu villu].
@@ -3758,6 +3909,7 @@ Ef ekki, þá getur þú notað einfalt eyðublað hér fyrir neðan. Athugasemd
 'api-error-ok-but-empty' => 'Innri villa: ekkert svar frá vefþjón.',
 'api-error-overwrite' => 'Óheimilt er að skrifa yfir skrá sem er þegar til.',
 'api-error-stashfailed' => 'Innri villa: Vefþjónninn gat ekki geymt tímabundna skrá.',
+'api-error-publishfailed' => 'Innri villa: Vefþjónninn gat ekki gefið út bráðabirgðaskrá.',
 'api-error-timeout' => 'Vefþjónninn svaraði ekki á tilætluðum tíma.',
 'api-error-unclassified' => 'Óþekkt villa kom upp.',
 'api-error-unknown-code' => 'Óþekkt villa: "$1"',
index 63ef592..cff4962 100644 (file)
@@ -139,6 +139,7 @@ $specialPageAliases = array(
        'Filepath'                  => array( 'Percorso' ),
        'Import'                    => array( 'Importa' ),
        'Invalidateemail'           => array( 'InvalidaEMail' ),
+       'JavaScriptTest'            => array( 'TestJavaScript' ),
        'BlockList'                 => array( 'IPBloccati', 'ElencoBlocchi', 'Blocchi' ),
        'LinkSearch'                => array( 'CercaCollegamenti', 'CercaLink' ),
        'Listadmins'                => array( 'Amministratori', 'ElencoAmministratori', 'Admin', 'Sysop', 'Cricca' ),
@@ -155,6 +156,7 @@ $specialPageAliases = array(
        'MIMEsearch'                => array( 'RicercaMIME' ),
        'Mostcategories'            => array( 'PagineConPiùCategorie' ),
        'Mostimages'                => array( 'ImmaginiPiùRichiamate' ),
+       'Mostinterwikis'            => array( 'InterwikiPiùRichiamati' ),
        'Mostlinked'                => array( 'PaginePiùRichiamate' ),
        'Mostlinkedcategories'      => array( 'CategoriePiùRichiamate' ),
        'Mostlinkedtemplates'       => array( 'TemplatePiùRichiamati' ),
@@ -249,14 +251,24 @@ $magicWords = array(
        'img_left'                  => array( '1', 'sinistra', 'left' ),
        'img_none'                  => array( '1', 'nessuno', 'none' ),
        'img_center'                => array( '1', 'centro', 'center', 'centre' ),
+       'img_framed'                => array( '1', 'riquadrato', 'incorniciato', 'originale', 'framed', 'enframed', 'frame' ),
+       'img_frameless'             => array( '1', 'senza_cornice', 'frameless' ),
        'img_page'                  => array( '1', 'pagina=$1', 'pagina_$1', 'page=$1', 'page $1' ),
+       'img_upright'               => array( '1', 'verticale', 'verticale=$1', 'verticale_$1', 'upright', 'upright=$1', 'upright $1' ),
        'img_border'                => array( '1', 'bordo', 'border' ),
+       'img_sub'                   => array( '1', 'pedice', 'sub' ),
+       'img_top'                   => array( '1', 'sopra', 'top' ),
+       'img_text_top'              => array( '1', 'testo-sopra', 'text-top' ),
+       'img_middle'                => array( '1', 'metà', 'middle' ),
+       'img_bottom'                => array( '1', 'sotto', 'bottom' ),
+       'img_text_bottom'           => array( '1', 'testo-sotto', 'text-bottom' ),
        'sitename'                  => array( '1', 'NOMESITO', 'SITENAME' ),
        'servername'                => array( '0', 'NOMESERVER', 'SERVERNAME' ),
        'gender'                    => array( '0', 'GENERE:', 'GENDER:' ),
        'currentweek'               => array( '1', 'SETTIMANACORRENTE', 'CURRENTWEEK' ),
        'localweek'                 => array( '1', 'SETTIMANALOCALE', 'LOCALWEEK' ),
        'plural'                    => array( '0', 'PLURALE:', 'PLURAL:' ),
+       'displaytitle'              => array( '1', 'MOSTRATITOLO', 'DISPLAYTITLE' ),
        'language'                  => array( '0', '#LINGUA', '#LANGUAGE:' ),
        'numberofadmins'            => array( '1', 'NUMEROADMIN', 'NUMBEROFADMINS' ),
        'special'                   => array( '0', 'speciale', 'special' ),
@@ -266,6 +278,9 @@ $magicWords = array(
        'index'                     => array( '1', '__INDICE__', '__INDEX__' ),
        'noindex'                   => array( '1', '__NOINDICE__', '__NOINDEX__' ),
        'protectionlevel'           => array( '1', 'LIVELLOPROTEZIONE', 'PROTECTIONLEVEL' ),
+       'formatdate'                => array( '0', 'formatodata', 'formatdate', 'dateformat' ),
+       'pagesincategory_pages'     => array( '0', 'pagine', 'pages' ),
+       'pagesincategory_files'     => array( '0', 'file', 'files' ),
 );
 
 $linkTrail = '/^([a-zàéèíîìóòúù]+)(.*)$/sDu';
@@ -706,7 +721,7 @@ Non dimenticare di personalizzare le [[Special:Preferences|preferenze di {{SITEN
 'gotaccount' => "Hai già un accesso? '''$1'''.",
 'gotaccountlink' => 'Entra',
 'userlogin-resetlink' => 'Hai dimenticato i tuoi dati di accesso?',
-'createaccountmail' => 'Tramite email',
+'createaccountmail' => "Usa una password casuale temporanea e inviala all'indirizzo e-mail specificato sotto",
 'createaccountreason' => 'Motivo:',
 'badretype' => 'Le password inserite non coincidono tra loro.',
 'userexists' => 'Il nome utente inserito è già utilizzato.
@@ -1285,7 +1300,7 @@ I dettagli possono essere trovati nel [{{fullurl:{{#Special:Log}}/delete|page={{
 'search-interwiki-default' => 'Risultati da $1:',
 'search-interwiki-more' => '(altro)',
 'search-relatedarticle' => 'Risultati correlati',
-'mwsuggest-disable' => 'Disattiva suggerimenti AJAX',
+'mwsuggest-disable' => 'Disattiva i suggerimenti di ricerca',
 'searcheverything-enable' => 'Cerca in tutti i namespace',
 'searchrelated' => 'correlati',
 'searchall' => 'tutti',
@@ -2175,7 +2190,7 @@ Vedi anche le [[Special:WantedCategories|categorie richieste]].',
 # Special:ActiveUsers
 '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-count' => "$1 {{PLURAL:$1|modifica|modifiche}} {{PLURAL:$3|nell'ultimo giorno|negli ultimi $3 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',
@@ -2689,7 +2704,7 @@ Ricordare di [[Special:UnlockDB|rimuovere il blocco]] dopo aver terminato le ope
 'move-page-legend' => 'Spostamento di pagina',
 'movepagetext' => "Questo modulo consente di rinominare una pagina, spostando tutta la sua cronologia al nuovo nome. La pagina attuale diverrà automaticamente un redirect al nuovo titolo. Puoi aggiornare automaticamente i redirect che puntano al titolo originale. Puoi decidere di non farlo, ma ricordati di verificare che lo spostamento non abbia creato [[Special:DoubleRedirects|doppi redirect]] o [[Special:BrokenRedirects|redirect errati]]. L'onere di garantire che i collegamenti alla pagina restino corretti spetta a chi la sposta.
 
-Si noti che la pagina '''non''' sarà spostata se ne esiste già una con il nuovo nome, a meno che non sia costituita solo da un redirect alla vecchia e sia priva di versioni precedenti. In caso di spostamento errato si può quindi tornare subito al vecchio titolo, e non è possibile sovrascrivere per errore una pagina già esistente.
+Si noti che la pagina '''non''' sarà spostata se ne esiste già una con il nuovo nome, a meno che quest'ultima non sia costituita solo da un redirect alla vecchia e sia priva di versioni precedenti. In caso di spostamento errato si può quindi tornare subito al vecchio titolo, e non è possibile sovrascrivere per errore una pagina già esistente.
 
 '''ATTENZIONE:'''
 Un cambiamento così drastico può creare contrattempi e problemi, soprattutto per le pagine più visitate. Accertarsi di aver valutato le conseguenze dello spostamento prima di procedere.",
@@ -3030,6 +3045,7 @@ Tutte le operazioni di importazione trans-wiki sono registrate nel [[Special:Log
 'pageinfo-robot-noindex' => 'Non indicizzabile',
 'pageinfo-views' => 'Numero di visualizzazioni',
 'pageinfo-watchers' => 'Numero di utenti che hanno la pagina nei loro osservati speciali',
+'pageinfo-few-watchers' => 'Meno di $1 {{PLURAL:$1|osservatore|osservatori}}',
 'pageinfo-redirects-name' => 'Redirect a questa pagina',
 'pageinfo-subpages-name' => 'Sottopagine di questa pagina',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirect}}; $3 {{PLURAL:$3|non redirect}})',
@@ -3043,8 +3059,8 @@ Tutte le operazioni di importazione trans-wiki sono registrate nel [[Special:Log
 'pageinfo-recent-authors' => 'Numero di autori diversi recenti',
 'pageinfo-magic-words' => '{{PLURAL:$1|Parola magica|Parole magiche}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoria nascosta|Categorie nascoste}} ($1)',
-'pageinfo-templates' => '{{PLURAL:$1|Template incluso}} in ($1)',
-'pageinfo-transclusions' => '{{PLURAL:$1|Pagina inclusa}} in ($1)',
+'pageinfo-templates' => 'Template {{PLURAL:$1|incluso|inclusi}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Pagina|Pagine}} in cui è incluso ($1)',
 'pageinfo-toolboxlink' => 'Informazioni sulla pagina',
 'pageinfo-redirectsto' => 'Reindirizza a',
 'pageinfo-redirectsto-info' => 'info',
@@ -3135,7 +3151,7 @@ $1',
 'seconds' => '{{PLURAL:$1|un secondo|$1 secondi}}',
 'minutes' => '{{PLURAL:$1|un minuto|$1 minuti}}',
 'hours' => "{{PLURAL:$1|un'ora|$1 ore}}",
-'days' => '{{PLURAL:$1|un giorno|$1 giorni}}',
+'days' => '{{PLURAL:$1|$1 giorno|$1 giorni}}',
 'months' => '{{PLURAL:$1|$1 mese|$1 mesi}}',
 'years' => '{{PLURAL:$1|$1 anno|$1 anni}}',
 'ago' => '$1 fa',
@@ -3663,6 +3679,9 @@ Per favore, conferma che desideri veramente ricreare questa pagina.",
 'confirm-unwatch-button' => 'OK',
 'confirm-unwatch-top' => 'Elimina questa pagina dalla tua lista degli osservati speciali?',
 
+# Separators for various lists, etc.
+'percent' => '$1&nbsp;%',
+
 # Multipage image navigation
 'imgmultipageprev' => '← pagina precedente',
 'imgmultipagenext' => 'pagina seguente →',
@@ -3807,7 +3826,7 @@ Le immagini vengono mostrate alla massima risoluzione disponibile, per gli altri
 'specialpages-group-highuse' => 'Pagine molto usate',
 'specialpages-group-pages' => 'Elenchi di pagine',
 'specialpages-group-pagetools' => 'Strumenti utili per le pagine',
-'specialpages-group-wiki' => 'Strumenti e informazioni sul progetto',
+'specialpages-group-wiki' => 'Dati e strumenti',
 'specialpages-group-redirects' => 'Pagine speciali di redirect',
 'specialpages-group-spam' => 'Strumenti contro lo spam',
 
@@ -3904,8 +3923,8 @@ Le immagini vengono mostrate alla massima risoluzione disponibile, per gli altri
 'logentry-newusers-newusers' => "L'utenza $1 è stata creata",
 'logentry-newusers-create' => "L'utenza $1 è stata creata",
 'logentry-newusers-create2' => "L'utenza $3 è stata creata da $1",
+'logentry-newusers-byemail' => "L'utente $3 è stato creato da $1 e la password è stata inviata via e-mail",
 'logentry-newusers-autocreate' => "L'utenza $1 è stata creata automaticamente",
-'newuserlog-byemail' => 'password inviata via mail',
 'logentry-rights-rights' => "$1 ha modificato l'appartenenza di $3 dal gruppo $4 al gruppo $5",
 'logentry-rights-rights-legacy' => "$1 ha modificato l'appartenenza a gruppi di $3",
 'logentry-rights-autopromote' => '$1 è stato/a automaticamente promosso/a da $4 a $5',
@@ -3962,6 +3981,7 @@ Le immagini vengono mostrate alla massima risoluzione disponibile, per gli altri
 'api-error-ok-but-empty' => 'Errore interno: nessuna risposta dal server.',
 'api-error-overwrite' => 'Sovrascrivere un file esistente non è consentito.',
 'api-error-stashfailed' => 'Errore interno: il server non è riuscito a memorizzare il documento temporaneo.',
+'api-error-publishfailed' => 'Errore interno: il server non è riuscito a pubblicare il documento temporaneo.',
 'api-error-timeout' => 'Il server non ha risposto entro il tempo previsto.',
 'api-error-unclassified' => 'Si è verificato un errore sconosciuto.',
 'api-error-unknown-code' => 'Errore sconosciuto: "$1"',
index 41b4dac..0c5a42d 100644 (file)
@@ -533,7 +533,7 @@ $messages = array(
 'navigation-heading' => '案内メニュー',
 'errorpagetitle' => 'エラー',
 'returnto' => '$1 に戻る。',
-'tagline' => '提供{{SITENAME}}',
+'tagline' => '提供{{SITENAME}}',
 'help' => 'ヘルプ',
 'search' => '検索',
 'searchbutton' => '検索',
@@ -578,7 +578,7 @@ $messages = array(
 'categorypage' => 'カテゴリのページを表示',
 'viewtalkpage' => '議論を表示',
 'otherlanguages' => '他言語版',
-'redirectedfrom' => '($1から転送)',
+'redirectedfrom' => '($1から転送)',
 'redirectpagesub' => '転送ページ',
 'lastmodifiedat' => 'このページの最終更新日時は $1 $2 です。',
 'viewcount' => 'このページは {{PLURAL:$1|$1 回}}アクセスされました。',
@@ -627,11 +627,11 @@ $1',
 'retrievedfrom' => '「$1」から取得',
 'youhavenewmessages' => '$1があります ($2)。',
 'newmessageslink' => '新着メッセージ',
-'newmessagesdifflink' => '最終更新の差分',
+'newmessagesdifflink' => '最新の差分',
 'youhavenewmessagesfromusers' => '{{PLURAL:$3|他の利用者|$3 人の利用者}}からの$1があります ($2)。',
 'youhavenewmessagesmanyusers' => '多数の利用者からの$1があります ($2)。',
 'newmessageslinkplural' => '{{PLURAL:$1|新着メッセージ}}',
-'newmessagesdifflinkplural' => '最終更新の{{PLURAL:$1|差分}}',
+'newmessagesdifflinkplural' => '{{PLURAL:$1|最新の差分|最新版までの差分}}',
 'youhavenewmessagesmulti' => '$1に新着メッセージがあります',
 'editsection' => '編集',
 'editold' => '編集',
@@ -644,10 +644,10 @@ $1',
 'hidetoc' => '非表示',
 'collapsible-collapse' => '折り畳む',
 'collapsible-expand' => '展開する',
-'thisisdeleted' => '$1を閲覧または復元しますか',
-'viewdeleted' => '$1を閲覧しますか',
+'thisisdeleted' => '$1を閲覧または復元しますか?',
+'viewdeleted' => '$1を閲覧しますか?',
 'restorelink' => '{{PLURAL:$1|削除された$1編集}}',
-'feedlinks' => 'フィード',
+'feedlinks' => 'フィード:',
 'feed-invalid' => 'フィード形式の指定が正しくありません。',
 'feed-unavailable' => 'フィードの配信は利用できません',
 'site-rss-feed' => '$1のRSSフィード',
@@ -656,7 +656,7 @@ $1',
 'page-atom-feed' => '「$1」のAtomフィード',
 'feed-atom' => 'Atom',
 'feed-rss' => 'RSS',
-'red-link-title' => '$1(存在しないページ)',
+'red-link-title' => '$1 (存在しないページ)',
 'sort-descending' => '降順に並べ替え',
 'sort-ascending' => '昇順に並べ替え',
 
@@ -689,19 +689,19 @@ URL を間違って入力したか、正しくないリンクをたどった可
 ソフトウェアにバグがある可能性があります。
 最後に実行を試みたクエリ:
 <blockquote><code>$1</code></blockquote>
-(関数「<code>$2</code>」内)
-データベースはエラー「<samp>$3$4</samp>」を返しました。',
+(関数「<code>$2</code>」内)
+データベースはエラー「<samp>$3$4</samp>」を返しました。',
 'dberrortextcl' => 'データベース クエリの構文エラーが発生しました。
 最後に実行を試みたクエリ:
 「$1」
-(関数「$2」内)
-データベースはエラー「$3$4」を返しました',
+(関数「$2」内)
+データベースはエラー「$3$4」を返しました',
 'laggedslavemode' => "'''警告:''' ページに最新の編集が反映されていない可能性があります。",
 'readonly' => 'データベースがロックされています',
 'enterlockreason' => 'ロックの理由とロック解除の予定を入力してください',
 'readonlytext' => 'データベースは現在、新しいページの追加や編集を受け付けない「ロック状態」になっています。これはおそらくデータベースの定期メンテナンスのためで、メンテナンス終了後は正常な状態に復帰します。
 
-データベースをロックした管理者による説明は以下の通りです$1',
+データベースをロックした管理者による説明は以下の通りです$1',
 'missing-article' => '指定されたページ「$1」$2 の本文がデータベース内で見つかりませんでした。
 
 通常、削除されたページの版への古い差分表示や固定リンクをたどった際に、このようなことが起きます。
@@ -712,7 +712,7 @@ URL を間違って入力したか、正しくないリンクをたどった可
 'missingarticle-diff' => '(差分: $1, $2)',
 'readonly_lag' => 'データベースはスレーブのデータベースサーバーがマスターに同期するまで自動的にロックされています',
 'internalerror' => '内部エラー',
-'internalerror_info' => '内部エラー$1',
+'internalerror_info' => '内部エラー$1',
 'fileappenderrorread' => '追加中に、「$1」を読み取れませんでした。',
 'fileappenderror' => '「$1」を「$2」に追加できませんでした。',
 'filecopyerror' => 'ファイル「$1」を「$2」に複製できませんでした。',
@@ -720,9 +720,9 @@ URL を間違って入力したか、正しくないリンクをたどった可
 'filedeleteerror' => 'ファイル「$1」を削除できませんでした。',
 'directorycreateerror' => 'ディレクトリ「$1」を作成できませんでした。',
 'filenotfound' => 'ファイル「$1」が見つかりませんでした。',
-'fileexistserror' => 'ã\83\95ã\82¡ã\82¤ã\83«ã\80\8c$1ã\80\8dã\81¸ã\81®æ\9b¸ã\81\8dè¾¼ã\81¿ã\81«å¤±æ\95\97ï¼\9aファイルが存在します。',
+'fileexistserror' => 'ã\83\95ã\82¡ã\82¤ã\83«ã\80\8c$1ã\80\8dã\81«æ\9b¸ã\81\8dè¾¼ã\82\81ã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9fファイルが存在します。',
 'unexpected' => '予期しない値「$1」=「$2」です。',
-'formerror' => 'エラーフォームを送信できませんでした。',
+'formerror' => 'エラーフォームを送信できませんでした。',
 'badarticleerror' => 'このページでは要求された操作を行えません。',
 'cannotdelete' => 'ページまたはファイル「$1」を削除できませんでした。
 他の人が既に削除した可能性があります。',
@@ -745,8 +745,8 @@ URL を間違って入力したか、正しくないリンクをたどった可
 'actionthrottledtext' => '短時間にこの操作を大量に行ったため、スパム対策として設定されている制限を超えました。
 少し時間をおいてからもう一度操作してください。',
 'protectedpagetext' => 'このページは編集や他の操作ができないように保護されています。',
-'viewsourcetext' => 'このページのソースの閲覧やコピーができます',
-'viewyourtext' => "このページへの'''あなたの編集'''のソースの閲覧やコピーができます",
+'viewsourcetext' => 'このページのソースの閲覧やコピーができます:',
+'viewyourtext' => "このページへの'''あなたの編集'''のソースの閲覧やコピーができます:",
 'protectedinterface' => 'このページにはこのウィキのソフトウェアのインターフェイスに使用されるテキストが保存されており、いたずらなどの防止のために保護されています。
 すべてのウィキに対して翻訳を追加/変更する場合は、MediaWiki の地域化プロジェクト [//translatewiki.net/ translatewiki.net] を使用してください。',
 'editinginterface' => "'''警告:''' ソフトウェアのインターフェイスに使用されるテキストのページを編集しています。
@@ -770,9 +770,9 @@ $2',
 'exception-nologin-text' => 'このページまたは操作には、このウィキへのログインが必要です。',
 
 # Virus scanner
-'virus-badscanner' => "環境設定が不適合です:不明なウイルス検知ソフトウェア:''$1''",
-'virus-scanfailed' => 'スキャンに失敗しました(コード $1)',
-'virus-unknownscanner' => '不明なウイルス対策',
+'virus-badscanner' => "環境設定が不適合です: 不明なウイルス対策ソフトウェア: ''$1''",
+'virus-scanfailed' => 'スキャンに失敗しました (コード $1)',
+'virus-unknownscanner' => '不明なウイルス対策ソフトウェア:',
 
 # Login and logout pages
 'logouttext' => "'''ログアウトしました。'''
@@ -803,9 +803,9 @@ $2',
 'createaccount' => 'アカウント作成',
 'gotaccount' => 'アカウントを既に持っている場合、$1。',
 'gotaccountlink' => 'ログインしてください',
-'userlogin-resetlink' => 'ログイン情報をお忘れですか',
-'createaccountmail' => 'メールで送信',
-'createaccountreason' => '理由',
+'userlogin-resetlink' => 'ログイン情報をお忘れですか?',
+'createaccountmail' => '一時的でランダムなパスワードを生成して、以下に指定したメールアドレスに送信する',
+'createaccountreason' => '理由:',
 'badretype' => '入力したパスワードが一致しません。',
 'userexists' => '入力された利用者名は既に使用されています。
 他の名前を選んでください。',
@@ -840,10 +840,10 @@ Cookieを有効にしていることを確認して、このページを再読
 'password-login-forbidden' => 'この利用者名とパスワードの使用は禁止されています。',
 'mailmypassword' => '新しいパスワードをメールで送信',
 'passwordremindertitle' => '{{SITENAME}}の仮パスワード通知',
-'passwordremindertext' => '誰か(おそらくあなた)がIPアドレス$1から{{SITENAME}} ($4) のログイン用パスワードの再発行を申請しました。
+'passwordremindertext' => '誰か (おそらくあなた) が IP アドレス $1 から{{SITENAME}} ($4) のログイン用パスワードの再発行を申請しました。
 利用者「$2」の仮パスワードが作成され「$3」に設定されました。
 もしあなたがこの申請をしたのであれば、ログインして新しいパスワードを決めてください。
-この仮パスワードは {{PLURAL:$5|$5 日間}}で有効期限が切れます。
+この仮パスワードは {{PLURAL:$5|$5 日|$5 日間}}で有効期限が切れます。
 
 この申請をしたのが他人の場合、あるいはパスワードを思い出してパスワード変更が不要になった場合は、
 このメッセージを無視して、引き続き以前のパスワードを使用し続けることができます。',
@@ -856,7 +856,7 @@ Cookieを有効にしていることを確認して、このページを再読
 メールに記載された手順に従って、このアカウントの所有者であることの確認が取れると、このアカウント宛のメールを受け取れるようになります。',
 'throttled-mailpassword' => '新しいパスワードは過去 {{PLURAL:$1|$1 時間}}に送信済みです。
 悪用防止のため、パスワードの再発行は {{PLURAL:$1|$1 時間}}に 1 回のみです。',
-'mailerror' => 'ã\83¡ã\83¼ã\83«ã\81®é\80\81信中ã\81«ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¾ã\81\97ã\81\9fï¼\9a$1',
+'mailerror' => 'ã\83¡ã\83¼ã\83«ã\82\92é\80\81ä¿¡ã\81\99ã\82\8bé\9a\9bã\81«ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¾ã\81\97ã\81\9f$1',
 'acct_creation_throttle_hit' => 'あなたと同じ IP アドレスでこのウィキに訪れた人が、最近 24 時間で {{PLURAL:$1|$1 アカウント}}を作成しており、これはこの期間で作成が許可されている最大数です。
 そのため、現在この IP アドレスではアカウントをこれ以上作成できません。',
 'emailauthenticated' => 'メールアドレスは$2 $3に認証済みです。',
@@ -871,7 +871,7 @@ Cookieを有効にしていることを確認して、このページを再読
 'accountcreated' => 'アカウントを作成しました',
 'accountcreatedtext' => '利用者アカウント「$1」を作成しました。',
 'createaccount-title' => '{{SITENAME}}のアカウント作成',
-'createaccount-text' => '誰か(おそらくあなた)が、{{SITENAME}} ($4) にあなたのメールアドレスのアカウントを作成しました。
+'createaccount-text' => '誰か (おそらくあなた) が、{{SITENAME}} ($4) にあなたのメールアドレスのアカウントを作成しました。
 アカウント名「$2」、パスワード「$3」です。
 今すぐログインしてパスワードを変更してください。
 
@@ -891,7 +891,7 @@ Cookieを有効にしていることを確認して、このページを再読
 # Change password dialog
 'resetpass' => 'パスワードの変更',
 'resetpass_announce' => 'メールでお送りした仮パスワードでログインしました。
-ログインを完了するには、ここで新しいパスワードを設定する必要があります',
+ログインを完了するには、ここで新しいパスワードを設定する必要があります:',
 'resetpass_text' => '<!-- ここに文を挿入 -->',
 'resetpass_header' => 'アカウントのパスワードの変更',
 'oldpassword' => '古いパスワード:',
@@ -916,17 +916,17 @@ Cookieを有効にしていることを確認して、このページを再読
 'passwordreset-pretext' => '{{PLURAL:$1||下記のデータのいずれか 1 つを入力してください}}',
 'passwordreset-username' => '利用者名:',
 'passwordreset-domain' => 'ドメイン:',
-'passwordreset-capture' => '送信されるメールの内容を表示しますか?',
-'passwordreset-capture-help' => 'このボックスにチェックを入れると、利用者に送信されるメールの内容(仮パスワードを含む)をあなたも閲覧できます。',
+'passwordreset-capture' => 'お送りするメールの内容を表示しますか?',
+'passwordreset-capture-help' => 'このボックスにチェックを入れると、利用者に送信されるメールの内容 (仮パスワードを含む) をあなたも閲覧できます。',
 'passwordreset-email' => 'メールアドレス:',
 'passwordreset-emailtitle' => '{{SITENAME}}上のアカウントの詳細',
-'passwordreset-emailtext-ip' => 'どなたか(おそらくあなた、IP アドレス $1)が {{SITENAME}} ($4) での
+'passwordreset-emailtext-ip' => '誰か (おそらくあなた、IP アドレス $1) が {{SITENAME}} ($4) での
 あなたのアカウントの詳細情報を送信するよう申請しました。
 以下の利用者{{PLURAL:$3|アカウント|アカウント群}}がこのメールアドレスと紐付けられています。
 
 $2
 
-{{PLURAL:$3|この仮パスワード|これらの仮パスワード}}は {{PLURAL:$5|$5 日間}}で有効期限が切れます。
+{{PLURAL:$3|この仮パスワード|これらの仮パスワード}}は {{PLURAL:$5|$5 日|$5 日間}}で有効期限が切れます。
 あなたはすぐにログインして新しいパスワードを設定する必要があります。
 これが他の誰かによる申請である場合、あるいはあなたが自分の元のパスワードを
 覚えていてそれを変更したくない場合には、このメッセージを無視して以前のパスワードを
@@ -942,8 +942,8 @@ $2
 この申請が他の誰かによるものの場合、あるいはあなたが自分の元のパスワードを
 覚えていて、変更したくない場合は、このメッセージを無視して
 以前のパスワードを使い続けることができます。',
-'passwordreset-emailelement' => '利用者名$1
-仮パスワード$2',
+'passwordreset-emailelement' => '利用者名$1
+仮パスワード$2',
 'passwordreset-emailsent' => '確認メールをお送りしました。',
 'passwordreset-emailsent-capture' => '下記の内容の、確認メールをお送りしました。',
 'passwordreset-emailerror-capture' => '以下の内容の確認メールを生成しましたが、利用者への送信に失敗しました: $1',
@@ -968,7 +968,7 @@ $2
 'link_sample' => 'リンクの名前',
 'link_tip' => '内部リンク',
 'extlink_sample' => 'http://www.example.com リンクの名前',
-'extlink_tip' => '外部リンク(http:// を忘れずに付けてください)',
+'extlink_tip' => '外部リンク (http:// を忘れずに付けてください)',
 'headline_sample' => '見出し文',
 'headline_tip' => '2段目の見出し',
 'nowiki_sample' => 'ここにマークアップを無効にするテキストを入力します',
@@ -978,7 +978,7 @@ $2
 'media_sample' => 'サンプル.ogg',
 'media_tip' => 'ファイルへのリンク',
 'sig_tip' => '時刻印付きの署名',
-'hr_tip' => '水平線を挿入(利用は控えめに)',
+'hr_tip' => '水平線を挿入 (利用は控えめに)',
 
 # Edit pages
 'summary' => '編集内容の要約:',
@@ -998,17 +998,17 @@ $2
 'missingcommenttext' => '以下にコメントを入力してください。',
 'missingcommentheader' => "'''注意:''' このコメントに対する題名/見出しが空欄です。
 「{{int:savearticle}}」ボタンをもう一度押すと、空のまま編集が保存されます。",
-'summary-preview' => '要約のプレビュー',
-'subject-preview' => '題名/見出しのプレビュー',
+'summary-preview' => '要約のプレビュー:',
+'subject-preview' => '題名/見出しのプレビュー:',
 'blockedtitle' => '利用者はブロックされています',
 'blockedtext' => "'''この利用者名またはIPアドレスはブロックされています。'''
 
 ブロックは$1によって実施されました。
 ブロックの理由は ''$2'' です。
 
-* ã\83\96ã\83­ã\83\83ã\82¯é\96\8bå§\8bæ\99\82æ\9c\9fï¼\9a$8
-* ブロック解除予定$6
-* ブロック対象$7
+* ã\83\96ã\83­ã\83\83ã\82¯é\96\8bå§\8bæ\97¥æ\99\82$8
+* ブロック解除予定$6
+* ブロック対象$7
 
 このブロックについて、$1もしくは他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]に問い合わせることができます。
 ただし、[[Special:Preferences|個人設定]]で有効なメールアドレスが登録されていない場合、またはメール送信機能の使用がブロックされている場合、「この利用者にメールを送信」の機能は使えません。
@@ -1019,9 +1019,9 @@ $2
 
 :''$2''
 
-* ブロックの開始:$8
-* ブロック解除予定$6
-* 意図されているブロック対象者:$7
+* ブロック開始日時: $8
+* ブロック解除予定$6
+* ブロック対象: $7
 
 $1または他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]にこのブロックについて問い合わせることができます。
 
@@ -1106,7 +1106,7 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'creating' => '「$1」を作成中',
 'editingsection' => '「$1」を編集中 (節単位)',
 'editingcomment' => '「$1」を編集中 (新しい節)',
-'editconflict' => '編集競合$1',
+'editconflict' => '編集競合$1',
 'explainconflict' => "このページを編集し始めた後に、他の誰かがこのページを変更しました。
 上側のテキスト領域は現在の最新の状態です。
 編集していた文章は下側のテキスト領域に示されています。
@@ -1114,23 +1114,23 @@ IP アドレスは複数の利用者で共有されている場合がありま
 上側のテキスト領域の内容'''だけ'''が、「{{int:savearticle}}」をクリックした時に実際に保存されます。",
 'yourtext' => '編集中の文章',
 'storedversion' => '保存された版',
-'nonunicodebrowser' => "'''警告:ご使用中のブラウザーはUnicodeに未対応です。'''
-安全にページを編集する回避策を表示しています:編集ボックス内の非ASCII文字を16進数コードで表現しています。",
-'editingold' => "'''警告このページの古い版を編集しています。'''
-保存すると、この版以降に追加されていた変更がすべて失われます。",
+'nonunicodebrowser' => "'''警告: ご使用中のブラウザーは Unicode に未対応です。'''
+安全にページを編集する回避策を表示しています: 編集ボックス内の非 ASCII 文字を 16 進数コードで表現しています。",
+'editingold' => "'''警告このページの古い版を編集しています。'''
+保存すると、この版以降になされた変更がすべて失われます。",
 'yourdiff' => '差分',
 'copyrightwarning' => "{{SITENAME}}への投稿は、すべて$2 (詳細は$1を参照) のもとで公開したと見なされることにご注意ください。
 あなたが投稿したものを、他人がよって遠慮なく編集し、それを自由に配布するのを望まない場合は、ここには投稿しないでください。<br />
 また、投稿するのは、あなたが書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください。
 '''著作権保護されている作品を、許諾なしに投稿しないでください!'''",
-'copyrightwarning2' => "{{SITENAME}}ã\81¸ã\81®ã\81\99ã\81¹ã\81¦ã\81®æ\8a\95稿ã\81¯ã\80\81ä»\96ã\81®å\88©ç\94¨è\80\85ã\81\8cç·¨é\9b\86ã\80\81å¤\89æ\9b´ã\80\81é\99¤å\8e»ã\81\99ã\82\8bå\8f¯è\83½æ\80§があります。
+'copyrightwarning2' => "{{SITENAME}}ã\81¸ã\81®ã\81\99ã\81¹ã\81¦ã\81®æ\8a\95稿ã\81¯ã\80\81ä»\96ã\81®å\88©ç\94¨è\80\85ã\81«ã\82\88ã\81£ã\81¦ç·¨é\9b\86ã\80\81å¤\89æ\9b´ã\80\81é\99¤å\8e»ã\81\95ã\82\8cã\82\8bå ´å\90\88があります。
 あなたの投稿を、他人が遠慮なく編集するのを望まない場合は、ここには投稿しないでください。<br />
-また、投稿するのは、あなたが書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は$1を参照)
+また、投稿するのは、あなたが書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください (詳細は$1を参照)
 '''著作権保護されている作品を、許諾なしに投稿してはいけません!'''",
 'longpageerror' => "'''エラー: 投稿された文章は {{PLURAL:$1|$1 KB}} の長さがあります。これは投稿できる最大の長さ {{PLURAL:$2|$2 KB}} を超えています。'''
 この編集内容は保存できません。",
 'readonlywarning' => "'''警告: データベースがメンテナンスのためロックされており、現在は編集内容を保存できません。'''
-å¿\85è¦\81ã\81§ã\81\82ã\82\8cã\81°æ\96\87ç« ã\82\92ã\82«ã\83\83ã\83\88&amp;ペーストしてテキストファイルとして保存し、後ほど保存をやり直してください。
+å¿\85è¦\81ã\81§ã\81\82ã\82\8cã\81°æ\96\87ç« ã\82\92ã\82³ã\83\94ã\83¼&amp;ペーストしてテキストファイルとして保存し、後ほど保存をやり直してください。
 
 データベースをロックした管理者による説明は以下の通りです: $1",
 'protectedpagewarning' => "'''警告: このページは保護されているため、管理者権限を持つ利用者のみが編集できます。'''
@@ -1140,12 +1140,12 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'cascadeprotectedwarning' => "'''警告:''' このページはカスケード保護されている以下の{{PLURAL:$1|ページ|ページ群}}から読み込まれているため、管理者権限を持つ利用者のみが編集できるように保護されています:",
 'titleprotectedwarning' => "'''警告: このページは保護されているため、作成には[[Special:ListGroupRights|特定の権限]]が必要です。'''
 参考として以下に最後の記録を表示します:",
-'templatesused' => 'このページで使用されている{{PLURAL:$1|テンプレート}}',
-'templatesusedpreview' => 'このプレビューで使用されている{{PLURAL:$1|テンプレート}}',
-'templatesusedsection' => 'この節で使用されている{{PLURAL:$1|テンプレート}}',
-'template-protected' => '(保護)',
+'templatesused' => 'このページで使用されている{{PLURAL:$1|テンプレート}}:',
+'templatesusedpreview' => 'このプレビューで使用されている{{PLURAL:$1|テンプレート}}:',
+'templatesusedsection' => 'この節で使用されている{{PLURAL:$1|テンプレート}}:',
+'template-protected' => '(保護)',
 'template-semiprotected' => '(半保護)',
-'hiddencategories' => 'このページは {{PLURAL:$1|$1 個の隠しカテゴリ}}に属しています',
+'hiddencategories' => 'このページは {{PLURAL:$1|$1 個の隠しカテゴリ}}に属しています:',
 'edittools' => '<!-- ここに書いたテキストは編集及びアップロードのフォームの下に表示されます。 -->',
 'nocreatetext' => '{{SITENAME}}ではページの新規作成を制限しています。
 元のページに戻って既存のページを編集するか、[[Special:UserLogin|ログインまたはアカウント作成]]をしてください。',
@@ -1153,12 +1153,12 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'sectioneditnotsupported-title' => '節単位編集はサポートされていません',
 'sectioneditnotsupported-text' => 'このページでは節単位編集はサポートされません。',
 'permissionserrors' => '認証エラー',
-'permissionserrorstext' => 'あなたにはこの操作を行う権限はありません。{{PLURAL:$1|理由}}は以下の通りです',
+'permissionserrorstext' => 'あなたにはこの操作を行う権限はありません。{{PLURAL:$1|理由}}は以下の通りです:',
 'permissionserrorstext-withaction' => 'あなたには「$2」を行う権限はありません。{{PLURAL:$1|理由}}は以下の通りです:',
-'recreate-moveddeleted-warn' => "'''警告以前削除されたページを再作成しようとしています。'''
+'recreate-moveddeleted-warn' => "'''警告以前削除されたページを再作成しようとしています。'''
 
 このページの編集を続行するのが適切かどうかご確認ください。
-参考までに、このページの削除と移動の記録を以下に示します",
+参考までに、このページの削除と移動の記録を以下に示します:",
 'moveddeleted-notice' => 'このページは削除されています。
 参考のため、このページの削除と移動の記録を以下に表示します。',
 'log-fulllog' => '完全な記録を閲覧',
@@ -1192,15 +1192,15 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'post-expand-template-argument-warning' => "'''警告:''' このページは、展開後のサイズが大きすぎるテンプレート引数を少なくとも 1 つ含んでいます。
 これらの引数を省略しました。",
 'post-expand-template-argument-category' => '省略されたテンプレート引数を含むページ',
-'parser-template-loop-warning' => 'ã\83\86ã\83³ã\83\97ã\83¬ã\83¼ã\83\88ã\81®ã\83«ã\83¼ã\83\97ã\81\8cæ¤\9cå\87ºã\81\95ã\82\8cã\81¾ã\81\97ã\81\9fï¼\9a[[$1]]',
-'parser-template-recursion-depth-warning' => 'テンプレートの再帰の深さ($1)が上限を超えました',
-'language-converter-depth-warning' => '言語変換機能の深さ($1)が制限を超えました',
+'parser-template-loop-warning' => 'ã\83\86ã\83³ã\83\97ã\83¬ã\83¼ã\83\88ã\81®ã\83«ã\83¼ã\83\97ã\82\92æ¤\9cå\87ºã\81\97ã\81¾ã\81\97ã\81\9f[[$1]]',
+'parser-template-recursion-depth-warning' => 'テンプレートの再帰の深さ ($1) が上限を超えました',
+'language-converter-depth-warning' => '言語変換機能の深さ ($1) が制限を超えました',
 'node-count-exceeded-category' => 'ノード数が制限を超えたページ',
 'node-count-exceeded-warning' => 'ページがノード数の制限を超えました',
 'expansion-depth-exceeded-category' => '展開の深さ制限を超えたページ',
 'expansion-depth-exceeded-warning' => 'ページが展開の深さ制限を超えました',
-'parser-unstrip-loop-warning' => 'Unstrip のループが検出されました',
-'parser-unstrip-recursion-limit' => 'Unstrip の再帰($1)が上限を超えました',
+'parser-unstrip-loop-warning' => 'unstrip のループを検出しました',
+'parser-unstrip-recursion-limit' => 'unstrip の再帰 ($1) が上限を超えました',
 'converter-manual-rule-error' => '手動の言語変換規則でエラーを検出しました。',
 
 # "Undo" feature
@@ -1214,7 +1214,7 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'cantcreateaccounttitle' => 'アカウントを作成できません',
 'cantcreateaccount-text' => "このIPアドレス('''$1''')からのアカウント作成は[[User:$3|$3]]によってブロックされています。
 
-$3が示した理由''$2''",
+$3が示した理由''$2''",
 
 # History pages
 'viewpagelogs' => 'このページの記録を閲覧',
@@ -1354,9 +1354,9 @@ $1",
 'mergehistory' => 'ページの履歴の統合',
 'mergehistory-header' => 'このページでは、ある元ページの履歴を新しいページに統合できます。
 この変更を行ってもページの履歴の連続性が確実に保たれるようにしてください。',
-'mergehistory-box' => '2ページの過去の版を統合する',
-'mergehistory-from' => '統合元となるページ',
-'mergehistory-into' => '統合先のページ',
+'mergehistory-box' => '2ページの過去の版を統合する:',
+'mergehistory-from' => '統合元となるページ:',
+'mergehistory-into' => '統合先のページ:',
 'mergehistory-list' => '統合できる編集履歴',
 'mergehistory-merge' => '以下の [[:$1]] の履歴を [[:$2]] に統合できます。
 特定の日時以前に作成された版のみを統合するには、ラジオボタンで版を選択してください。
@@ -1371,22 +1371,22 @@ $1",
 'mergehistory-invalid-source' => '統合元のページは有効な名前でなければなりません。',
 'mergehistory-invalid-destination' => '統合先のページは有効な名前でなければなりません。',
 'mergehistory-autocomment' => '[[:$1]]を[[:$2]]に統合',
-'mergehistory-comment' => '[[:$1]]を[[:$2]]に統合$3',
+'mergehistory-comment' => '[[:$1]]を[[:$2]]に統合$3',
 'mergehistory-same-destination' => '統合元と統合先のページを同じにはできません',
-'mergehistory-reason' => '理由',
+'mergehistory-reason' => '理由:',
 
 # Merge log
 'mergelog' => '統合記録',
-'pagemerge-logentry' => '[[$1]]を[[$2]]に統合($3 版まで)',
+'pagemerge-logentry' => '[[$1]]を[[$2]]に統合 ($3 版まで)',
 'revertmerge' => '統合解除',
 'mergelogpagetext' => '以下は、最近行われたあるページから別のページへの統合の一覧です。',
 
 # Diffs
 'history-title' => '「$1」の変更履歴',
-'difference-title' => '$1:版間の差分',
-'difference-title-multipage' => '$1 と $2:ページ間の差分',
+'difference-title' => '「$1」の版間の差分',
+'difference-title-multipage' => 'ページ「$1」と「$2」の間の差分',
 'difference-multipage' => '(ページ間の差分)',
-'lineno' => '$1行',
+'lineno' => '$1行:',
 'compareselectedversions' => '選択した版同士を比較',
 'showhideselectedversions' => '選択した版を表示/非表示',
 'editundo' => '取り消し',
@@ -1401,7 +1401,7 @@ $1",
 'searchresults' => '検索結果',
 'searchresults-title' => '「$1」の検索結果',
 'searchresulttext' => '{{SITENAME}}の検索に関する詳しい情報は、[[{{MediaWiki:Helppage}}|{{int:help}}]]をご覧ください。',
-'searchsubtitle' => "'''[[:$1]]'''の検索([[Special:Prefixindex/$1|「$1」から始まるページ]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|「$1」へリンクしている全ページ]])",
+'searchsubtitle' => "'''[[:$1]]'''の検索 ([[Special:Prefixindex/$1|「$1」から始まるページ]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|「$1」へリンクしている全ページ]])",
 'searchsubtitleinvalid' => "'''$1'''を検索しました",
 'toomanymatches' => '一致したページが多すぎます。他の検索語を指定してください。',
 'titlematches' => 'ページ名と一致',
@@ -1439,7 +1439,7 @@ $1",
 'search-interwiki-default' => '$1の結果:',
 'search-interwiki-more' => '(続き)',
 'search-relatedarticle' => '関連',
-'mwsuggest-disable' => 'Ajaxによる検索候補の提示を無効にする',
+'mwsuggest-disable' => '検索候補の提示を無効にする',
 'searcheverything-enable' => 'すべての名前空間を検索',
 'searchrelated' => '関連',
 'searchall' => 'すべて',
@@ -1447,7 +1447,7 @@ $1",
 'showingresultsnum' => "'''$2''' 件目以降の {{PLURAL:$3|'''$3''' 件の結果}}を表示しています。",
 'showingresultsheader' => "「'''$4'''」の検索結果 {{PLURAL:$5|'''$3''' 件中の '''$1''' 件目|'''$3''' 件中の '''$1''' 件目から '''$2''' 件目}}",
 'nonefound' => "'''注意''': 既定では一部の名前空間のみを検索します。
-''all:''を前に付けると、すべて(トークページやテンプレートなどを含む)を対象にできます。検索する名前空間を前に付けることもできます。",
+''all:''を前に付けると、すべて (トークページやテンプレートなどを含む) を対象にできます。検索する名前空間を前に付けることもできます。",
 'search-nonefound' => '問い合わせに合致する検索結果はありませんでした。',
 'powersearch' => '高度な検索',
 'powersearch-legend' => '高度な検索',
@@ -1521,7 +1521,7 @@ $1",
 'timezonelegend' => 'タイムゾーン:',
 'localtime' => 'ローカルの時刻:',
 'timezoneuseserverdefault' => 'ウィキの既定を使用 ($1)',
-'timezoneuseoffset' => 'その他(時差を指定)',
+'timezoneuseoffset' => 'その他 (時差を指定)',
 'timezoneoffset' => '時差¹:',
 'servertime' => 'サーバーの時刻:',
 'guesstimezone' => 'ブラウザーの設定から入力',
@@ -1611,7 +1611,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'userrights-groups-help' => 'この利用者が属するグループを変更できます。
 * チェックが入っているボックスは、この利用者がそのグループに属していることを意味します。
 * チェックが入っていないボックスは、この利用者がそのグループに属していないことを意味します。
-* 「*」はグループに一旦追加した場合に除去(あるいはその逆)ができないことを示しています。',
+* 「*」はグループに一旦追加した場合に除去 (あるいはその逆) ができないことを示しています。',
 'userrights-reason' => '理由:',
 'userrights-no-interwiki' => '他ウィキ上における利用者権限の編集権限はありません。',
 'userrights-nodatabase' => 'データベース$1は存在しないか、ローカル上にありません。',
@@ -1648,7 +1648,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 # Rights
 'right-read' => 'ページを閲覧',
 'right-edit' => 'ページを編集',
-'right-createpage' => 'ページ(議論ページ以外)を作成',
+'right-createpage' => 'ページ (議論ページ以外) を作成',
 'right-createtalk' => '議論ページを作成',
 'right-createaccount' => '新しい利用者アカウントを作成',
 'right-minoredit' => '細部の編集の印を付ける',
@@ -1672,7 +1672,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'right-bigdelete' => '大きな履歴があるページを削除',
 'right-deletelogentry' => '特定の記録項目を削除/復元',
 'right-deleterevision' => 'ページの特定の版を削除/復元',
-'right-deletedhistory' => '削除された履歴項目(関連する本文を除く)を閲覧',
+'right-deletedhistory' => '削除された履歴項目 (関連する本文を除く) を閲覧',
 'right-deletedtext' => '削除された本文と削除された版間の差分を閲覧',
 'right-browsearchive' => '削除されたページを検索',
 'right-undelete' => 'ページを復元',
@@ -1685,7 +1685,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'right-proxyunbannable' => 'プロキシの自動ブロックを回避',
 'right-unblockself' => '自身に対するブロックを解除',
 'right-protect' => '保護レベルを変更し、保護されたページを編集',
-'right-editprotected' => '保護ページ(カスケード保護を除く)を編集',
+'right-editprotected' => '保護ページ (カスケード保護を除く) を編集',
 'right-editinterface' => 'ユーザーインターフェイスを編集',
 'right-editusercssjs' => '他の利用者のCSSファイル/JavaScriptファイルを編集',
 'right-editusercss' => '他の利用者のCSSファイルを編集',
@@ -1781,12 +1781,12 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'boteditletter' => 'ボ',
 'unpatrolledletter' => '!',
 'number_of_watching_users_pageview' => '[{{PLURAL:$1|$1 人の利用者}}がウォッチしています]',
-'rc_categories' => 'カテゴリを限定(「|」で区切る)',
+'rc_categories' => 'カテゴリを限定 (「|」で区切る)',
 'rc_categories_any' => 'すべて',
 'rc-change-size' => '$1',
 'rc-change-size-new' => '変更後は $1 {{PLURAL:$1|バイト}}',
 'newsectionsummary' => '/* $1 */ 新しい節',
-'rc-enhanced-expand' => '詳細を表示(JavaScript が必要)',
+'rc-enhanced-expand' => '詳細を表示 (JavaScript が必要)',
 'rc-enhanced-hide' => '詳細を非表示',
 'rc-old-title' => '作成時のページ名は「$1」',
 
@@ -1796,10 +1796,10 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'recentchangeslinked-toolbox' => '関連ページの更新状況',
 'recentchangeslinked-title' => '「$1」と関連する変更',
 'recentchangeslinked-noresult' => '指定期間中に指定ページのリンク先に変更はありませんでした。',
-'recentchangeslinked-summary' => "これは指定したページからリンクされている(または指定したカテゴリに含まれている)ページの最近の変更の一覧です。
+'recentchangeslinked-summary' => "これは指定したページからリンクされている (または指定したカテゴリに含まれている) ページの最近の変更の一覧です。
 [[Special:Watchlist|自分のウォッチリスト]]にあるページは'''太字'''で表示されます。",
 'recentchangeslinked-page' => 'ページ名:',
-'recentchangeslinked-to' => '指定したページの「リンク元」ページの変更を表示',
+'recentchangeslinked-to' => 'このページへのリンク元での変更の表示に切り替え',
 
 # Upload
 'upload' => 'ファイルをアップロード',
@@ -1809,7 +1809,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'uploadnologin' => 'ログインしていません',
 'uploadnologintext' => 'ファイルをアップロードするには[[Special:UserLogin|ログイン]]する必要があります。',
 'upload_directory_missing' => 'アップロード先ディレクトリ ($1) が見つかりませんでした。ウェブ サーバーによる作成もできませんでした。',
-'upload_directory_read_only' => 'アップロード先ディレクトリ($1)には、ウェブサーバーが書き込めません。',
+'upload_directory_read_only' => 'アップロード先ディレクトリ ($1) には、ウェブサーバーが書き込めません。',
 'uploaderror' => 'アップロードのエラー',
 'upload-recreate-warning' => "'''警告: その名前のファイルは、以前に削除または移動されています。'''
 
@@ -1876,15 +1876,15 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 新しい概要を表示させるには、説明ページを手動で編集する必要があります。
 [[$1|thumb]]',
 'fileexists-extension' => '類似した名前のファイルが既に存在します: [[$2|thumb]]
-* アップロード中のファイルの名前<strong>[[:$1]]</strong>
+* アップロード中のファイルの名前<strong>[[:$1]]</strong>
 * 既存ファイルの名前: <strong>[[:$2]]</strong>
 違う名前を選択してください。',
-'fileexists-thumbnail-yes' => "このファイルは元の画像から縮小されたもの''(サムネイル)''のようです。
+'fileexists-thumbnail-yes' => "このファイルは元の画像から縮小されたもの ''(サムネイル)'' のようです。
 [[$1|thumb]]
-ファイル<strong>[[:$1]]</strong>を確認してください。
+ファイル <strong>[[:$1]]</strong> を確認してください。
 確認したファイルが同じ画像の元のサイズの版の場合は、サムネイルを別途アップロードする必要はありません。",
-'file-thumbnail-no' => "ファイル名が<strong>$1</strong>から始まっています。
-他の画像から縮小されたもの''(サムネイル)''のようです。
+'file-thumbnail-no' => "ファイル名が <strong>$1</strong> で始まっています。
+他の画像から縮小されたもの ''(サムネイル)'' のようです。
 より高精細な画像をお持ちの場合はそれをアップロードしてください。お持ちではない場合はファイル名を変更してください。",
 'fileexists-forbidden' => 'この名前のファイルは既に存在しており、上書きできません。
 アップロードを継続したい場合は、前のページに戻り、別のファイル名を使用してください。
@@ -1892,8 +1892,8 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'fileexists-shared-forbidden' => 'この名前のファイルは共有ファイルリポジトリに既に存在しています。
 アップロードを継続したい場合は、前のページに戻り、別のファイル名を使用してください。
 [[File:$1|thumb|center|$1]]',
-'file-exists-duplicate' => 'このファイルは以下の{{PLURAL:$1|ファイル|ファイル群}}と重複しています',
-'file-deleted-duplicate' => 'このファイル([[:$1]])と同一のファイルが以前に削除されています。
+'file-exists-duplicate' => 'このファイルは以下の{{PLURAL:$1|ファイル|ファイル群}}と重複しています:',
+'file-deleted-duplicate' => 'このファイル ([[:$1]]) と同一のファイルが以前に削除されています。
 再度アップロードをする前に、以前削除されたファイルの削除記録を確認してください。',
 'uploadwarning' => 'アップロード警告',
 'uploadwarning-text' => '下記のファイル解説を修正して再試行してください。',
@@ -1957,7 +1957,7 @@ $1',
 それでもこのエラーが発生する場合は、[[Special:ListUsers/sysop|管理者]]に連絡してください。',
 'upload-too-many-redirects' => 'そのURLに含まれるリダイレクトが多すぎます',
 'upload-unknown-size' => 'サイズ不明',
-'upload-http-error' => 'HTTPエラー発生:$1',
+'upload-http-error' => 'HTTP エラー発生: $1',
 'upload-copy-upload-invalid-domain' => 'このドメインからのアップロードは許可されていません。',
 
 # File backend
@@ -2041,14 +2041,14 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization をご覧ください
 'img-auth-bad-query-string' => 'URLの中に無効なクエリ文字列があります。',
 
 # HTTP errors
-'http-invalid-url' => '無効なURL$1',
+'http-invalid-url' => '無効なURL$1',
 'http-invalid-scheme' => 'スキーム「$1」の URL には未対応です。',
 'http-request-error' => '不明なエラーによりHTTPリクエストに失敗しました。',
 'http-read-error' => 'HTTP読み込みエラーです。',
 'http-timed-out' => 'HTTP要求がタイムアウトしました。',
 'http-curl-error' => 'URLからの取得に失敗しました: $1',
 'http-host-unreachable' => 'URLに到達できません。',
-'http-bad-status' => 'HTTP要求中に問題が発生しました:$1$2',
+'http-bad-status' => 'HTTP リクエストで問題が発生しました: $1 $2',
 
 # Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
 'upload-curl-error6' => 'URLに到達できませんでした',
@@ -2098,7 +2098,7 @@ URLが正しいものであり、ウェブサイトが稼働していること
 'filehist-comment' => 'コメント',
 'filehist-missing' => 'ファイルがありません',
 'imagelinks' => 'ファイルの使用状況',
-'linkstoimage' => '以下の {{PLURAL:$1| ページ|$1 ページ}}が、このファイルへリンクしています:',
+'linkstoimage' => '以下の{{PLURAL:1|ページ|&#32;$1 ページ}}がこのファイルにリンクしています:',
 'linkstoimage-more' => 'このファイルへは $1 を超える数のページからリンクがあります。
 以下の一覧ではこのファイルにリンクしている最初の $1 ページのみを表示しています。
 [[Special:WhatLinksHere/$2|完全な一覧]]も参照してください。',
@@ -2112,9 +2112,9 @@ URLが正しいものであり、ウェブサイトが稼働していること
 'sharedupload-desc-here' => 'このファイルは$1から来ており、他のプロジェクトで使用されている可能性があります。
 $1での[$2 ファイル解説ページ]にある説明を以下に示します。',
 'sharedupload-desc-edit' => 'このファイルは$1から来ており、他のプロジェクトで使用されている可能性があります。
-$1での[$2 ファイル解説ページ]にある説明を編集したほうがいいかもしれません。',
+$1での[$2 ファイル解説ページ]にある説明を編集したがいいかもしれません。',
 'sharedupload-desc-create' => 'このファイルは$1から来ており、他のプロジェクトで使用されている可能性があります。
-$1での[$2 ファイル解説ページ]にある説明を編集したほうがいいかもしれません。',
+$1での[$2 ファイル解説ページ]にある説明を編集したがいいかもしれません。',
 'filepage-nofile' => 'この名前のファイルは存在しません。',
 'filepage-nofile-link' => 'この名前のファイルは存在しませんが、[$1 アップロード]できます。',
 'uploadnewversion-linktext' => 'このファイルの新しい版をアップロードする',
@@ -2175,7 +2175,7 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 
 # Random page
 'randompage' => 'おまかせ表示',
-'randompage-nopages' => '以下の{{PLURAL:$2|名前空間}}にはページがありません:$1。',
+'randompage-nopages' => '以下の{{PLURAL:$2|名前空間}}にはページがありません: $1',
 
 # Random redirect
 'randomredirect' => 'おまかせリダイレクト',
@@ -2313,7 +2313,7 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'log' => '記録',
 'all-logs-page' => 'すべての公開記録',
 'alllogstext' => '{{SITENAME}}の取得できる記録をまとめて表示しています。
-記録の種類、実行した利用者(大文字小文字は区別)、影響を受けたページ(大文字小文字は区別)による絞り込みができます。',
+記録の種類、実行した利用者 (大文字小文字は区別)、影響を受けたページ (大文字小文字は区別) による絞り込みができます。',
 'logempty' => '該当する記録はありません。',
 'log-title-wildcard' => 'この文字列で始まるページ名を検索',
 'showhideselectedlogentries' => '選択した記録項目を表示/非表示',
@@ -2331,7 +2331,7 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'allpagesprev' => '前へ',
 'allpagesnext' => '次へ',
 'allpagessubmit' => '表示',
-'allpagesprefix' => '次の文字列から始まるページを表示',
+'allpagesprefix' => '次の文字列から始まるページを表示:',
 'allpagesbadtitle' => '指定したページ名は無効か、言語間またはインターウィキ接頭辞を含んでいます。
 ページ名に使用できない文字が1つ以上含まれている可能性があります。',
 'allpages-bad-ns' => '{{SITENAME}}に「$1」という名前空間はありません。',
@@ -2347,7 +2347,7 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'categoriespagetext' => '以下の{{PLURAL:$1|カテゴリ}}にはページまたはメディアがあります。
 [[Special:UnusedCategories|未使用のカテゴリ]]はここには表示していません。
 [[Special:WantedCategories|望まれるカテゴリ]]も参照してください。',
-'categoriesfrom' => '最初に表示するカテゴリ',
+'categoriesfrom' => '最初に表示するカテゴリ:',
 'special-categories-sort-count' => '項目数順に並べ替え',
 'special-categories-sort-abc' => '辞書順に並べ替え',
 
@@ -2376,7 +2376,7 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 # Special:ActiveUsers
 'activeusers' => '活動中の利用者一覧',
 'activeusers-intro' => 'これは過去 $1 {{PLURAL:$1|日|日間}}に何らかの活動をした利用者の一覧です。',
-'activeusers-count' => '過去 {{PLURAL:$3|1 日|$3 日間}}に $1 {{PLURAL:$1|回の編集}}',
+'activeusers-count' => '過去 {{PLURAL:$3|1 日|$3 日間}}に $1 {{PLURAL:$1|回の操作}}',
 'activeusers-from' => '最初に表示する利用者:',
 'activeusers-hidebots' => 'ボットを隠す',
 'activeusers-hidesysops' => '管理者を隠す',
@@ -2394,12 +2394,12 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'listgrouprights-members' => '(該当者一覧)',
 'listgrouprights-right-display' => '<span class="listgrouprights-granted">$1 (<code>$2</code>)</span>',
 'listgrouprights-right-revoked' => '<span class="listgrouprights-revoked">$1 (<code>$2</code>)</span>',
-'listgrouprights-addgroup' => '{{PLURAL:$2|グループ}}を追加$1',
-'listgrouprights-removegroup' => '{{PLURAL:$2|グループ}}を除去$1',
+'listgrouprights-addgroup' => '{{PLURAL:$2|グループ}}を追加$1',
+'listgrouprights-removegroup' => '{{PLURAL:$2|グループ}}を除去$1',
 'listgrouprights-addgroup-all' => '全グループを追加可能',
 'listgrouprights-removegroup-all' => '全グループを除去可能',
-'listgrouprights-addgroup-self' => '自分のアカウントに{{PLURAL:$2|グループ}}を追加:$1',
-'listgrouprights-removegroup-self' => '自分のアカウントから{{PLURAL:$2|グループ}}を除去:$1',
+'listgrouprights-addgroup-self' => '自身のアカウントに{{PLURAL:$2|グループ}}を追加: $1',
+'listgrouprights-removegroup-self' => '自身のアカウントから{{PLURAL:$2|グループ}}を除去: $1',
 'listgrouprights-addgroup-self-all' => '自分のアカウントに全グループを追加可能',
 'listgrouprights-removegroup-self-all' => '自分のアカウントから全グループを除去可能',
 
@@ -2412,7 +2412,7 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'emailpage' => '利用者にメールを送信',
 'emailpagetext' => '以下のフォームを使用してこの{{GENDER:$1|利用者}}にメールを送信できます。
 「差出人」として、[[Special:Preferences|利用者の個人設定]]で入力したメールアドレスが設定されます。これにより、受信者があなたに直接返信できるようになります。',
-'usermailererror' => 'メールが以下のエラーを返しました',
+'usermailererror' => 'メールが以下のエラーを返しました:',
 'defemailsubject' => '{{SITENAME}} 利用者「$1」からのメール',
 'usermaildisabled' => '利用者メール機能は無効です',
 'usermaildisabledtext' => 'このウィキでは他の利用者にメールを送信できません',
@@ -2479,16 +2479,16 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'enotif_mailer' => '{{SITENAME}} 通知メール',
 'enotif_reset' => 'すべてのページを訪問済みにする',
 'enotif_impersonal_salutation' => '{{SITENAME}}の利用者',
-'enotif_subject_deleted' => '{{SITENAME}} ページ $1 を {{gender:$2|$2}} が削除しました',
-'enotif_subject_created' => '{{SITENAME}} ページ $1 を {{gender:$2|$2}} が作成しました',
-'enotif_subject_moved' => '{{SITENAME}} ページ $1 を {{gender:$2|$2}} が移動しました',
-'enotif_subject_restored' => '{{SITENAME}} ページ $1 を {{gender:$2|$2}} が復元しました',
-'enotif_subject_changed' => '{{SITENAME}} ページ $1 を {{gender:$2|$2}} が変更しました',
-'enotif_body_intro_deleted' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、{{gender:$2 |$2}}によって削除されました。$3をご覧ください。',
-'enotif_body_intro_created' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、{{gender:$2 |$2}}によって作成されました。現在の版は$3で閲覧できます。',
-'enotif_body_intro_moved' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、{{gender:$2 |$2}}によって移動されました。現在の版は$3で閲覧できます。',
-'enotif_body_intro_restored' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、{{gender:$2 |$2}}によって復元されました。現在の版は$3で閲覧できます。',
-'enotif_body_intro_changed' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、{{gender:$2 |$2}}によって変更されました。現在の版は$3で閲覧できます。',
+'enotif_subject_deleted' => '{{SITENAME}} ページ $1 を $2 が{{GENDER:$2|削除しました}}',
+'enotif_subject_created' => '{{SITENAME}} ページ $1 を $2 が{{GENDER:$2|作成しました}}',
+'enotif_subject_moved' => '{{SITENAME}} ページ $1 を $2 が{{GENDER:$2|移動しました}}',
+'enotif_subject_restored' => '{{SITENAME}} ページ $1 を $2 が{{GENDER:$2|復元しました}}',
+'enotif_subject_changed' => '{{SITENAME}} ページ $1 を $2 が{{GENDER:$2|変更しました}}',
+'enotif_body_intro_deleted' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、$2 によって{{GENDER:$2|削除}}されました。$3 をご覧ください。',
+'enotif_body_intro_created' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、$2 によって{{GENDER:$2|作成}}されました。現在の版は $3 で閲覧できます。',
+'enotif_body_intro_moved' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、$2 によって{{GENDER:$2|移動}}されました。現在の版は $3 で閲覧できます。',
+'enotif_body_intro_restored' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、$2 によって{{GENDER:$2|復元}}されました。現在の版は $3 で閲覧できます。',
+'enotif_body_intro_changed' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、$2 によって{{GENDER:$2|変更}}されました。現在の版は $3 で閲覧できます。',
 'enotif_lastvisited' => '最終訪問以降のすべての変更は $1 をご覧ください。',
 'enotif_lastdiff' => 'この変更内容を表示するには $1 をご覧ください。',
 'enotif_anon_editor' => '匿名利用者「$1」',
@@ -2496,27 +2496,27 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 
 $PAGEINTRO $NEWPAGE
 
-編集内容の要約:$PAGESUMMARY($PAGEMINOREDIT)
+編集内容の要約: $PAGESUMMARY ($PAGEMINOREDIT)
 
-投稿者の連絡先
-メール$PAGEEDITOR_EMAIL
-ウィキ$PAGEEDITOR_WIKI
+投稿者の連絡先:
+メール$PAGEEDITOR_EMAIL
+ウィキ$PAGEEDITOR_WIKI
 
 このページを訪れない限り、これ以上の活動に対する通知は送信されません。ウォッチリスト内のすべてのページについて、通知を再設定することもできます。
 
                          {{SITENAME}}通知システム
 
 --
-メール通知の設定は、以下のページで変更してください
+メール通知の設定は、以下のページで変更してください:
 {{canonicalurl:{{#special:Preferences}}}}
 
-ウォッチリストの設定は、以下のページで変更してください
+ウォッチリストの設定は、以下のページで変更してください:
 {{canonicalurl:{{#special:EditWatchlist}}}}
 
-このページは、以下のページでウォッチリストから削除できます
+このページは、以下のページでウォッチリストから削除できます:
 $UNWATCHURL
 
-ご意見、お問い合わせ
+ご意見、お問い合わせ:
 {{canonicalurl:{{MediaWiki:Helppage}}}}',
 'created' => '作成',
 'changed' => '変更',
@@ -2564,13 +2564,13 @@ $UNWATCHURL
 'rollbackfailed' => '巻き戻しに失敗しました',
 'cantrollback' => '編集を差し戻せません。
 最後の投稿者が、このページの唯一の作者です。',
-'alreadyrolled' => 'ページ[[:$1]]の[[User:$2|$2]]([[User talk:$2|トーク]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])による編集を巻き戻せません。
+'alreadyrolled' => 'ページ[[:$1]]の[[User:$2|$2]] ([[User talk:$2|トーク]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) による編集を巻き戻せません。
 他の利用者が既に編集または巻き戻しを行ったためです。
 
-このページの最後の編集は[[User:$3|$3]]([[User talk:$3|トーク]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])によるものです。',
+このページの最後の編集は[[User:$3|$3]] ([[User talk:$3|トーク]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) によるものです。',
 'editcomment' => "編集内容の要約:「''$1''」",
-'revertpage' => '[[Special:Contributions/$2|$2]]([[User talk:$2|トーク]])による編集を[[User:$1|$1]]による直前の版へ差し戻しました',
-'revertpage-nouser' => '(利用者名削除)による編集を[[User:$1|$1]]による直前の版へ差し戻しました',
+'revertpage' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|トーク]]) による編集を[[User:$1|$1]]による直前の版へ差し戻しました',
+'revertpage-nouser' => '(利用者名削除) による編集を[[User:$1|$1]]による直前の版へ差し戻しました',
 'rollback-success' => '$1による編集を差し戻しました。
 $2による直前の版へ変更されました。',
 
@@ -2593,6 +2593,7 @@ $2による直前の版へ変更されました。',
 'prot_1movedto2' => '[[$1]] を [[$2]] へ移動',
 'protect-badnamespace-title' => '保護不可能な名前空間',
 'protect-badnamespace-text' => 'この名前空間のページは保護できません。',
+'protect-norestrictiontypes-text' => '利用できる制限の種類がないため、このページは保護できません。',
 'protect-norestrictiontypes-title' => '保護できないページ',
 'protect-legend' => '保護の確認',
 'protectcomment' => '理由:',
@@ -2632,10 +2633,10 @@ $2による直前の版へ変更されました。',
 ** 高負荷ページ',
 'protect-edit-reasonlist' => '保護理由を編集',
 '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' => '制限レベル',
+'restriction-type' => '許可:',
+'restriction-level' => '制限レベル:',
 'minimum-size' => '最小サイズ',
-'maximum-size' => '最大サイズ',
+'maximum-size' => '最大サイズ:',
 'pagesize' => '(バイト)',
 
 # Restrictions (nouns)
@@ -2710,7 +2711,7 @@ $1',
 'tooltip-invert' => '選択した名前空間 (チェックを入れている場合は、関連付けられた名前空間も含む) のページの変更を非表示にするには、このボックスにチェックを入れる',
 'namespace_association' => '関連付けられた名前空間も含める',
 'tooltip-namespace_association' => '選択した名前空間に関連付けられたトークページ (逆にトークページの名前空間を選択した場合も同様) の名前空間も含めるには、このボックスにチェックを入れる',
-'blanknamespace' => '(標準)',
+'blanknamespace' => '(標準)',
 
 # Contributions
 'contributions' => '{{GENDER:$1|利用者}}の投稿記録',
@@ -2922,10 +2923,12 @@ $1 のブロックの理由は「''$2''」です。",
 [[Special:DoubleRedirects|二重転送]]や[[Special:BrokenRedirects|迷子のリダイレクト]]を確認する必要があります。
 リンクを正しく維持するのは移動した人の責任です。
 
-移動先が既に存在する場合は、そのページが転送ページであり、かつ過去の版を持たない場合を除いて移動'''できません'''。つまり、間違えてページ名を変更した場合には元に戻せます。また移動によって既存のページを上書きしてしまうことはありません。
+移動先のページが既に存在する場合は、その移動先が転送ページであり、かつ過去の版を持たない場合以外は移動'''できません'''。
+つまり、間違えてページ名を変更した場合には元に戻せます。また移動によって既存のページを上書きしてしまうことはありません。
 
-'''注意!'''
-よく閲覧されるページや、他の多くのページからリンクされているページを移動すると予期しない結果が起こるかもしれません。ページの移動に伴う影響をよく考えてから踏み切るようにしてください。",
+'''注意!'''
+よく閲覧されるページや、他の多くのページからリンクされているページを移動すると予期しない結果が起こるかもしれません。
+ページの移動に伴う影響をよく考えてから踏み切るようにしてください。",
 'movepagetext-noredirectfixer' => "下のフォームを使用すると、ページ名を変更でき、そのページの履歴も変更先に移動できます。
 移動元のページは移動先への転送ページになります。
 自動的な修正を選択しない場合は、[[Special:DoubleRedirects|二重転送]]や[[Special:BrokenRedirects|迷子のリダイレクト]]を確認する必要があります。
@@ -2934,7 +2937,7 @@ $1 のブロックの理由は「''$2''」です。",
 移動先が既に存在する場合は、そのページが転送ページであり、かつ過去の版を持たない場合を除いて移動'''できません'''。
 つまり、間違えてページ名を変更した場合には元に戻せます。また移動によって既存のページを上書きしてしまうことはありません。
 
-'''警告'''
+'''警告!'''
 多く閲覧されるページや多くリンクされているページを移動すると、予期しない大きな変化が起こるかもしれないことにご注意ください。
 ページの移動に伴う影響をよく考えてから移動してください。",
 'movepagetalktext' => "関連付けられたトークページも一緒に、自動的に移動されます。ただし、'''以下の場合を除きます:'''
@@ -3085,7 +3088,7 @@ MediaWiki 全般のローカライズ (地域化) に貢献したい場合は、
 'importbadinterwiki' => 'ウィキ間リンクが正しくありません',
 'importnotext' => '内容が空、または本文がありません',
 'importsuccess' => '取り込みが完了しました!',
-'importhistoryconflict' => '取り込み時にいくつかの版が競合しました(以前に同じページが取り込まれているかもしれません)',
+'importhistoryconflict' => '取り込み時にいくつかの版が競合しました (以前に同じページが取り込まれているかもしれません)',
 'importnosources' => 'ウィキ間移動の取り込み元が定義されていないため、履歴の直接アップロードは無効になっています。',
 'importnofile' => '取り込みファイルはアップロードされませんでした。',
 'importuploaderrorsize' => '取り込みファイルのアップロードに失敗しました。
@@ -3124,8 +3127,8 @@ MediaWiki 全般のローカライズ (地域化) に貢献したい場合は、
 'javascripttest-title' => '$1 のテストの実行',
 'javascripttest-pagetext-noframework' => 'このページは JavaScript のテストを実行するために予約されています。',
 'javascripttest-pagetext-unknownframework' => 'テストフレームワーク「$1」は不明です。',
-'javascripttest-pagetext-frameworks' => '次のテストフレームワークからひとつを選択してください:$1',
-'javascripttest-pagetext-skins' => 'テストを実行する外装を選択してください',
+'javascripttest-pagetext-frameworks' => '以下のテストフレームワークから1つ選択してください: $1',
+'javascripttest-pagetext-skins' => 'テストを実行する外装を選択してください:',
 'javascripttest-qunit-intro' => 'mediawiki.org上の[$1 テストのドキュメント]を参照してください。',
 'javascripttest-qunit-heading' => 'MediaWiki JavaScript QUnit テストスイート',
 
@@ -3253,7 +3256,7 @@ MediaWiki 全般のローカライズ (地域化) に貢献したい場合は、
 'spamprotectiontitle' => 'スパム防御フィルター',
 'spamprotectiontext' => '保存しようとした文章はスパムフィルターによってブロックされました。
 これはおそらく、ブラックリストにある外部サイトへのリンクが原因で発生します。',
-'spamprotectionmatch' => '以下の文章はスパムフィルターが発動したものです$1',
+'spamprotectionmatch' => '以下の文章はスパムフィルターが発動したものです$1',
 'spambot_username' => 'MediaWikiスパム除去',
 'spam_reverting' => '$1へのリンクを含まない最新の版に差し戻し',
 'spam_blanking' => 'すべての版が$1へのリンクを含んでいます。白紙化します。',
@@ -3276,6 +3279,7 @@ MediaWiki 全般のローカライズ (地域化) に貢献したい場合は、
 'pageinfo-robot-noindex' => '検索エンジンに収集されない',
 'pageinfo-views' => '閲覧回数',
 'pageinfo-watchers' => 'ページをウォッチリストに入れている人数',
+'pageinfo-few-watchers' => 'ウォッチしている利用者 $1 {{PLURAL:$1|人未満}}',
 'pageinfo-redirects-name' => 'このページへのリダイレクト数',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'このページの下位ページ数',
@@ -3364,8 +3368,8 @@ $1',
 'svg-long-desc-animated' => 'アニメーション SVG ファイル、$1 × $2 ピクセル、ファイルサイズ: $3',
 'svg-long-error' => '無効な SVG ファイル: $1',
 'show-big-image' => '高解像度での画像',
-'show-big-image-preview' => 'このプレビューのサイズ$1。',
-'show-big-image-other' => 'その他の{{PLURAL:$2|解像度}}$1。',
+'show-big-image-preview' => 'このプレビューのサイズ$1。',
+'show-big-image-other' => 'その他の{{PLURAL:$2|解像度}}$1。',
 'show-big-image-size' => '$1 × $2 ピクセル',
 'file-info-gif-looped' => 'ループします',
 'file-info-gif-frames' => '$1 {{PLURAL:$1|フレーム}}',
@@ -3403,11 +3407,11 @@ $1',
 'just-now' => 'ちょうど今',
 
 # Bad image list
-'bad_image_list' => '書式は以下の通りです
+'bad_image_list' => '書式は以下の通りです:
 
-箇条書き項目(*で始まる行)のみが考慮されます。
-各行最初のリンクは、好ましくないファイルへのリンクとしてください。
\90\8cã\81\98è¡\8cã\81§それ以降にあるリンクは例外、つまりインライン挿入されてもいいページと見なされます。',
+箇条書き項目 (*で始まる行) のみが考慮されます。
+各行の最初のリンクは、好ましくないファイルへのリンクにしてください。
\90\8cã\81\98è¡\8cã\81®それ以降にあるリンクは例外、つまりインライン挿入されてもいいページと見なされます。',
 
 /*
 Short names for language variants used for language conversion links.
@@ -3466,8 +3470,8 @@ Variants for Chinese language
 
 # Metadata
 'metadata' => 'メタデータ',
-'metadata-help' => 'このファイルには、追加情報があります(おそらく、作成やデジタル化する際に使用したデジタルカメラやスキャナーが追加したものです)
-このファイルが元の状態から変更されている場合、いくつかの項目は、修正されたファイルを完全に反映していないかもしれません。',
+'metadata-help' => 'このファイルには、追加情報があります (おそらく、作成やデジタル化する際に使用したデジタルカメラやスキャナーが追加したものです)
+このファイルが元の状態から変更されている場合、修正されたファイルを完全に反映していない項目がある場合があります。',
 'metadata-expand' => '拡張項目を表示',
 'metadata-collapse' => '拡張項目を非表示',
 'metadata-fields' => 'このメッセージで列挙している画像メタデータフィールドは、メタデータ表を折り畳んだ状態のときに画像ページに読み込まれます。
@@ -3575,7 +3579,7 @@ Variants for Chinese language
 'exif-gpslongitude' => '経度',
 'exif-gpsaltituderef' => '高度の基準',
 'exif-gpsaltitude' => '高度',
-'exif-gpstimestamp' => 'GPS日時(原子時計)',
+'exif-gpstimestamp' => 'GPS日時 (原子時計)',
 'exif-gpssatellites' => '測位に用いた衛星信号',
 'exif-gpsstatus' => 'GPS受信機の状態',
 'exif-gpsmeasuremode' => 'GPSの測位方法',
@@ -3640,7 +3644,7 @@ Variants for Chinese language
 'exif-label' => 'ラベル',
 'exif-datetimemetadata' => 'メタデータの最終更新日',
 'exif-nickname' => '画像の非公式名',
-'exif-rating' => '評価(5点満点)',
+'exif-rating' => '評価 (5点満点)',
 'exif-rightscertificate' => '権利管理証明書',
 'exif-copyrighted' => '著作権情報',
 'exif-copyrightowner' => '著作権者',
@@ -3911,35 +3915,35 @@ Variants for Chinese language
 'confirmemail_loggedin' => 'メールアドレスは確認されました。',
 'confirmemail_error' => '確認情報を保存する際にエラーが発生しました。',
 'confirmemail_subject' => '{{SITENAME}} メールアドレスの確認',
-'confirmemail_body' => '誰か(おそらくあなた)が、IPアドレス$1から、
+'confirmemail_body' => '誰か (おそらくあなた) が、IPアドレス$1から、
 このメールアドレスで{{SITENAME}}のアカウント「$2」を登録しました。
 
 このアカウントが本当に自分のものか確認して、
-{{SITENAME}}のメール機能を有効にするには、以下のURLをブラウザーで開いてください
+{{SITENAME}}のメール機能を有効にするには、以下のURLをブラウザーで開いてください:
 
 $3
 
 もしアカウントの登録をした覚えがない場合は、
-次のURLをブラウザーで開いて、メールアドレスの確認を中止してください:
+次のURLをブラウザーで開いて、メールアドレスの確認をキャンセルしてください:
 
 $5
 
 この確認用コードは、$4に期限切れになります。',
-'confirmemail_body_changed' => '誰か(おそらくあなた)が IP アドレス $1 から、
+'confirmemail_body_changed' => '誰か (おそらくあなた) が IP アドレス $1 から、
 {{SITENAME}} のアカウント「$2」のメールアドレスをこのアドレスに変更しました。
 
 このアカウントが本当にあなたのものであれば、以下のリンクをブラウザーで開いて、
-{{SITENAME}} のメール機能を再び有効にしてください
+{{SITENAME}} のメール機能を再び有効にしてください:
 
 $3
 
 もしあなたのアカウント *ではない* 場合は、
-ブラウザーで以下のリンクを開いて、メールアドレスの確認をキャンセルしてください
+ブラウザーで以下のリンクを開いて、メールアドレスの確認をキャンセルしてください:
 
 $5
 
 この確認コードは $4 に期限切れになります。',
-'confirmemail_body_set' => '誰か(おそらくあなた)が IP アドレス $1 から
+'confirmemail_body_set' => '誰か (おそらくあなた) が IP アドレス $1 から
 {{SITENAME}} のアカウント「$2」のメールアドレスをこのアドレスに設定しました。
 
 このアカウントが本当にあなたのものであれば、以下のリンクをブラウザーで開いて、
@@ -3948,7 +3952,7 @@ $5
 $3
 
 もしあなたのアカウントではない場合は、
-次のリンクをブラウザーで開いて、メールアドレスの確認をキャンセルしてください
+次のリンクをブラウザーで開いて、メールアドレスの確認をキャンセルしてください:
 
 $5
 
@@ -3966,8 +3970,8 @@ $5
 'deletedwhileediting' => "'''警告''': このページが、編集開始後に削除されました!",
 'confirmrecreate' => "あなたが編集を開始した後、[[User:$1|$1]] ([[User talk:$1|トーク]]) がこのページを以下の理由で削除しました:
 : ''$2''
-本当にこのままこのページを再作成していいか確認してください。",
-'confirmrecreate-noreason' => 'あなたが編集を開始した後、[[User:$1|$1]] ([[User talk:$1|トーク]]) がこのページを削除しました。本当にこのページを再作成していいかご確認ください。',
+このままこのページを本当に再作成していいか確認してください。",
+'confirmrecreate-noreason' => 'あなたが編集を開始した後、[[User:$1|$1]] ([[User talk:$1|トーク]]) がこのページを削除しました。このページを本当に再作成していいかご確認ください。',
 'recreate' => '再作成する',
 
 # action=purge
@@ -4122,7 +4126,7 @@ $5
 'hebrew-calendar-m12-gen' => 'エルール',
 
 # Signatures
-'signature' => '[[{{ns:user}}:$1|$2]]([[{{ns:user_talk}}:$1|トーク]])',
+'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|トーク]])',
 
 # Core parser functions
 'unknown_extension_tag' => '不明な拡張機能タグ「$1」です',
@@ -4149,11 +4153,11 @@ $5
 'version-poweredby-credits' => "このウィキは、'''[//www.mediawiki.org/ MediaWiki]'''(copyright © 2001-$1 $2)で動作しています。",
 'version-poweredby-others' => 'その他',
 'version-credits-summary' => '[[Special:Version|MediaWiki]] に貢献した以下の人たちに感謝します。',
-'version-license-info' => 'MediaWikiはフリーソフトウェアです。あなたは、フリーソフトウェア財団の発行するGNU一般公衆利用許諾書 (GNU General Public License)(バージョン2、またはそれ以降のライセンス)の規約に基づき、このライブラリを再配布および改変できます。
+'version-license-info' => 'MediaWikiはフリーソフトウェアです。あなたは、フリーソフトウェア財団の発行するGNU一般公衆利用許諾書 (GNU General Public License) (バージョン2、またはそれ以降のライセンス) の規約に基づき、このライブラリを再配布および改変できます。
 
 MediaWikiは、有用であることを期待して配布されていますが、商用あるいは特定の目的に適するかどうかも含めて、暗黙的にも、一切保証されません。詳しくは、GNU一般公衆利用許諾書をご覧ください。
 
-あなたはこのプログラムと共に、[{{SERVER}}{{SCRIPTPATH}}/COPYING GNU一般公衆利用許諾契約書の複製]を受け取ったはずです。もし受け取っていなければ、フリーソフトウェア財団(the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA)まで請求するか、[//www.gnu.org/licenses/old-licenses/gpl-2.0.html オンラインで閲覧]してください。',
+あなたはこのプログラムと共に、[{{SERVER}}{{SCRIPTPATH}}/COPYING GNU一般公衆利用許諾契約書の複製]を受け取ったはずです。受け取っていない場合は、フリーソフトウェア財団 (the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA) まで請求するか、[//www.gnu.org/licenses/old-licenses/gpl-2.0.html オンラインで閲覧]してください。',
 'version-software' => 'インストール済みソフトウェア',
 'version-software-product' => '製品',
 'version-software-version' => 'バージョン',
@@ -4195,7 +4199,7 @@ MediaWikiは、有用であることを期待して配布されていますが
 'specialpages-group-highuse' => 'よく利用されているページ',
 'specialpages-group-pages' => 'ページの一覧',
 'specialpages-group-pagetools' => 'ページツール',
-'specialpages-group-wiki' => 'ã\82¦ã\82£ã\82­ã\81«é\96¢ã\81\99ã\82\8bæ\83\85å ±とツール',
+'specialpages-group-wiki' => 'ã\83\87ã\83¼ã\82¿とツール',
 'specialpages-group-redirects' => '転送される特別ページ',
 'specialpages-group-spam' => 'スパム対策ツール',
 
@@ -4205,8 +4209,8 @@ MediaWikiは、有用であることを期待して配布されていますが
 
 # External image whitelist
 'external_image_whitelist' => '  #この行はこのままにしておいてください<pre>
-#この下に正規表現(//の間に入る記述)を置いてください
-#外部の(ホットリンクされている)画像の URL と一致するか検査されます
+#この下に正規表現 (//の間に入る記述) を置いてください
+#外部の (ホットリンクされている) 画像の URL と一致するか検査されます
 #一致する場合は画像として、一致しない場合は画像へのリンクとして表示されます
 #行の頭に # を付けるとコメントとして扱われます
 #大文字と小文字は区別されません
@@ -4215,7 +4219,7 @@ MediaWikiは、有用であることを期待して配布されていますが
 
 # Special:Tags
 'tags' => '有効な変更タグ',
-'tag-filter' => '[[Special:Tags|タグ]]絞り込み',
+'tag-filter' => '[[Special:Tags|タグ]]絞り込み:',
 'tag-filter-submit' => '絞り込み',
 'tags-title' => 'タグ',
 'tags-intro' => 'このページは、ソフトウェアが編集に対して付けるタグとその意味の一覧です。',
@@ -4261,19 +4265,19 @@ MediaWikiは、有用であることを期待して配布されていますが
 'htmlform-selectorother-other' => 'その他',
 
 # SQLite database support
-'sqlite-has-fts' => '$1(全文検索あり)',
-'sqlite-no-fts' => '$1(全文検索なし)',
+'sqlite-has-fts' => '$1 (全文検索あり)',
+'sqlite-no-fts' => '$1 (全文検索なし)',
 
 # New logging system
 'logentry-delete-delete' => '$1 がページ「$3」を削除しました',
 'logentry-delete-restore' => '$1 がページ「$3」を復元しました',
-'logentry-delete-event' => '$1 が$3の{{PLURAL:$5|記録項目$5件}}の閲覧レベルを変更しました$4',
-'logentry-delete-revision' => '$1 がページ「$3」の{{PLURAL:$5|$5版}}の閲覧レベルを変更しました$4',
+'logentry-delete-event' => '$1 が$3の{{PLURAL:$5|記録項目$5件}}の閲覧レベルを変更しました$4',
+'logentry-delete-revision' => '$1 がページ「$3」の{{PLURAL:$5|$5版}}の閲覧レベルを変更しました$4',
 'logentry-delete-event-legacy' => '$1 が「$3」の記録項目の閲覧レベルを変更しました',
 'logentry-delete-revision-legacy' => '$1 がページ「$3」の版の閲覧レベルを変更しました',
 'logentry-suppress-delete' => '$1 がページ「$3」を隠蔽しました',
-'logentry-suppress-event' => '$1 が$3の{{PLURAL:$5|記録項目$5件}}の閲覧レベルを見えない形で変更しました$4',
-'logentry-suppress-revision' => '$1 がページ「$3」の{{PLURAL:$5|$5版}}の閲覧レベルを見えない形で変更しました$4',
+'logentry-suppress-event' => '$1 が$3の{{PLURAL:$5|記録項目$5件}}の閲覧レベルを見えない形で変更しました$4',
+'logentry-suppress-revision' => '$1 がページ「$3」の{{PLURAL:$5|$5版}}の閲覧レベルを見えない形で変更しました$4',
 'logentry-suppress-event-legacy' => '$1 が$3で記録項目の閲覧レベルを見えない形で変更しました',
 'logentry-suppress-revision-legacy' => '$1 がページ「$3」の版の閲覧レベルを見えない形で変更しました',
 'revdelete-content-hid' => '本文の不可視化',
@@ -4293,8 +4297,8 @@ MediaWikiは、有用であることを期待して配布されていますが
 'logentry-newusers-newusers' => '利用者アカウント $1 が作成されました',
 'logentry-newusers-create' => '利用者アカウント $1 が作成されました',
 'logentry-newusers-create2' => '利用者アカウント $3 が $1 により作成されました',
+'logentry-newusers-byemail' => '利用者アカウント $3 が $1 によって作成され、そのパスワードをメールで送信しました',
 'logentry-newusers-autocreate' => '利用者アカウント $1 が自動的に作成されました',
-'newuserlog-byemail' => 'パスワードをメールで送信しました',
 'logentry-rights-rights' => '$1 が $3 の所属グループを $4 から $5 に変更しました',
 'logentry-rights-rights-legacy' => '$1 が $3 の所属グループを変更しました',
 'logentry-rights-autopromote' => '$1 が $4 から $5 に自動的に昇格しました',
@@ -4303,14 +4307,14 @@ MediaWikiは、有用であることを期待して配布されていますが
 # Feedback
 'feedback-bugornote' => '技術的な問題の詳細を説明する準備ができている場合は、[$1 バグ報告]をお願いします。
 準備ができていない場合は、下の簡易フォームを使用してください。あなたのコメントと利用者名が、ページ「[$3 $2]」に追加されます。',
-'feedback-subject' => '件名',
-'feedback-message' => 'メッセージ',
+'feedback-subject' => '件名:',
+'feedback-message' => 'メッセージ:',
 'feedback-cancel' => 'キャンセル',
 'feedback-submit' => 'フィードバックを送信',
 'feedback-adding' => 'ページへのフィードバックの追加...',
-'feedback-error1' => 'エラー:APIから認識されない結果が返ってきました',
-'feedback-error2' => 'エラー編集に失敗しました',
-'feedback-error3' => 'エラー:APIからの応答がありません',
+'feedback-error1' => 'エラー: 認識できない結果を API が返しました',
+'feedback-error2' => 'エラー編集に失敗しました',
+'feedback-error3' => 'エラー: API からの応答がありません',
 'feedback-thanks' => 'ありがとうございます。フィードバックを「[$2 $1]」のページに投稿しました。',
 'feedback-close' => '完了',
 'feedback-bugcheck' => 'Great! [$1 既出のバグ]に既に含まれていないかご確認ください。',
@@ -4322,7 +4326,7 @@ MediaWikiは、有用であることを期待して配布されていますが
 
 # API errors
 'api-error-badaccess-groups' => 'このウィキへのファイルのアップロードが許可されていません。',
-'api-error-badtoken' => '内部エラートークンが正しくありません。',
+'api-error-badtoken' => '内部エラートークンが正しくありません。',
 'api-error-copyuploaddisabled' => 'URLによるアップロードはこのサーバーでは無効になっています。',
 'api-error-duplicate' => '当ウェブサイト上には、既に同じ内容の{{PLURAL:$1|[$2 他のファイル]が|[$2 他のファイルがいくつか]}}存在しています。',
 'api-error-duplicate-archive' => 'サイト上に同じ内容の{{PLURAL:$1|[$2 別のファイル]が|[$2 他のファイルがいくつか]}}既にありましたが、{{PLURAL:$1|それは|それらは}}削除されました。',
@@ -4330,7 +4334,7 @@ MediaWikiは、有用であることを期待して配布されていますが
 'api-error-duplicate-popup-title' => '重複した{{PLURAL:$1|ファイル|ファイル群}}です。',
 'api-error-empty-file' => '送信されたファイルは空でした。',
 'api-error-emptypage' => '内容がないページの新規作成は許可されていません。',
-'api-error-fetchfileerror' => '内部エラー:ファイルの取得中に問題が発生しました。',
+'api-error-fetchfileerror' => '内部エラー: ファイルを取得する際に問題が発生しました。',
 'api-error-fileexists-forbidden' => '「$1」という名前のファイルは存在しており、上書きはできません。',
 'api-error-fileexists-shared-forbidden' => '「$1」という名前のファイルは共有ファイルリポジトリに存在しており、上書きはできません。',
 'api-error-file-too-large' => '送信されたファイルは大きすぎます。',
@@ -4339,23 +4343,24 @@ MediaWikiは、有用であることを期待して配布されていますが
 'api-error-filetype-banned-type' => '$1{{PLURAL:$4|は許可されていないファイル形式です}}。許可されている{{PLURAL:$3|ファイル形式}}は$2です。',
 'api-error-filetype-missing' => 'ファイルに拡張子がありません。',
 'api-error-hookaborted' => '拡張機能のフックによって、修正が中断されました。',
-'api-error-http' => '内部エラー:サービスへの接続で問題が発生しました。',
+'api-error-http' => '内部エラー: サーバーに接続できませんでした。',
 'api-error-illegal-filename' => 'ファイル名が許可されていません。',
-'api-error-internal-error' => '内部エラーウィキ上でアップロードを処理する際に問題が発生しました。',
-'api-error-invalid-file-key' => '内部エラー一時格納場所にファイルが見つかりませんでした。',
-'api-error-missingparam' => '内部エラーリクエストのパラメーターが足りません。',
-'api-error-missingresult' => '内部エラー:複製に成功したか判断できませんでした。',
+'api-error-internal-error' => '内部エラーウィキ上でアップロードを処理する際に問題が発生しました。',
+'api-error-invalid-file-key' => '内部エラー一時格納場所にファイルが見つかりませんでした。',
+'api-error-missingparam' => '内部エラーリクエストのパラメーターが足りません。',
+'api-error-missingresult' => '内部エラー: 複製に成功したかどうか判断できませんでした。',
 'api-error-mustbeloggedin' => 'ファイルをアップロードするにはログインする必要があります。',
-'api-error-mustbeposted' => '内部エラー:リクエストはHTTP POSTである必要があります。',
+'api-error-mustbeposted' => '内部エラー: リクエストは HTTP の POST メソッドである必要があります。',
 'api-error-noimageinfo' => 'アップロードには成功しましたが、サーバーはファイルに関する情報を返しませんでした。',
-'api-error-nomodule' => '内部エラーアップロードを処理するモジュールが設定されていません。',
-'api-error-ok-but-empty' => '内部エラーサーバーからの応答がありません。',
+'api-error-nomodule' => '内部エラーアップロードを処理するモジュールが設定されていません。',
+'api-error-ok-but-empty' => '内部エラーサーバーからの応答がありません。',
 'api-error-overwrite' => '既存のファイルへの上書きは許可されていません。',
-'api-error-stashfailed' => '内部エラー:サーバーは一時ファイルを格納できませんでした。',
+'api-error-stashfailed' => '内部エラー: サーバーは一時ファイルを格納できませんでした。',
+'api-error-publishfailed' => '内部エラー: サーバーは一時ファイルを発行できませんでした。',
 'api-error-timeout' => 'サーバーが決められた時間内に応答しませんでした。',
 'api-error-unclassified' => '不明なエラーが発生しました。',
 'api-error-unknown-code' => '不明なエラー:「$1」',
-'api-error-unknown-error' => '内部エラー:ファイルのアップロードの途中で問題が発生しました。',
+'api-error-unknown-error' => '内部エラー: ファイルをアップロードする際に問題が発生しました。',
 'api-error-unknown-warning' => '不明な警告:「$1」',
 'api-error-unknownerror' => '不明なエラー:「$1」',
 'api-error-uploaddisabled' => 'このウィキではアップロードは無効になっています。',
index 331f912..4279d5f 100644 (file)
@@ -853,7 +853,4 @@ Kun endholtet åf æ liste (lenjer startende ve *) bliver brugt. Den første hen
 # Special:SpecialPages
 'specialpages' => 'Sonst sider',
 
-# New logging system
-'newuserlog-byemail' => 'kodeort tilsend via e-mail',
-
 );
index b37c7a0..73d4961 100644 (file)
@@ -8,6 +8,7 @@
  * @file
  *
  * @author Anggoro
+ * @author Bennylin
  * @author Helix84
  * @author Hoo
  * @author Kaganer
@@ -99,7 +100,7 @@ $messages = array(
 
 'underline-always' => 'Tansah',
 'underline-never' => 'Ora',
-'underline-default' => 'Miturut konfigurasi panjlajah wèb',
+'underline-default' => 'Kulit atau penjelajah bawaan',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Modhèl aksara (font) ing kotak suntingan:',
@@ -184,6 +185,7 @@ $messages = array(
 'newwindow' => '(buka ing jendhéla anyar)',
 'cancel' => 'Batalna',
 'moredotdotdot' => 'Liyané...',
+'morenotlisted' => 'Isih ana...',
 'mypage' => 'Kaca',
 'mytalk' => 'Wicara',
 'anontalk' => 'Dhiskusi IP puniki',
@@ -369,9 +371,9 @@ Iki manawa uga nuduhaké anané kesalahan ing piranti alus sing dipigunakaké d
 'databaseerror' => 'Kasalahan database',
 'dberrortext' => 'Ana kasalahan sintaks ing panyuwunan basis data.
 Kasalahan iki mbokmenawa nuduhaké anané \'\'bug\'\' ing software.
-Panyuwunan basis data sing pungkasan yakuwi: <blockquote><tt>$1</tt></blockquote>
-saka jroning fungsi "<tt>$2</tt>".
-Basis data ngasilaké kasalahan "<tt>$3: $4</tt>".',
+Panyuwunan basis data sing pungkasan yakuwi: <blockquote><code>$1</code></blockquote>
+saka jroning fungsi "<code>$2</code>".
+Basis data ngasilaké kasalahan "<samp>$3: $4</samp>".',
 'dberrortextcl' => 'Ana kasalahan sintaks ing panyuwunan basis data.
 Panyuwunan basis data sing pungkasan iku:
 "$1"
@@ -452,6 +454,7 @@ Sampéyan bisa nganggo {{SITENAME}} sacara anonim, utawa bisa <span class='plain
 
 Cathet yèn sapérangan kaca mungkin isih nampilaké tulisan yèn Sampéyan isih nèng njero log, kuwi bisa ilang yèn Sampéyan ngresiki ''cache'' pramban Sampéyan.",
 'welcomeuser' => 'Sugeng Rawuh, $1!',
+'welcomecreation-msg' => 'Akun panjenengan wis kacipta. Aja lali nata konfigurasi [[Special:Preferences|preferensi {{SITENAME}}]] panjenengan.',
 'yourname' => 'Asma pangangeman',
 'yourpassword' => 'Tembung sandhi:',
 'yourpasswordagain' => 'Balènana tembung sandhi',
@@ -474,7 +477,7 @@ Cathet yèn sapérangan kaca mungkin isih nampilaké tulisan yèn Sampéyan isih
 'gotaccount' => "Wis kagungan akun? '''$1'''.",
 'gotaccountlink' => 'Mlebu',
 'userlogin-resetlink' => 'Lali rincian mlebu log Sampéyan?',
-'createaccountmail' => 'liwat layang e-mail',
+'createaccountmail' => 'Nganggoa sandi sembarang lan kirimna liwat layang e-mail ing ngisor iki',
 'createaccountreason' => 'Alesan:',
 'badretype' => 'Sandhi panjenengan ora gathuk',
 'userexists' => 'Jeneng panganggo sing dilebokaké lagi dianggo.
@@ -537,6 +540,7 @@ Tulung nunggu dhisik sadurungé njajal manèh.',
 # E-mail sending
 'php-mail-error-unknown' => 'Kasalahan ora dingertèni nèng piguna mail() PHP.',
 'user-mail-no-addy' => 'Njajal ngirim layang èlèktronik tanpa alamat layang èlèktronik.',
+'user-mail-no-body' => 'Nyoba ngirim layang e-mail, tapi isine kosong.',
 
 # Change password dialog
 'resetpass' => 'Ganti tembung sandi',
@@ -568,6 +572,25 @@ Panjengen manawa wis kasil ganti tembung sandi utawa nyuwun tembung sandi saunta
 'passwordreset-capture-help' => 'Yèn Sampéyan nyentang kothak iki, layang èlèktronik (mawa tembung sandhi sawetara) bakal ditampilaké nèng Sampéyan lan uga dikirim nèng panganggo.',
 'passwordreset-email' => 'Alamat layang èlèktronik:',
 'passwordreset-emailtitle' => 'Rincian akun nèng {{SITENAME}}',
+'passwordreset-emailtext-ip' => 'Seseorang (mungkin Anda, dari alamat IP $1) meminta pengingat
+detail akun untuk {{SITENAME}} ($4). {{PLURAL:$3|Akun|Akun-akun}} berikut
+terkait dengan alamat surel ini:
+
+$2
+
+{{PLURAL:$3|Sandi sementara|Sandi sementara}} berikut akan kedaluwarsa dalam {{PLURAL:$5|satu hari|$5 hari}}.
+Anda harus masuk dan memilih sandi baru sekarang. Jika orang lain membuat
+permintaan ini atau jika Anda ingat sandi asli dan tidak lagi
+ingin mengubahnya, Anda dapat mengabaikan pesan ini dan terus menggunakan sandi lama.',
+'passwordreset-emailtext-user' => 'Seseorang (mungkin Anda, dari alamat IP $1) meminta pengingat detail akun untuk {{SITENAME}} ($4).
+{{PLURAL:$3|Akun|Akun-akun}} berikut terkait dengan alamat surel ini:
+
+$2
+
+{{PLURAL:$3|Sandi sementara|Sandi sementara}} berikut akan kedaluwarsa dalam {{PLURAL:$5|satu hari|$5 hari}}.
+Anda harus masuk dan memilih sandi baru sekarang. Jika orang lain membuat
+permintaan ini atau jika Anda ingat sandi asli dan tidak lagi
+ingin mengubahnya, Anda dapat mengabaikan pesan ini dan terus menggunakan sandi lama.',
 'passwordreset-emailelement' => 'Jeneng panganggo: $1
 Tembung sandhi sawetara: $2',
 'passwordreset-emailsent' => 'Layang èlèktronik pangèling wis dikirim.',
@@ -582,6 +605,7 @@ Tembung sandhi sawetara: $2',
 'changeemail-oldemail' => 'Alamat layang èlèktronik saiki:',
 'changeemail-newemail' => 'Alamat layang èlèktronik anyar:',
 'changeemail-none' => '(ora ana)',
+'changeemail-password' => 'Sandi {{SITENAME}} panjenengan:',
 'changeemail-submit' => 'Ganti layang èlèktronik',
 'changeemail-cancel' => 'Batal',
 
@@ -698,7 +722,7 @@ Log pamblokiran pungkasan dituduhaké ing ngisor iki minangka bahan rujukan:',
 'note' => "'''Cathetan:'''",
 'previewnote' => "'''Èling yèn Sampéyan mung ndelok pratayang.'''
 Owahan Sampéyan durung kasimpen!",
-'continue-editing' => 'Banjuraké nyunting',
+'continue-editing' => 'Lunga menyang area nyunting',
 'previewconflict' => 'Pratilik iki nuduhaké tèks ing bagian dhuwur kothak suntingan tèks kayadéné bakal katon yèn panjenengan bakal simpen.',
 'session_fail_preview' => "'''Nuwun sèwu, suntingan panjenengan ora bisa diolah amarga dhata sèsi kabusak.
 Coba kirim dhata manèh. Yèn tetep ora bisa, coba log metua lan mlebu log manèh.''''''Amerga wiki iki marengaké panggunan kodhe HTML mentah, mula pratilik didhelikaké minangka pancegahan marang serangan JavaScript.'''
@@ -772,6 +796,15 @@ Katoné kaca iki wis dibusak.',
 'edit-already-exists' => 'Ora bisa nggawé kaca anyar.
 Amerga wis ana.',
 'defaultmessagetext' => 'Tèks layang gawan',
+'content-failed-to-parse' => 'Gagal menjabarkan konten $2 untuk model $1: $3',
+'invalid-content-data' => 'Data konten ora sah',
+'content-not-allowed-here' => 'Konten "$1" ora oleh ing kaca [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'teks wiki',
+'content-model-text' => 'teks polos',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "Pènget: Kaca iki ngandhut kakèhan panggunan fungsi ''parser'' sing larang.
@@ -790,6 +823,8 @@ Sawetara cithakan bakal dilirwakaké.',
 'node-count-exceeded-warning' => 'Kaca munjuli itungan-nodé',
 'expansion-depth-exceeded-category' => 'Kaca sing jeroné èkspansi wis punjul',
 'expansion-depth-exceeded-warning' => 'Kaca munculi jeroné èkspansi',
+'parser-unstrip-loop-warning' => 'Unstrip loop detected',
+'parser-unstrip-recursion-limit' => 'Unstrip recursion limit exceeded ($1)',
 'converter-manual-rule-error' => 'Kasalahan kadètèk nèng aturan pangubahan basa manual',
 
 # "Undo" feature
@@ -919,10 +954,11 @@ Panjenengan ora nduwèni aksès menyang révisi iki.',
 'revdelete-concurrent-change' => 'Gagal ngowahi révisi tanggal $1, jam $2: statusé mbokmanawa wis diowahi déning panganggo liya bebarengan karo panjenengan.
 Mangga priksa cathetan log.',
 'revdelete-only-restricted' => 'Ora bisa ndhelikaké siji barang mawa tanggal $1 wanci $2: Sampéyan ora bisa ndhelikaké barang kuwi saka pangurus tanpa milih salah sawiji pilihan kanggo ndhelikaké sing liyané.',
-'revdelete-reason-dropdown' => '*Alesan mbusak sing umum
-** Planggaran hak cipta
-** Inpormasi pribadi sing ora patut
-** Inpormasi sing potènsial ngrusak martabat',
+'revdelete-reason-dropdown' => '*Alasan penghapusan yang umum
+** Pelanggaran hak cipta
+** Komentar atau informasi pribadi yang tidak pantas
+** Nama pengguna yang tidak pantas
+** Berpotensi mencemarkan nama baik',
 'revdelete-otherreason' => 'Alesan liya/tambahan:',
 'revdelete-reasonotherlist' => 'Alesan liya',
 'revdelete-edit-reasonlist' => 'Sunting alesan pambusakan',
@@ -1115,7 +1151,7 @@ Iki aji acak sing bisa panjenengan gunakaké: $1',
 'timezoneregion-indian' => 'Samodra Hindhia',
 'timezoneregion-pacific' => 'Samodra Pasifik',
 'allowemail' => 'Marengaké panganggo liyané ngirim layang èlèktronik (email).',
-'prefs-searchoptions' => 'Opsi-opsi panggolèkan',
+'prefs-searchoptions' => 'Golèk',
 'prefs-namespaces' => 'Ruang jeneng / Bilik jeneng',
 'defaultns' => 'Utawa golèki ing bilik jeneng iki:',
 'default' => 'baku',
@@ -1128,9 +1164,9 @@ Pembalikan ora bisa dibatalaké.',
 'prefs-emailconfirm-label' => 'Konfirmasi layang-e:',
 'prefs-textboxsize' => 'Ukuran kothak suntingan',
 'youremail' => 'Layang élèktronik (E-mail):',
-'username' => 'Asma panganggo:',
-'uid' => 'ID panganggo:',
-'prefs-memberingroups' => 'Anggota {{PLURAL:$1|klompok|klompok-klompok}}:',
+'username' => '{{GENDER:$1|Asma panganggo}}:',
+'uid' => '{{GENDER:$1|ID panganggo}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Anggota}} {{PLURAL:$1|klompok|klompok-klompok}}:',
 'prefs-registration' => 'Wektu régistrasi:',
 'yourrealname' => 'Asma sajatiné :',
 'yourlanguage' => 'Basa sing dianggo:',
@@ -1508,6 +1544,7 @@ Mangga kontak [[Special:ListUsers/sysop|pangurus]].',
 'backend-fail-notsame' => 'Berkas nonidèntik wis ana nèng "$1".',
 'backend-fail-invalidpath' => '"$1" dudu jurusan nyimpen sing sah.',
 'backend-fail-delete' => 'Ora bisa mbusak berkas "$1".',
+'backend-fail-describe' => 'Gagal mengubah metadata untuk berkas "$1".',
 'backend-fail-alreadyexists' => 'Berkas "$1" wis ana.',
 'backend-fail-store' => 'Ora bisa nyèlèhaké berkas "$1" nèng "$2".',
 'backend-fail-copy' => 'Ora bisa nyalin berkas "$1" nèng "$2".',
@@ -1518,8 +1555,17 @@ Mangga kontak [[Special:ListUsers/sysop|pangurus]].',
 'backend-fail-read' => 'Ora bisa maca berkas "$1".',
 'backend-fail-create' => 'Ora bisa nulis berkas "$1".',
 'backend-fail-maxsize' => 'Ora bisa nulis berkas "$1" amarga luwih gedhé saka {{PLURAL:$2|sak bita|$2 bita}}.',
+'backend-fail-readonly' => 'Backend penyimpanan "$1" ini saat ini hanya bisa dibaca. Alasan yang diberikan adalah: "\'\'$2\'\'"',
+'backend-fail-synced' => 'Berkas "$1" dalam keadaan yang tidak konsisten dalam backends penyimpanan internal',
+'backend-fail-connect' => 'Tidak dapat menyambung ke penyimpanan backend "$1".',
+'backend-fail-internal' => 'Kesalahan yang tidak dikenal terjadi di backend penyimpanan "$1".',
 'backend-fail-contenttype' => 'Ora bisa nemtokaké jinisé kontèn saka berkas sing arep disimpen nèng "$1".',
-'backend-fail-usable' => 'Ora bisa nulis berkas "$1" amarga idin durung nyukupi utawa ilang dirèktori/kontaineré.',
+'backend-fail-batchsize' => 'Penyimpanan backend diberikan batch $1 berkas {{PLURAL:$1||}}operasi; batasnya adalah $2 {{PLURAL:$2||}}operasi.',
+'backend-fail-usable' => 'Ora bisa maca utawa nulis berkas "$1" amarga idin durung nyukupi utawa ilang dirèktori/kontaineré.',
+
+# File journal errors
+'filejournal-fail-dbconnect' => 'Tidak dapat menyambung ke database jurnal untuk penyimpanan backend "$1".',
+'filejournal-fail-dbquery' => 'Tidak bisa update database jurnal untuk penyimpanan backend "$1".',
 
 # Lock manager
 'lockmanager-notlocked' => 'Ora bisa mbukak gembok "$1"; kuwi ora kagembok.',
@@ -1650,6 +1696,7 @@ Mungkin Sampéyan pingin nyunting katrangan nèng [$2 kaca katrangan berkasé] n
 'uploadnewversion-linktext' => 'Unggahna vèrsi sing luwih anyar tinimbang gambar iki',
 'shared-repo-from' => 'saka $1',
 'shared-repo' => 'sawijining panyimpenan kanggo bebarengan',
+'upload-disallowed-here' => 'Anda tidak bisa menimpa berkas ini.',
 
 # File reversion
 'filerevert' => 'Balèkna $1',
@@ -1757,6 +1804,7 @@ Jeneng sing wis <del>dicorèk</del> tegesé wis rampung didandani.',
 # Miscellaneous special pages
 'nbytes' => '$1 {{PLURAL:$1|bita|bita}}',
 'ncategories' => '$1 {{PLURAL:$1|kategori|kategori}}',
+'ninterwikis' => '$1 {{PLURAL:$1|interwiki|interwiki}}',
 'nlinks' => '$1 {{PLURAL:$1|pranala|pranala}}',
 'nmembers' => '$1 {{PLURAL:$1|anggota|anggota}}',
 'nrevisions' => '$1 {{PLURAL:$1|revisi|revisi}}',
@@ -1785,6 +1833,7 @@ Jeneng sing wis <del>dicorèk</del> tegesé wis rampung didandani.',
 'mostlinkedtemplates' => 'Cithakan sing kerep dhéwé dienggo',
 'mostcategories' => 'Kaca sing kategoriné akèh dhéwé',
 'mostimages' => 'Berkas sing kerep dhéwé dienggo',
+'mostinterwikis' => 'Halaman dengan interwiki terbanyak',
 'mostrevisions' => 'Kaca mawa pangowahan sing akèh dhéwé',
 'prefixindex' => 'Kabèh kaca mawa ater-ater',
 'prefixindex-namespace' => 'Kabèh kaca mawa ater-ater (bilik jeneng $1)',
@@ -1882,7 +1931,9 @@ Deleng uga [[Special:WantedCategories|kategori sing diperlokaké]].',
 'linksearch-pat' => 'Pola panggolèkan:',
 'linksearch-ns' => 'Bilik nama:',
 'linksearch-ok' => 'Golèk',
-'linksearch-text' => "''Wildcards'' kaya ta \"*.wikipedia.org\" bisa dienggo.<br />Protokol sing disengkuyung: <code>\$1</code>",
+'linksearch-text' => 'Tanda bintang seperti "*.wikipedia.org" dapat digunakan.
+Perlu sedikitnya satu domain tingkat atas, misalnya "*.org".<br />
+{{PLURAL:$2|Protokol|Protokol}} yang didukung: <code>$1</code> (menggunakan http:// bila protokol tidak ditentukan)',
 'linksearch-line' => '$1 disambung saka $2',
 'linksearch-error' => "''Wildcards'' namung bisa dienggo ing bagéyan awal saka jeneng host.",
 
@@ -1924,8 +1975,10 @@ Informasi tambahan perkara hak-hak individual bisa ditemokaké ing [[{{MediaWiki
 'mailnologin' => 'Ora ana alamat layang e-mail',
 'mailnologintext' => 'Panjenengan kudu [[Special:UserLogin|mlebu log]] lan kagungan alamat e-mail sing sah ing [[Special:Preferences|preféèrensi]] yèn kersa ngirim layang e-mail kanggo panganggo liya.',
 'emailuser' => 'Kirim e-mail panganggo iki',
+'emailuser-title-target' => 'Kirim surel ke {{GENDER:$1|pengguna}} ini',
+'emailuser-title-notarget' => 'Kirimi panganggo iki layang e-mail',
 'emailpage' => 'Kirimi panganggo iki layang e-mail',
-'emailpagetext' => 'Panjenengan bisa migunakaké formulir ing ngisor kanggo ngirim layang-e marang panganggo iki.
+'emailpagetext' => 'Panjenengan bisa migunakaké formulir ing ngisor kanggo ngirim layang-e marang {{GENDER:$1|panganggo}} iki.
 Alamat layang-e sing panjenengan lebokaké ing [[Special:Preferences|préferèsi panjenengan]] bakal dadi alamat "Saka" jroning layang-e kasebut, mula panampa layang-e bakal bisa mbalesi langsung menyang panjenengan.',
 'usermailererror' => 'Kaluputan obyèk layang:',
 'defemailsubject' => '{{SITENAME}} layang èlèktronik saka panganggo "$1"',
@@ -1956,7 +2009,7 @@ Alamat layang-e sing panjenengan lebokaké ing [[Special:Preferences|préferèsi
 'usermessage-editor' => 'Pawartaning layang sistem',
 
 # Watchlist
-'watchlist' => 'Daftar artikel pilihan',
+'watchlist' => 'Daptar pangawasan',
 'mywatchlist' => 'Daftar pangawasan',
 'watchlistfor2' => 'Kanggo $1 $2',
 'nowatchlist' => 'Daftar pangawasan panjenengan kosong.',
@@ -1964,8 +2017,8 @@ Alamat layang-e sing panjenengan lebokaké ing [[Special:Preferences|préferèsi
 'watchnologin' => 'Durung mlebu log',
 'watchnologintext' => 'Panjenengan kudu [[Special:UserLogin|mlebu log]] kanggo ngowahi daftar artikel pilihan.',
 'addwatch' => 'Tambah nèng daptar pangawasan',
-'addedwatchtext' => "Kaca \"[[:\$1]]\" wis ditambahaké menyang [[Special:Watchlist|daftar pangawasan]].
-Owah-owahan sing dumadi ing tembé ing kaca iku lan kaca dhiskusi sing kagandhèng, bakal dipacak ing kéné, lan kaca iku bakal dituduhaké '''kandel''' ing [[Special:RecentChanges|daftar owah-owahan iku]] supados luwih gampang katon.",
+'addedwatchtext' => 'Kaca "[[:$1]]" wis ditambahaké menyang [[Special:Watchlist|daftar pangawasan]].
+Owah-owahan sing dumadi ing tembé ing kaca iku lan kaca dhiskusi sing kagandhèng, bakal dipacak ing kéné.',
 'removewatch' => 'Singkiraké saka daptar pangawasan',
 'removedwatchtext' => 'Kaca "[[:$1]]" wis dibusak saka [[Special:Watchlist|daftar pangawasan]].',
 'watch' => 'tutana',
@@ -1994,6 +2047,16 @@ Owah-owahan sing dumadi ing tembé ing kaca iku lan kaca dhiskusi sing kagandhè
 'enotif_mailer' => 'Pangirim Notifikasi {{SITENAME}}',
 'enotif_reset' => 'Tandhanana kabèh kaca sing wis ditiliki',
 'enotif_impersonal_salutation' => 'Panganggo {{SITENAME}}',
+'enotif_subject_deleted' => 'Halaman $1 di {{SITENAME}} telah dihapus oleh {{gender:$2|$2}}',
+'enotif_subject_created' => 'Halaman $1 di {{SITENAME}} telah dibuat oleh {{gender:$2|$2}}',
+'enotif_subject_moved' => 'Halaman $1 di {{SITENAME}} telah dipindahkan oleh {{gender:$2|$2}}',
+'enotif_subject_restored' => 'Halaman $1 di {{SITENAME}} telah dikembalikan oleh {{gender:$2|$2}}',
+'enotif_subject_changed' => 'Halaman $1 di {{SITENAME}} telah diubah oleh {{gender:$2|$2}}',
+'enotif_body_intro_deleted' => 'Halaman $1 di {{SITENAME}} telah dihapus pada $PAGEEDITDATE oleh {{gender:$2|$2}}, lihat $3.',
+'enotif_body_intro_created' => 'Halaman $1 di {{SITENAME}} telah dibuat pada $PAGEEDITDATE oleh {{gender:$2|$2}}, lihat $3 untuk revisi terkini.',
+'enotif_body_intro_moved' => 'Halaman $1 di {{SITENAME}} telah dipindahkan pada $PAGEEDITDATE oleh {{gender:$2|$2}}, lihat $3 untuk revisi terkini.',
+'enotif_body_intro_restored' => 'Halaman $1 di {{SITENAME}} telah dikembalikan pada $PAGEEDITDATE oleh {{gender:$2|$2}}, lihat $3 untuk revisi terkini.',
+'enotif_body_intro_changed' => 'Halaman $1 di {{SITENAME}} telah diubah pada $PAGEEDITDATE oleh {{gender:$2|$2}}, lihat $3 untuk revisi terkini.',
 'enotif_lastvisited' => 'Deleng $1 kanggo kabèh owah-owahan wiwit pungkasan panjenengan niliki.',
 'enotif_lastdiff' => 'Tilikana $1 kanggo mirsani owah-owahan iki.',
 'enotif_anon_editor' => 'panganggo anonim $1',
@@ -2088,6 +2151,8 @@ Delok [[Special:ProtectedPages|daptar kaca sing dijaga]] kanggo daptar panjagan
 'prot_1movedto2' => '$1 dialihaké menyang $2',
 'protect-badnamespace-title' => 'Bilik jeneng sing ora bisa dijagani',
 'protect-badnamespace-text' => 'Kaca nèng bilik jeneng iki ora bisa dijagani.',
+'protect-norestrictiontypes-text' => 'Kaca iki ora isa diproteksi.',
+'protect-norestrictiontypes-title' => 'Kaca sing ora bisa diproteksi',
 'protect-legend' => 'Konfirmasi pangreksan',
 'protectcomment' => 'Alesan:',
 'protectexpiry' => 'Kadaluwarsa:',
@@ -2148,8 +2213,8 @@ Ing ngisor iki kapacak konfigurasi kanggo kaca '''$1''':",
 'undeletepagetext' => '{{PLURAL:$1|kaca iki wis dibusak nanging isih|$1 kaca iki wis dibusak nanging isih}} ana ing arsip lan bisa dibalèkaké.
 Arsip bisa diresiki sakala-kala.',
 'undelete-fieldset-title' => 'Mulihaké rèvisi',
-'undeleteextrahelp' => "Kanggo mbalèkaké kabèh sajarah kaca, kothongaké kabèh kothak-cèk lan klik '''''Balèkna'''''.
-Kanggo nglakoni pambalèkan pinilih, conthèngen kothak-cèk  sing magepokan karo révisi sing dipéngini lan klik '''''Balèkna'''''.
+'undeleteextrahelp' => "Kanggo mbalèkaké kabèh sajarah kaca, kothongaké kabèh kothak-cèk lan klik '''''{{int:undeletebtn}}'''''.
+Kanggo nglakoni pambalèkan pinilih, conthèngen kothak-cèk  sing magepokan karo révisi sing dipéngini lan klik '''''{{int:undeletebtn}}'''''.
 Mencèt tombol '''''Reset''''' bakal ngosongaké isi komentar lan kabèh kothak-cèk.",
 'undeleterevisions' => '$1 {{PLURAL:$1|révisi|révisi}} diarsipaké',
 'undeletehistory' => 'Yèn panjenengan mbalèkaké kaca, kabèh révisi bakal dibalèkaké jroning sajarah.
@@ -2173,7 +2238,7 @@ Panjenengan mbokmenawa ngetutaké pranala sing salah, utawa revisi iku wis dipul
 'undeletedrevisions-files' => '$1 {{PLURAL:$1|révisi|révisi}} lan $2 berkas dibalèkaké',
 'undeletedfiles' => '$1 {{PLURAL:$1|berkas|berkas}} dibalèkaké',
 'cannotundelete' => 'Olèhé mbatalaké pambusakan gagal;
-mbokmenawa wis ana wong liya sing luwih dhisik nglakoni pambatalan.',
+$1',
 'undeletedpage' => "'''$1 bisa dibalèkaké'''
 
 Delengen [[Special:Log/delete|log pambusakan]] kanggo data pambusakan lan pambalèkan.",
@@ -2205,7 +2270,7 @@ $1',
 'blanknamespace' => '(Utama)',
 
 # Contributions
-'contributions' => 'Sumbangan panganggo',
+'contributions' => 'Sumbangan {{GENDER:$1|panganggo}}',
 'contributions-title' => 'Kontribusi panganggo kanggo $1',
 'mycontris' => 'Kontribusi',
 'contribsub2' => 'Kanggo $1 ($2)',
@@ -2344,7 +2409,7 @@ Log brèdèlan sumadhiya nèng ngisor kanggo rujukan:',
 'reblock-logentry' => 'Ngowahi sèting pamblokiran [[$1]] kanthi wektu daluwarsa $2 $3',
 'blocklogtext' => 'Ing ngisor iki kapacak log pamblokiran lan panjabelan blokir panganggo.
 Alamat IP sing diblokir sacara otomatis ora ana ing daftar iki.
-Mangga mirsani [[Special:BlockList|daftar alamat IP sing diblokir]] kanggo daftar blokir pungkasan.',
+Mangga mirsani [[Special:BlockList|daftar panganggo sing diblokir]] kanggo daftar blokir pungkasan.',
 'unblocklogentry' => 'njabel blokir "$1"',
 'block-log-flags-anononly' => 'namung panganggo anonim waé',
 'block-log-flags-nocreate' => 'opsi nggawé akun utawa rékening dipatèni',
@@ -2409,6 +2474,17 @@ Gatèkna yèn kaca iki '''ora''' bakal dipindhah yèn wis ana kaca liyané sing
 '''PÈNGET!'''
 Perkara iki bisa ngakibataké owah-owahan sing drastis lan ora kaduga kanggo kaca-kaca sing populèr;
 pastekaké dhisik panjenengan ngerti konsekwènsi saka panggayuh panjenengan sadurungé dibanjuraké.",
+'movepagetext-noredirectfixer' => "Formulir di bawah ini digunakan untuk mengubah nama suatu halaman dan memindahkan semua data sejarah ke nama baru.
+Judul yang lama akan menjadi halaman peralihan menuju judul yang baru.
+Pastikan untuk memeriksa pengalihan [[Special:DoubleRedirects|ganda]] atau [[Special:BrokenRedirects|rusak]].
+Anda bertanggung jawab untuk memastikan bahwa pranala terus menyambung ke halaman yang seharusnya.
+
+Perhatikan bahwa halaman '''tidak''' akan dipindah apabila telah ada halaman yang menggunakan judul yang baru, kecuali bila halaman tersebut kosong atau merupakan halaman peralihan dan tidak mempunyai sejarah penyuntingan.
+Ini berarti Anda dapat mengubah nama halaman kembali seperti semula apabila Anda membuat kesalahan, dan Anda tidak dapat menimpa halaman yang telah ada.
+
+'''Peringatan:'''
+Hal ini dapat mengakibatkan perubahan yang tak terduga dan drastis bagi halaman yang populer;
+Pastikan Anda mengerti konsekuensi dari perbuatan ini sebelum melanjutkan.",
 'movepagetalktext' => "Kaca dhiskusi sing kagandhèng uga bakal dipindhahaké sacara otomatis '''kejaba yèn:'''
 
 *Sawijining kaca dhiskusi sing ora kosong wis ana sangisoring irah-irahan (judhul) anyar, utawa
@@ -2461,6 +2537,7 @@ Apa panjenengan kersa mbusak iku supaya kacané bisa dialihaké?',
 'immobile-target-namespace-iw' => 'Pranala interwiki dudu target sing sah kanggo pamindhahan kaca.',
 'immobile-source-page' => 'Kaca iki ora bisa dipindhahaké.',
 'immobile-target-page' => 'Ora bisa mindhahaké menyang irah-irahan tujuan kasebut.',
+'bad-target-model' => 'Halaman yang dituju menggunakan model isi yang berbeda. Tidak dapat mengonversi $1 ke $2.',
 'imagenocrossnamespace' => 'Ora bisa mindhahaké gambar menyang bilik nama non-gambar',
 'nonfile-cannot-move-to-file' => 'Ora bisa mindhahaké non-berkas nèng bilik jeneng berkas',
 'imagetypemismatch' => 'Èkstènsi anyar berkas ora cocog karo jenisé',
@@ -2539,6 +2616,7 @@ Kabèh aktivitas impor transwiki bakal dilog ing [[Special:Log/import|log impor]
 'import-interwiki-templates' => 'Katutna kabèh cithakan',
 'import-interwiki-submit' => 'Impor',
 'import-interwiki-namespace' => 'Bilik jeneng tujuan:',
+'import-interwiki-rootpage' => 'Halaman turunan tujuan (opsional):',
 'import-upload-filename' => 'Jeneng berkas:',
 'import-comment' => 'Komentar:',
 'importtext' => 'Mangga èkspor berkas saka wiki sumber nganggo [[Special:Export|prangkat èkspor]].
@@ -2571,6 +2649,10 @@ Simpen nèng komputer Sampéyan lan unggaha nèng kéné.',
 'import-error-interwiki' => 'Kaca "$1" ora diimpor amarga jenengé dicadhangaké kango pranala njaba (interwiki).',
 'import-error-special' => 'Kaca "$1" ora diimpor amarga kuwi kalebu nèng bilik jeneng kusus sing ora nglilakaké anané kaca.',
 'import-error-invalid' => 'Kaca "$1" ora diimpor amarga jenengé ora sah.',
+'import-error-unserialize' => 'Revisi $2 dari halaman "$1" tidak dapat di-\'\'unserialized\'\'. Revisi tersebut dilaporkan menggunakan model konten $3 diserialisasi sebagai $4.',
+'import-options-wrong' => '{{PLURAL:$2|Opsi|Opsi}} salah: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'Halaman turunan yang diberikan adalah judul yang salah.',
+'import-rootpage-nosubpage' => 'Ruang nama "$1" di halaman turunan tidak mengizinkan subhalaman.',
 
 # Import log
 'importlogpage' => 'Log impor',
@@ -2686,9 +2768,27 @@ Mbokmanawa iki disebabaké anané pranala jaba sing klebu daftar ireng.',
 
 # Info page
 'pageinfo-title' => 'Inpormasi kanggo "$1"',
+'pageinfo-not-current' => 'Maaf, tidak mungkin memberikan informasi ini ke revisi lama.',
+'pageinfo-header-basic' => 'Informasi dhasar',
 'pageinfo-header-edits' => 'Riwayat suntingan',
+'pageinfo-header-restrictions' => 'Perlindungan halaman',
+'pageinfo-header-properties' => 'Properti kaca',
+'pageinfo-display-title' => 'Judul tampilan',
+'pageinfo-default-sort' => 'Kunci urut baku',
+'pageinfo-length' => 'Panjang halaman (dalam bita)',
+'pageinfo-article-id' => 'ID kaca',
+'pageinfo-language' => 'Bahasa isi halaman',
+'pageinfo-robot-policy' => 'Status mesin pencari',
+'pageinfo-robot-index' => 'Dapat diindeks',
+'pageinfo-robot-noindex' => 'Tidak dapat diindeks',
 'pageinfo-views' => 'Cacahing delokan',
 'pageinfo-watchers' => 'Cacahé pangawas kaca',
+'pageinfo-redirects-name' => 'Pengalihan ke halaman ini',
+'pageinfo-subpages-name' => 'Subhalaman halaman ini',
+'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|pengalihan|pengalihan}}; $3 {{PLURAL:$3|non-pengalihan|non-pengalihan}})',
+'pageinfo-firstuser' => 'Pembuat halaman',
+'pageinfo-firsttime' => 'Tanggal pembuatan halaman',
+'pageinfo-lastuser' => 'Penyunting terakhir',
 'pageinfo-lasttime' => 'Tanggal suntingan pungkasan',
 'pageinfo-edits' => 'Cacahé kabèh suntingan',
 'pageinfo-authors' => 'Cacahé kabèh panganggit sing bédha-bédha.',
@@ -2696,12 +2796,20 @@ Mbokmanawa iki disebabaké anané pranala jaba sing klebu daftar ireng.',
 'pageinfo-recent-authors' => 'Cacahé panganggit sing bédha-bédha saiki',
 'pageinfo-magic-words' => '{{PLURAL:$1|Tembung|Tembung}} mujarab ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Katégori|Katégori}} kadhelikaké ($1)',
+'pageinfo-templates' => '{{PLURAL:$1|Templat|Templat}} yang ditransklusi ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Kaca|Kaca}} sing ditransklusi ing ($1)',
 'pageinfo-toolboxlink' => 'Informasi kaca',
 'pageinfo-redirectsto' => 'Dialihaké dhateng',
 'pageinfo-redirectsto-info' => 'info',
 'pageinfo-contentpage' => 'Diétung minangka satunggaling kaca isi',
 'pageinfo-contentpage-yes' => 'Iya',
+'pageinfo-protect-cascading' => 'Proteksi runtun',
 'pageinfo-protect-cascading-yes' => 'Iya',
+'pageinfo-protect-cascading-from' => 'Proteksi runtun saking',
+'pageinfo-category-info' => 'Informasi kategori',
+'pageinfo-category-pages' => 'Cacahing kaca',
+'pageinfo-category-subcats' => 'Jumlah subkategori',
+'pageinfo-category-files' => 'Cacahing gambar',
 
 # Patrolling
 'markaspatrolleddiff' => 'Tandhanana wis dipatroli',
@@ -2713,6 +2821,8 @@ Mbokmanawa iki disebabaké anané pranala jaba sing klebu daftar ireng.',
 'markedaspatrollederror' => 'Ora bisa awèh tandha wis dipatroli',
 'markedaspatrollederrortext' => 'Panjenengan kudu nentokaké sawijining révisi kanggo ditandhani minangka sing dipatroli.',
 'markedaspatrollederror-noautopatrol' => 'Panjenengan ora pareng nandhani suntingan panjenengan dhéwé minangka dipatroli.',
+'markedaspatrollednotify' => 'Perubahan $1 telah dipatroli.',
+'markedaspatrollederrornotify' => 'Penanda patroli gagal dibuat.',
 
 # Patrol log
 'patrol-log-page' => 'Log patroli',
@@ -2745,6 +2855,8 @@ Yèn dilakokaké, sistem Sampéyan bisa kaserang.",
 'file-info-size-pages' => '$1 × $2 piksel, gedhéné berkas: $3, jinisé MIME: $4, $5 {{PLURAL:$5|kaca|kaca}}',
 'file-nohires' => 'Ora ana résolusi sing luwih dhuwur.',
 'svg-long-desc' => 'Berkas SVG, nominal $1 × $2 piksel, gedhené berkas: $3',
+'svg-long-desc-animated' => 'Berkas SVG, nominal $1 × $2 piksel, gedhené berkas: $3',
+'svg-long-error' => 'Berkas SVG ora sah: $1',
 'show-big-image' => 'Résolusi kebak',
 'show-big-image-preview' => 'Gedhéné pratayang iki: $1',
 'show-big-image-other' => '{{PLURAL:$2|Résolusi|Résolusi}} liya: $1.',
@@ -2754,6 +2866,8 @@ Yèn dilakokaké, sistem Sampéyan bisa kaserang.",
 'file-info-png-looped' => 'mubeng',
 'file-info-png-repeat' => 'diputer {{PLURAL:$1|ping|ping}} $1',
 'file-info-png-frames' => '$1 {{PLURAL:$1|rangka|rangka}}',
+'file-no-thumb-animation' => "'''Catatan: Karena keterbatasan teknis, cuplikan berkas ini tidak akan teranimasikan.'''",
+'file-no-thumb-animation-gif' => "'''Catatan: Karena keterbatasan teknis, cuplikan gambar GIF beresolusi tinggi seperti yang satu ini tidak akan teranimasikan.'''",
 
 # Special:NewFiles
 'newimages' => 'Galeri berkas anyar',
@@ -2772,7 +2886,10 @@ Yèn dilakokaké, sistem Sampéyan bisa kaserang.",
 'minutes' => '{{PLURAL:$1|$1 menit|$1 menit}}',
 'hours' => '{{PLURAL:$1|$1 jam|$1 jam}}',
 'days' => '{{PLURAL:$1|$1 dina|$1 dina}}',
+'months' => '{{PLURAL:$1|$1 sasi|$1 sasi}}',
+'years' => '{{PLURAL:$1|$1 taun|$1 taun}}',
 'ago' => '$1 kapungkur',
+'just-now' => 'baru saja',
 
 # Bad image list
 'bad_image_list' => "Formaté kaya mengkéné:
@@ -2980,6 +3097,9 @@ Pranala-pranala sabanjuré ing baris sing padha dianggep minangka ''pengecualian
 
 # EXIF attributes
 'exif-compression-1' => 'Ora dikomprèsi',
+'exif-compression-2' => 'CCITT Group 3 1-Dimensional Modified Huffman RLE',
+'exif-compression-3' => 'CCITT Group 3 fax encoding',
+'exif-compression-4' => 'CCITT Group 4 fax encoding',
 
 'exif-copyrighted-true' => 'Mawa hak cipta',
 'exif-copyrighted-false' => 'Domain umum',
@@ -3148,6 +3268,7 @@ Pranala-pranala sabanjuré ing baris sing padha dianggep minangka ''pengecualian
 'exif-gpsdirection-m' => 'Arah magnètis',
 
 'exif-ycbcrpositioning-1' => 'Kapusat',
+'exif-ycbcrpositioning-2' => 'Atas (co-sited)',
 
 'exif-dc-contributor' => 'Kontributor',
 'exif-dc-coverage' => 'Cakepan latar utawa wektu média',
@@ -3226,6 +3347,24 @@ Yèn panjenengan *ora tau* ndaftar akun iki, tutna pranala ing ngisor iki kanggo
 
 $5
 
+Konfirmasi iki bakal kadaluwarsa ing $4.',
+'confirmemail_body_changed' => 'Sawijining wong, mbokmenawa panjenengan dhéwé, saka alamat IP $1, wis ndaftaraké akun "$2" mawa alamat e-mail iki ing {{SITENAME}}. Bukaka pranala iki ing panjlajah wèb panjenengan.
+
+$3
+
+Yèn panjenengan *ora tau* ndaftar akun iki, tutna pranala ing ngisor iki kanggo mbatalaké konfirmasi alamat e-mail:
+
+$5
+
+Konfirmasi iki bakal kadaluwarsa ing $4.',
+'confirmemail_body_set' => 'Sawijining wong, mbokmenawa panjenengan dhéwé, saka alamat IP $1, wis ndaftaraké akun "$2" mawa alamat e-mail iki ing {{SITENAME}}. Bukaka pranala iki ing panjlajah wèb panjenengan.
+
+$3
+
+Yèn panjenengan *ora tau* ndaftar akun iki, tutna pranala ing ngisor iki kanggo mbatalaké konfirmasi alamat e-mail:
+
+$5
+
 Konfirmasi iki bakal kadaluwarsa ing $4.',
 'confirmemail_invalidated' => 'Pandhedhesan (konfirmasi) alamat e-mail batal',
 'invalidateemail' => 'Batalna pandhedhesan (konfirmasi) e-mail',
@@ -3233,6 +3372,7 @@ Konfirmasi iki bakal kadaluwarsa ing $4.',
 # Scary transclusion
 'scarytranscludedisabled' => '[Transklusi cithakan interwiki dipatèni]',
 'scarytranscludefailed' => '[Olèhé njupuk cithakan $1 gagal]',
+'scarytranscludefailed-httpstatus' => '[Pengambilan templat $1 gagal: HTTP $2]',
 'scarytranscludetoolong' => '[URL-é kedawan]',
 
 # Delete conflict
@@ -3342,6 +3482,12 @@ Panjenengan uga bisa [[Special:EditWatchlist|nganggo éditor standar panjenengan
 'version-license' => 'Lisènsi',
 'version-poweredby-credits' => "Wiki iki disengkuyung déning '''[//www.mediawiki.org/ MediaWiki]''', hak cipta © 2001-$1 $2.",
 'version-poweredby-others' => 'liyané',
+'version-credits-summary' => 'Kami ingin mengakui orang-orang berikut atas kontribusinya terhadap [[Special:Version|MediaWiki]].',
+'version-license-info' => 'MediaWiki adalah perangkat lunak bebas; Anda diperbolehkan untuk mendistribusikan dan/atau memodfikasinya dengan persyaratan Lisensi Publik Umum GNU yang diterbitkan oleh Free Software Foundation; versi 2 atau terbaru.
+
+MediaWiki didistribusikan dengan harapan dapat digunakan, tetapi TANPA JAMINAN APA PUN; tanpa jaminan PERDAGANGAN atau KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat Lisensi Publik Umum GNU untuk informasi lebih lanjut.
+
+Anda seharusnya telah menerima [{{SERVER}}{{SCRIPTPATH}}/COPYING salinan Lisensi Publik Umum GNU] bersama dengan program ini; jika tidak, kirim surat ke Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA atau [//www.gnu.org/licenses/old-licenses/gpl-2.0.html baca daring].',
 'version-software' => "''Software'' wis diinstalasi",
 'version-software-product' => 'Prodhuk',
 'version-software-version' => 'Vèrsi',
@@ -3477,8 +3623,11 @@ Gambar dituduhaké mawa résolusi kebak lan tipe liyané berkas bakal dibuka lan
 'logentry-newusers-newusers' => 'Akun panganggo $1 digawé',
 'logentry-newusers-create' => 'Akun panganggo $1 digawé',
 'logentry-newusers-create2' => 'Akun panganggo $3 digawé déning $1',
+'logentry-newusers-byemail' => 'Akun pengguna $3 dibuat oleh $1 dan kata sandi dikirim melalui e-mail',
 'logentry-newusers-autocreate' => 'Akun $1 digawé otomatis',
-'newuserlog-byemail' => 'tembung sandhi wis dikirim liwat e-mail',
+'logentry-rights-rights' => 'ngganti kaanggotan kelompok kanggo $3 saka $4 dadi $5',
+'logentry-rights-rights-legacy' => '$1 mengubah keanggotaan grup $3',
+'logentry-rights-autopromote' => 'otomatis ditawakaké saka $4 nèng $5',
 'rightsnone' => '(ora ana)',
 
 # Feedback
@@ -3533,6 +3682,7 @@ Utawa, Sampéyan bisa nganggo pormulir gampang ngisor. Tanggepan Sampéyan bakal
 'api-error-ok-but-empty' => 'Kasalahan njero: Ora ana tanggepan saka sasana.',
 'api-error-overwrite' => 'Nibani berkas sing wis ana ora dililakaké.',
 'api-error-stashfailed' => 'Kasalahan njero: Sasana gagal nyèlèhaké berkas sawetara.',
+'api-error-publishfailed' => 'Kasalahan njero: Sasana gagal nyèlèhaké berkas sawetara.',
 'api-error-timeout' => 'Sasana ora nanggepi nèng wektu sing karepaké.',
 'api-error-unclassified' => 'Ana masalah sing ora dingertèni.',
 'api-error-unknown-code' => 'Kasalahan ora dingertèni: "$1".',
index 4f673ff..97bb77b 100644 (file)
@@ -211,6 +211,7 @@ $messages = array(
 'tog-ccmeonemails' => 'გამომიგზავნე ელფოსტების ასლები, რომლებსაც მე სხვა მომხმარებლებს ვუგზავნი',
 'tog-diffonly' => 'დამალე გვერდის შიგთავსი ცვლილების ქვევით',
 'tog-showhiddencats' => 'დამალული კატეგორიების ჩვენება',
+'tog-noconvertlink' => 'სათაურის გარდაქმნის ბმულის გამორთვა',
 'tog-norollbackdiff' => 'გამოტოვეთ ცვლილება გაუქმებისას',
 
 'underline-always' => 'მუდამ',
@@ -218,7 +219,7 @@ $messages = array(
 'underline-default' => 'დამოკიდებული მომხმარებელზე ან ბრაუზერის არჩევანზე',
 
 # Font style option in Special:Preferences
-'editfont-style' => 'რედაქტირების არის შრიფტის ტიპი:',
+'editfont-style' => 'á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\91á\83\98á\83¡ á\83\90á\83 á\83\94á\83\90á\83\9aá\83\98á\83¡ á\83¨á\83 á\83\98á\83¤á\83¢á\83\98á\83¡ á\83¢á\83\98á\83\9eá\83\98:',
 'editfont-default' => 'ბრაუზერის უპირობო არჩევანი',
 'editfont-monospace' => 'მონოშირული შრიფტი',
 'editfont-sansserif' => 'შრიფტი სანს-სერიფი',
@@ -612,7 +613,7 @@ $2',
 'gotaccount' => "უკვე რეგისტრირებული ხართ? '''$1'''",
 'gotaccountlink' => 'შესვლა',
 'userlogin-resetlink' => 'ავტორიზაციის მონაცემები დაგავიწყდათ?',
-'createaccountmail' => 'á\83\94á\83\9a\83¤á\83\9dá\83¡á\83¢á\83\98á\83\97',
+'createaccountmail' => 'á\83\92á\83\90á\83\9bá\83\9dá\83\98á\83§á\83\94á\83\9cá\83\94á\83\97 á\83¨á\83\94á\83\9bá\83\97á\83®á\83\95á\83\94á\83\95á\83\98á\83\97á\83\9dá\83\91á\83\98á\83¡ á\83\9bá\83\94á\83\97á\83\9dá\83\93á\83\98á\83\97 á\83¨á\83\94á\83 á\83©á\83\94á\83£á\83\9aá\83\98 á\83\93á\83 á\83\9dá\83\94á\83\91á\83\98á\83\97á\83\98 á\83\9eá\83\90á\83 á\83\9dá\83\9aá\83\98 á\83\93á\83\90 á\83\9bá\83\98á\83¡á\83\98 á\83\92á\83\90á\83\92á\83\96á\83\90á\83\95á\83\9cá\83\90 á\83¥á\83\95á\83\94á\83\9bá\83\9dá\83\97 á\83\9bá\83\98á\83\97á\83\98á\83\97á\83\94á\83\91á\83£á\83\9a á\83\94á\83\9a. á\83¤á\83\9dá\83¡á\83¢á\83\98á\83¡ á\83\9bá\83\98á\83¡á\83\90á\83\9bá\83\90á\83 á\83\97á\83\96á\83\94:',
 'createaccountreason' => 'მიზეზი:',
 'badretype' => 'თქვენს მიერ შეყვანილი პაროლები ერთმანეთს არ ემთხვევა.',
 'userexists' => 'ეს სახელი უკვე გამოყენებულია.
@@ -688,6 +689,7 @@ $1 საათში.',
 # E-mail sending
 'php-mail-error-unknown' => 'ამოუცნობი შეცდომა PHP-ის mail() ფუნქციაში',
 'user-mail-no-addy' => 'ცდილობდა ელ-ფოსტის გაგზავნას ელ-ფოსტის მისამართის გარეშე.',
+'user-mail-no-body' => 'ცდილობდა ცარიელი ან უაზროდ მოკლე შინაარსის ელექტრონული წერილის გაგზავნას.',
 
 # Change password dialog
 'resetpass' => 'შეცვალეთ პაროლი',
@@ -1226,7 +1228,7 @@ $1",
 'search-interwiki-default' => 'შედეგები $1-დან:',
 'search-interwiki-more' => '(გაგრძელება)',
 'search-relatedarticle' => 'დაკავშირებული',
-'mwsuggest-disable' => 'გათიშეთ AJAX დახმარებები',
+'mwsuggest-disable' => 'გათიშეთ ძიების შეთავაზებები',
 'searcheverything-enable' => 'ძიება სახელთა ყველა სივრცეებში',
 'searchrelated' => 'მიბმული',
 'searchall' => 'ყველა',
@@ -1302,7 +1304,7 @@ $1",
 'prefs-help-watchlist-token' => 'ამ ველის შევსება საიდუმლო გასაღებით შექმნის RSS ტრანსლაციას თქვენი კონტროლის სიისთვის.
 ყველა, ვინც იცის გასაღები, შესძლებს იხილოს თქვენი კონტროლის სია. ფრთხილად იყავით საიდუმლო მნიშვნელობის არჩევისას.
 თქვენ შეგიძლიათ გამოიყენოთ ასევე შემთვევითი მნიშვნელობა: $1',
-'savedprefs' => 'თქვენ მიერ შერჩეული პარამეტრები დამახსოვრებულია.',
+'savedprefs' => 'თქვენ მიერ შერჩეული პარამეტრები დამახსოვრებულია.',
 'timezonelegend' => 'სასაათო სარტყელი:',
 'localtime' => 'ადგილობრივი დრო:',
 'timezoneuseserverdefault' => 'გამოიყენე ნაგულისხმევი პარამეტრები ($1)',
@@ -1381,18 +1383,19 @@ $1",
 # User rights
 'userrights' => 'მომხმარებელთა უფლებების მართვა',
 'userrights-lookup-user' => 'მომხმარებელთა ჯგუფების მართვა',
-'userrights-user-editname' => 'á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83¡á\83\90á\83®á\83\94á\83\9aá\83\98á\83¡ á\83¨á\83\94á\83¢á\83\90á\83\9cá\83\90:',
+'userrights-user-editname' => 'á\83¨á\83\94á\83\98á\83¢á\83\90á\83\9cá\83\94á\83\97 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83¡á\83\90á\83®á\83\94á\83\9aá\83\98:',
 'editusergroup' => 'მომხმარებელთა ჯგუფების რედაქტირება',
-'editinguser' => "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83£á\83¤á\83\9aá\83\94á\83\91á\83\94á\83\91á\83\98á\83¡ á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\90 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡á\83\97á\83\95á\83\98á\83¡ '''[[User:$1|$1]]''' $2",
-'userrights-editusergroup' => 'á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\91á\83\90 á\83\92á\83\90á\83£á\83\99á\83\94á\83\97á\83\94á\83\97 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83¯á\83\92á\83£á\83¤á\83\94á\83\91á\83¡',
+'editinguser' => "á\83£á\83¤á\83\9aá\83\94á\83\91á\83\94á\83\91á\83\98á\83¡ á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\90 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡á\83\97á\83\95á\83\98á\83¡: '''[[User:$1|$1]]''' $2",
+'userrights-editusergroup' => 'á\83\93á\83\90á\83\90á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\97 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83¯á\83\92á\83£á\83¤á\83\94á\83\91á\83\98',
 'saveusergroups' => 'მომხმარებელთა ჯგუფების შენახვა',
 'userrights-groupsmember' => 'ჯგუფის წევრი:',
 'userrights-groupsmember-auto' => 'ნაგულისხმევი წევრი:',
+'userrights-groupsmember-type' => '$1',
 'userrights-groups-help' => 'თქვენ შეგიძლიათ შეცვალოთ ჯგუფები, რომელშიც შედის ეს მომხმარებელი.
 * თუ ჯგუფის სახელწოდებასთან გაკეთებულია ნიშნული, ე.ი მომხმარებელი შედის ამ ჯგუფში.
 * თუ ნიშნული არ არის – მომხმარებელი არ განეკუთვნება არსებულ ჯგუფს.
 * ნიშანი * ნიშნავს, რომ თქვენ არ შეგიძლიათ მომხმარებლის ჯგუფიდან წაშლა, თუ დაამატებთ მას იქ ან პირიქით.',
-'userrights-reason' => 'მიზეზი:',
+'userrights-reason' => 'á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\98á\83¡ á\83\9bá\83\98á\83\96á\83\94á\83\96á\83\98:',
 'userrights-no-interwiki' => 'თქვენ არ გაქვთ მომხმარებლის უფლებების რედაქტირების უფლება სხვა ვიკი-ებში.',
 'userrights-nodatabase' => 'მონაცემთა ბაზა $1 არ არსებობს, ან არ არის ლოკალური.',
 'userrights-nologin' => 'თქვენ უნდა [[Special:UserLogin|წარადგინოთ თავი სისტემისადმი]] ადმინისისტრატორის ანგარიშით იმისთვის, რომ გასცეთ მომხმარებელთა უფლებები.',
@@ -1942,7 +1945,7 @@ $1',
 'statistics-pages' => 'გვერდები',
 'statistics-pages-desc' => 'ვიკის ყველა გვერდი, განხილვის, გადამისამართების და სხვ. ჩათვლით.',
 'statistics-files' => 'ატვირთული ფაილები',
-'statistics-edits' => 'გვერდის შესწორებები {{SITENAME}}-ის შექმნიდან',
+'statistics-edits' => 'გვერდის შესწორებები პროექტის {{SITENAME}} შექმნის შემდეგ',
 'statistics-edits-average' => 'რედაქტირების საერთო რაოდენობა გვერდზე',
 'statistics-views-total' => 'სულ ხილვა',
 'statistics-views-total-desc' => 'სათვალავში არ მიიღება არარსებული და სამუშაო გვერდების გადახედვა',
@@ -2126,7 +2129,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'აქტიურ მომხმარებელთა სია',
 'activeusers-intro' => 'ეს არის მომხმარებელთა სია, რომელთაც აქვს წვლილი უკანასკნელი $1 {{PLURAL:$1|დღის|დღის}} განმავლობაში.',
-'activeusers-count' => '$1 {{PLURAL:$1|á\83ªá\83\95á\83\9aá\83\98á\83\9aá\83\94á\83\91á\83\90\83ªá\83\95á\83\9aá\83\98á\83\9aá\83\94á\83\91á\83\90}} {{PLURAL:$2|$3 á\83\93á\83¦á\83\94|$3 დღის}} განმავლობაში.',
+'activeusers-count' => '$1 {{PLURAL:$1|á\83\9bá\83\9dá\83¥á\83\9bá\83\94á\83\93á\83\94á\83\91á\83\90\83\9bá\83\9dá\83¥á\83\9bá\83\94á\83\93á\83\94á\83\91á\83\90}} {{PLURAL:$3|á\83\93á\83¦á\83\98á\83¡|$3 დღის}} განმავლობაში.',
 'activeusers-from' => 'მომხმარებელთა ჩვენება, დაწყებული:',
 'activeusers-hidebots' => 'რობოტების დამალვა',
 'activeusers-hidesysops' => 'ადმინისტრატორების დამალვა',
@@ -2174,8 +2177,8 @@ $1',
 'emailusername' => 'მომხმარებლის სახელი:',
 'emailusernamesubmit' => 'შენახვა',
 'email-legend' => 'წერილის გაგზავნა სხვა მომხმარებლისადმი {{grammar:genitive|{{SITENAME}}}}',
-'emailfrom' => 'á\83\92á\83\90á\83\9bá\83\9dá\83\9bá\83\92á\83\96á\83\90á\83\95á\83\9cá\83\98:',
-'emailto' => 'á\83\90á\83\93á\83 á\83\94á\83¡á\83\90á\83¢ი:',
+'emailfrom' => 'გამგზავნი:',
+'emailto' => 'á\83\9bá\83\98á\83\9bá\83¦á\83\94á\83\91ი:',
 'emailsubject' => 'თემა:',
 'emailmessage' => 'შეტყობინება:',
 'emailsend' => 'გაგზავნა',
@@ -2191,7 +2194,7 @@ $1',
 'usermessage-template' => 'MediaWiki:მომხმარებლის შეტყობინება',
 
 # Watchlist
-'watchlist' => 'á\83©á\83\94á\83\9bá\83\98 á\83\99á\83\9dá\83\9cá\83¢á\83 á\83\9dá\83\9aá\83\98á\83¡ á\83¡á\83\98á\83\90',
+'watchlist' => 'კონტროლის სია',
 'mywatchlist' => 'კონტროლის სია',
 'watchlistfor2' => '$1 ($2) თვის',
 'nowatchlist' => 'თქვენი კონტროლის სია ცარიელია.',
@@ -2342,6 +2345,8 @@ $UNWATCHURL
 'prot_1movedto2' => '[[$1]] გადატანილია გვერდზე [[$2]]',
 'protect-badnamespace-title' => 'დაუცველი სახელთა სივრცე',
 'protect-badnamespace-text' => 'ამ სახელთა სივრცის გვერდების დაცვა შეუძლებელია.',
+'protect-norestrictiontypes-text' => 'ამ გვერდის დაცვა შეუძლებელია, რადგან მისთვის არ არსებობს შესაბამისი დაცვის ტიპი.',
+'protect-norestrictiontypes-title' => 'დაუცველი გვერდი',
 'protect-legend' => 'დაცვის დადასტურება',
 'protectcomment' => 'მიზეზი:',
 'protectexpiry' => 'ვადა',
@@ -2358,8 +2363,9 @@ $UNWATCHURL
 თქვენ შეგიძლიათ ამ გვერდის დაცვის დონე შეცვალოთ, თუმცა ეს კასკადურ დაცვაზე გავლენას არ იქონიებს.',
 'protect-default' => 'ყველა მომხმარებელი',
 'protect-fallback' => 'ხელმისაწვდომია მხოლოდ „$1-ის“ უფლების მქონე მომხმარებლებისათვის',
-'protect-level-autoconfirmed' => 'á\83\90á\83®á\83\90á\83\9aá\83\98 á\83\93á\83\90 á\83\90á\83 á\83\90á\83 á\83\94á\83\92á\83\98á\83¡á\83¢á\83 á\83\98á\83 á\83\94á\83\91á\83£á\83\9aá\83\98 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\94á\83\91á\83\98á\83¡á\83\90á\83\92á\83\90á\83\9c á\83\93á\83\90á\83ªá\83\95á\83\90',
+'protect-level-autoconfirmed' => 'á\83®á\83\94á\83\9aá\83\9bá\83\98á\83¡á\83\90á\83¬á\83\95á\83\93á\83\9dá\83\9bá\83\98á\83\90 á\83\9bá\83®á\83\9dá\83\9aá\83\9dá\83\93 á\83\90á\83\95á\83¢á\83\9dá\83\9bá\83\90á\83¢á\83£á\83 á\83\90á\83\93 á\83\93á\83\90á\83\93á\83\90á\83¡á\83¢á\83£á\83 á\83\94á\83\91á\83£á\83\9aá\83\98 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\94á\83\91á\83\98á\83¡á\83\90á\83\97á\83\95á\83\98á\83¡',
 'protect-level-sysop' => 'მხოლოდ ადმინისტრატორები',
+'protect-summary-desc' => '[$1=$2] ($3)',
 'protect-summary-cascade' => 'იერარქიული',
 'protect-expiring' => 'ვადა გასდის: $1 (UTC)',
 'protect-expiring-local' => 'ვადის გასვლის თარიღია $1',
@@ -2653,11 +2659,18 @@ $1',
 # Move page
 'move-page' => '$1 — გადატანა',
 'move-page-legend' => 'გვერდის გადატანა',
-'movepagetext' => 'ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. ძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე. ბმულები ძველი გვერდის სათაურზე არ შეიცვლება; შეამოწმეთ ორმაგი ან გამწყდარი გადამისამართებები. თქვენ ხართ პასუხისმგებელი, რომ ბმულები მკითხველს დანიშნულებისამებრ მიიყვანს.
+'movepagetext' => "ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. 
+ძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე. 
+ბმულები ძველი გვერდის სათაურზე არ შეიცვლება; 
+შეამოწმეთ [[Special:DoubleRedirects|ორმაგი]] ან [[Special:BrokenRedirects|გამწყდარი გადამისამართებები]]. 
+თქვენ ხართ პასუხისმგებელი, რომ ბმულები მკითხველს დანიშნულებისამებრ მიიყვანს.
 
-გაითვალისწინეთ, რომ გვერდი არ გადავა, თუ ახალი სათაურით სტატია უკვე არსებობს, გარდა იმ შემთხვევისა, თუ ის ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. ეს ნიშნავს, რომ თქვენ შეგიძლიათ დაუბრუნოთ ძველი სახელი გვერდს, თუ შეცდომა დაუშვით, მაგრამ არ შეგიძლიათ ზემოთ გადააწეროთ არსებულ გვერდს.
+გაითვალისწინეთ, რომ გვერდი არ გადავა, თუ ახალი სათაურით სტატია უკვე არსებობს, გარდა იმ შემთხვევისა, როდესაც მსგავსი გვერდი ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. 
+ეს ნიშნავს, რომ თქვენ შეგიძლიათ დაუბრუნოთ ძველი სახელი გვერდს, თუ შეცდომა დაუშვით, მაგრამ არ შეგიძლიათ ზემოთ გადააწეროთ არსებულ გვერდს.
 
-<b>გაფრთხილებთ!</b> ამ მოქმედებამ შეიძლება მნიშვნელოვანი და მოულოდნელი ცვლილება გამოიწვის პოპულარულ გვერდზე; სანამ გააგრძელებდეთ, გთხოვთ დარწმუნდეთ, რომ თქვენ გესმით თქვენი ქმედების შედეგები.',
+'''ფრთხილად!'''
+ამ მოქმედებამ შეიძლება მნიშვნელოვანი და მოულოდნელი ცვლილება გამოიწვის პოპულარულ გვერდზე; 
+სანამ გააგრძელებდეთ, გთხოვთ დარწმუნდეთ, რომ თქვენ გესმით თქვენი ქმედების შედეგები.",
 'movepagetext-noredirectfixer' => "ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. 
 ძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე.
 შეამოწმეთ [[Special:DoubleRedirects|ორმაგი]] ან [[Special:BrokenRedirects|გამწყდარი]] გადამისამართებები. 
@@ -2829,6 +2842,7 @@ $1',
 'import-error-interwiki' => 'გვერდი „$1“ არ იქნა იმპორტირებული, რადგანაც მისი სახელი დარეგისტრირებულია გარე ბმულებისათვის (interwiki).',
 'import-error-special' => 'გვერდი „$1“ არ იქნა იმპორტირებული, რადგანაც ის განეკუთვნება განსაკუთრებულ სახელთა სივრცეს, რომელიც კრძალავს გვერდების შექმნას.',
 'import-error-invalid' => 'გვერდი "$1" იმპორტირება არ მოხდა მიუღებელი სახელის გამო.',
+'import-error-unserialize' => 'ვერსია $2 გვერდისათვის „$1“ არ შეიძლება იყოს სტრუქტურირებული (დესერიალიზებული). მიღებულია შეტყობინება, რომ ამ ვერსიაში გამოიყენება $3 შემცველი მოდელი, სერიალიზებული ფორმატში $4.',
 'import-options-wrong' => 'არასწორი {{PLURAL:$2|პარამეტრი|პარამეტრი}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'ძირეული გვერდის მითითებული სახელი არასწორია.',
 'import-rootpage-nosubpage' => 'სახელტა სივრცეში მითითებულ ძირეულ გვერდში „$1“ ქვეგვერდები დაუშვებელია.',
@@ -2981,6 +2995,7 @@ $1',
 'pageinfo-robot-noindex' => 'არ ინდექსირდება',
 'pageinfo-views' => 'ხილვების რაოდენობა',
 'pageinfo-watchers' => 'გვერდის დამკვირვებელთა რაოდენობა',
+'pageinfo-few-watchers' => 'სულ მცირე $1 {{PLURAL:$1|დამკვირვებელი|დამკვირვებელი}}',
 'pageinfo-redirects-name' => 'გადამისამართება ამ გვერდზე',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'ამ გვერდის ქვეგვერდები',
@@ -2996,6 +3011,7 @@ $1',
 'pageinfo-magic-words' => 'ჯადოსნური {{PLURAL:$1|სიტყვა|სიტყვა}} ($1)',
 'pageinfo-hidden-categories' => 'დამალული {{PLURAL:$1|კატეგორია|კატეგორია}} ($1)',
 'pageinfo-templates' => 'ინტეგრირებულია {{PLURAL:$1|თარგი|თარგი}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|ჩართული გვერდი|ჩართული გვერდი}} ($1)',
 'pageinfo-toolboxlink' => 'გვერდის ინფორმაცია',
 'pageinfo-redirectsto' => 'გადამისამართება',
 'pageinfo-redirectsto-info' => 'ინფორმაცია',
@@ -3004,6 +3020,10 @@ $1',
 'pageinfo-protect-cascading' => 'კასკადური დაცვა აქედან',
 'pageinfo-protect-cascading-yes' => 'დიახ',
 'pageinfo-protect-cascading-from' => 'კასკადური დაცვა',
+'pageinfo-category-info' => 'ინფორმაცია კატეგორიის შესახებ',
+'pageinfo-category-pages' => 'გვერდების რაოდენობა',
+'pageinfo-category-subcats' => 'ქვეკატეგორიების რაოდენობა',
+'pageinfo-category-files' => 'ფაილების რაოდენობა',
 
 # Skin names
 'skinname-standard' => 'კლასიკური',
@@ -3097,6 +3117,8 @@ $1',
 'minutes' => '$1 წუთის',
 'hours' => '$1 საათის',
 'days' => '$1 დღის',
+'months' => '{{PLURAL:$1|$1 თვე|$1 თვე}}',
+'years' => '{{PLURAL:$1|$1 წელი|$1 წელი}}',
 'ago' => '$1 წინ',
 'just-now' => 'ახლახანს',
 
@@ -3284,7 +3306,7 @@ $1',
 'exif-lens' => 'გამოყენებული ლინზა',
 'exif-serialnumber' => 'კამერის სერიული ნომერი',
 'exif-cameraownername' => 'კამერის მფლობელი',
-'exif-label' => 'á\83\98á\83\90á\83 á\83\9aá\83\98á\83§ი',
+'exif-label' => 'á\83¡á\83\90á\83®á\83\94á\83\9aი',
 'exif-datetimemetadata' => 'მეტამონაცემების ბოლო ცვლილების თარიღი',
 'exif-nickname' => 'სურათის არაფორმალური სახელი',
 'exif-rating' => 'რეიტინგი (5-დან)',
@@ -3829,7 +3851,7 @@ MediaWiki ვრცელდება იმ იმედით, რომ ი
 'specialpages-group-highuse' => 'ხშირად გამოყენებული გვერდები',
 'specialpages-group-pages' => 'გვერდების სიები',
 'specialpages-group-pagetools' => 'ინსტრუმენტები გვერდებისთვის',
-'specialpages-group-wiki' => 'á\83\95á\83\98á\83\99á\83\98\83\9bá\83\9dá\83\9cá\83\90á\83ªá\83\94á\83\9bá\83\94á\83\91á\83\98 á\83\93á\83\90 á\83\98á\83\9cá\83¡á\83¢á\83 á\83£á\83\9bá\83\94á\83\9cá\83¢á\83\94á\83\91á\83\98',
+'specialpages-group-wiki' => 'მონაცემები და ინსტრუმენტები',
 'specialpages-group-redirects' => 'სპეცგვერდების გადამისამართება',
 'specialpages-group-spam' => 'ინსტრუმენტები სპამის წინააღმდეგ',
 
@@ -3924,8 +3946,8 @@ MediaWiki ვრცელდება იმ იმედით, რომ ი
 'logentry-newusers-newusers' => 'მომხმარებლის ანგარიში $1 შექმნილია',
 'logentry-newusers-create' => 'შეიქმნა მომხმარებლის ანგარიში $1',
 'logentry-newusers-create2' => 'მომხმარებლის ანგარიში $3 შექმნა მომხმარებელმა $1',
+'logentry-newusers-byemail' => 'მომხმარებლის ანგარიში $3 შექმნა მომხმარებელმა $1 და პაროლი გაგზავნა ელ. ფოსტით',
 'logentry-newusers-autocreate' => 'ავტომატურად შეიქმნა მომხმარებლის ანგარიში $1',
-'newuserlog-byemail' => 'პაროლი ელ-ფოსტითაა გამოგზავნილი',
 'logentry-rights-rights' => '$1 შეცვალა ჯგუფის წევრობა $3-თვის $4-დან $5-ზე',
 'logentry-rights-rights-legacy' => '$1 შეცვალა ჯგუფის წევრობა $3-თვის',
 'logentry-rights-autopromote' => '$1 ავტომატურად იქნა გადაყვანილი $4–დან $5–ში',
@@ -3982,7 +4004,8 @@ MediaWiki ვრცელდება იმ იმედით, რომ ი
 'api-error-nomodule' => 'შიდა შეცდომა. ატვირთვის მოდული არ არის კონფიგურირებული.',
 'api-error-ok-but-empty' => 'შიდა შეცდომა. სერვერს არ დაუბრუნებია ინფორმაცია ატვირთვადი ფაილის შესახებ.',
 'api-error-overwrite' => 'არსებული ფაილის შეცვლა მიუღებელია.',
-'api-error-stashfailed' => 'შიდა შეცდომა. ვიკიმ ვერ შეძლო დროებით ფაილის შენახვა.',
+'api-error-stashfailed' => 'შიდა შეცდომა: სერვერმა ვერ შეძლო დროებითი ფაილის შენახვა.',
+'api-error-publishfailed' => 'შიდა შეცდომა: სერვერმა ვერ შეძლო დროებითი ფაილის შენახვა.',
 'api-error-timeout' => 'სერვერმა არ მოახდინა რეაგირება მოსალოდნელ დროში.',
 'api-error-unclassified' => 'აღმოჩენილია უცნობი შეცდომა.',
 'api-error-unknown-code' => 'უცნობი შეცდომა : „$1“',
index cbbb01f..7057d96 100644 (file)
@@ -1942,7 +1942,6 @@ Bul tastıyıqlaw kodının' pitetug'ın waqtı: $4.",
 # New logging system
 'revdelete-restricted' => "administratorlarg'a qollanılg'an sheklewler",
 'revdelete-unrestricted' => "administratorlardan alıp taslang'an sheklewler",
-'newuserlog-byemail' => 'parol e-mail arqalı jiberildi',
 'rightsnone' => '(hesh qanday)',
 
 );
index 7071b00..257e949 100644 (file)
 
 # $fallback = 'ru'; // bug 27785
 
+$namespaceNames = array(
+       NS_MEDIA            => 'Медиа',
+       NS_SPECIAL          => 'Служебная',
+       NS_TALK             => 'Тепсэлъэхьыгъуэ',
+       NS_USER             => 'ЦӀыхухэт',
+       NS_USER_TALK        => 'ЦӀыхухэт_тепсэлъэхьыгъуэ',
+       NS_PROJECT_TALK     => '$1_тепсэлъэхьыгъуэ',
+       NS_FILE             => 'Файл',
+       NS_FILE_TALK        => 'Файл_тепсэлъэхьыгъуэ',
+       NS_MEDIAWIKI        => 'MediaWiki',
+       NS_MEDIAWIKI_TALK   => 'MediaWiki_тепсэлъэхьыгъуэ',
+       NS_TEMPLATE         => 'Шаблон',
+       NS_TEMPLATE_TALK    => 'Шаблон_тепсэлъэхьыгъуэ',
+       NS_HELP             => 'ДэӀэпыкъуэгъуэ',
+       NS_HELP_TALK        => 'ДэӀэпыкъуэгъуэ_тепсэлъэхьыгъуэ',
+       NS_CATEGORY         => 'Категориэ',
+       NS_CATEGORY_TALK    => 'Категориэ_тепсэлъэхьыгъуэ',
+);
+
+$namespaceAliases = array(
+       # Russian namespaces
+       'Обсуждение'                         => NS_TALK,
+       'Участник'                           => NS_USER,
+       'Обсуждение_участника'               => NS_USER_TALK,
+       'Обсуждение_{{GRAMMAR:genitive|$1}}' => NS_PROJECT_TALK,
+       'Обсуждение_файла'                   => NS_FILE_TALK,
+       'Обсуждение_MediaWiki'               => NS_MEDIAWIKI_TALK,
+       'Обсуждение_шаблона'                 => NS_TEMPLATE_TALK,
+       'Справка'                            => NS_HELP,
+       'Обсуждение_справки'                 => NS_HELP_TALK,
+       'Категория'                          => NS_CATEGORY,
+       'Обсуждение_категории'               => NS_CATEGORY_TALK,
+);
+
+// Remove Russian gender aliases
+$namespaceGenderAliases = array();
+
 $messages = array(
 # User preference toggles
 'tog-underline' => 'ТехьэпӀэхэр щӀэтхъэн:',
index 0470242..6bb3162 100644 (file)
@@ -141,6 +141,7 @@ $messages = array(
 'index-category' => 'نو انڈیکس صفحات',
 'noindex-category' => 'نو انڈیکس صفحات',
 'broken-file-category' => 'نس پھت صفحات',
+'categoryviewer-pagedlinks' => '($1) ($2)',
 
 'about' => 'تعارف',
 'article' => 'صفحۂ مشمول',
@@ -269,6 +270,7 @@ $1',
 [[Special:Version|version page]]',
 
 'ok' => 'ٹھیک شیر',
+'pagetitle' => '$1 - {{SITENAME}}',
 'pagetitle-view-mainpage' => '{{SITENAME}}',
 'retrievedfrom' => '‘‘$1’’ نقل کاردو',
 'youhavenewmessages' => 'تہ بچے ای $1 شیر۔ ($2)',
@@ -276,6 +278,7 @@ $1',
 'newmessagesdifflink' => 'تـجـدیـد مـاقـبل آخـراری فـرق',
 'youhavenewmessagesmulti' => 'ء$1 تہ بچے نوغ نوغ پیغامات شینی',
 'editsection' => 'ترمیم',
+'editsection-brackets' => '[$1]',
 'editold' => 'ترمیم',
 'viewsourceold' => 'مآخذو لوڑے',
 'editlink' => 'تدوین کورے',
@@ -293,6 +296,8 @@ $1',
 'site-atom-feed' => '$1 اٹوم فیڈ',
 'page-rss-feed' => '$1 آر ایس ایس فیڈ',
 'page-atom-feed' => '$1 آٹوم فیڈ',
+'feed-atom' => 'اٹوم',
+'feed-rss' => 'آر ایس ایس',
 'red-link-title' => '
 $1 (صفحہ موجود نیکی)',
 
@@ -606,6 +611,9 @@ MySQL جوابِ خطاء پرائے "$3: $4"',
 'revdel-restore-deleted' => 'حذف شدہ رویژنز',
 'revdel-restore-visible' => 'ویزیبل رویژنز',
 
+# History merging
+'mergehistory-revisionrow' => '$1 ($2) $3 . . $4 $5 $6',
+
 # Merge log
 'revertmerge' => 'غیر ضم',
 
@@ -672,6 +680,7 @@ MySQL جوابِ خطاء پرائے "$3: $4"',
 'username' => 'ممبارو نم',
 'uid' => 'ممبارو لمبار:',
 'prefs-memberingroups' => '{{PLURAL:$1|گروہ|گروہاں}} رُکن:',
+'prefs-registration-date-time' => '$1',
 'yourrealname' => '* اصلی نم',
 'yournick' => 'دسخط',
 'badsig' => "ناقص خام دسخط.
index f253611..0c50033 100644 (file)
@@ -185,7 +185,7 @@ $messages = array(
 'about' => 'Heqa',
 'article' => 'Pela tedeesteyu',
 'newwindow' => '(zerrê pençerê dê newey de beno ra)',
-'cancel' => 'Texelnaene',
+'cancel' => 'Bıtexelne',
 'moredotdotdot' => 'Jêde...',
 'mypage' => 'Pela mı',
 'mytalk' => 'Hurênayişê mı',
@@ -674,7 +674,7 @@ Beno ke [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log
 Sıma be idarekerênia ho ra şikinê hona [$1 nê ferqi bıvênê], eke wazenê dewam kerê.",
 'rev-delundel' => 'bıasne/wedare',
 'rev-showdeleted' => 'bıasne',
-'revisiondelete' => 'Çımraviarnaisu bıestere/peyser bia',
+'revisiondelete' => 'Çımraviarnaisu bestere/peyser bia',
 'revdelete-nooldid-title' => 'Çımraviarnaena waştiye nêvêrena',
 'revdelete-nooldid-text' => 'Sıma vırastena nê fonksiyoni rê ya jü çımraviarnaena waştiye diyar nêkerdo, çımraviarnaena diyarkerdiye çına, ya ki sıma wazenê ke çımraviarnaena nıkaêne bınımnê.',
 'revdelete-nologtype-title' => 'Qet qeydê cı nêdiya',
@@ -902,7 +902,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'right-move' => 'Pelu bere',
 'right-movefile' => 'Dosyu bere',
 'right-upload' => 'Dosyu bar ke',
-'right-delete' => 'Pelu bıestere',
+'right-delete' => 'Pelu bestere',
 'right-undelete' => 'Esterıtena na pele peyser bıcê',
 
 # Special:Log/newusers
@@ -921,7 +921,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'action-move' => 'na pele bere',
 'action-movefile' => 'na dosya bere',
 'action-upload' => 'na dosya bar ke',
-'action-delete' => 'na pele bıestere',
+'action-delete' => 'na pele bestere',
 'action-undelete' => 'na pele meestere',
 
 # Recent changes
@@ -990,7 +990,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'watchthisupload' => 'Na dosya de şêr ke',
 
 'license' => 'Lisans:',
-'license-header' => 'Lisanskerdene',
+'license-header' => 'Lisansdais',
 
 # Special:ListFiles
 'imgfile' => 'dosya',
@@ -1007,7 +1007,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'file-anchor-link' => 'Dosya',
 'filehist' => 'Tarixê dosya',
 'filehist-help' => "Serba diyaena viartê dosya tarixê ke qısımê tarix/zeman'i derê inu bıteqne.",
-'filehist-deleteall' => 'Pêrune bıestere',
+'filehist-deleteall' => 'Pêrune bestere',
 'filehist-deleteone' => 'bestere',
 'filehist-revert' => 'raçarne',
 'filehist-current' => 'nıkaên',
@@ -1036,8 +1036,8 @@ Cêr [$2 pela arezekerdena dosya de] arezekerdene asnina.',
 'filerevert-submit' => 'Raçarne',
 
 # File deletion
-'filedelete' => 'Bıestere $1',
-'filedelete-legend' => 'Dosya bıestere',
+'filedelete' => 'Bestere $1',
+'filedelete-legend' => 'Dosya bestere',
 'filedelete-comment' => 'Sebeb:',
 'filedelete-submit' => 'Bestere',
 'filedelete-otherreason' => 'Sebebo bin/ilaweki:',
@@ -1168,7 +1168,7 @@ Nara dıme, vurnaisê na pele u pela hurênaisê dawa alaqedare ita bena lista,
 'changed' => 'vuriya',
 
 # Delete
-'deletepage' => 'Pele bıestere',
+'deletepage' => 'Pele bestere',
 'delete-legend' => 'Bestere',
 'confirmdeletetext' => 'Tı hawo kena ke jü pele be tarixê dae pêro bıne ra bıesterê.
 Eke ferqê neticê na kerdene de bena u no kar be gorê [[{{MediaWiki:Policy-url}}|qeydunê esterıtene]] beno, wa gurêy tesdiq ke.',
@@ -1398,7 +1398,7 @@ Kerem ke, qeydkerdene ra ver gozaga verqayti bıgurene.',
 Tı şikina çımunê dae bıvênê',
 'tooltip-ca-history' => 'Versiyonê verênê na pele',
 'tooltip-ca-protect' => 'Na pele bısevekne',
-'tooltip-ca-delete' => 'Na pele bıestere',
+'tooltip-ca-delete' => 'Na pele bestere',
 'tooltip-ca-move' => 'Namê na pele bıvurne',
 'tooltip-ca-watch' => 'Na pele bıcê lista huya şêrkerdene',
 'tooltip-ca-unwatch' => 'Na pele lista huya şêrkerdene ra wedare',
index b015c83..e090991 100644 (file)
@@ -3180,7 +3180,6 @@ $5
 'logentry-newusers-create' => '$1 жаңадан аккаунт тіркеді',
 'logentry-newusers-create2' => '$1 $3 деген аккаунт тіркеді',
 'logentry-newusers-autocreate' => '$1 аккаунты автоматты түрде тіркелді',
-'newuserlog-byemail' => 'Құпия сөз e-mail арқылы жіберілді',
 'rightsnone' => '(ешқандай)',
 
 # Search suggestions
index d33d200..077d775 100644 (file)
@@ -628,12 +628,12 @@ $1',
 'actionthrottledtext' => 'ក្រោមវិធានការប្រឆាំងស្ប៉ាម​ អ្នកត្រូវបាន​គេកំហិតមិនឱ្យ​ធ្វើសកម្មភាពនេះ​ច្រើនដងពេកទេ​ក្នុងរយៈពេលខ្លីមួយ។
 
 សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេលប៉ុន្មាននាទីទៀត។',
-'protectedpagetext' => 'á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9f\81á\9f\87á\9e\94á\9e¶á\9e\93á\9e\8fá\9f\92á\9e\9aá\9e¼á\9e\9cá\9e\85á\9e¶á\9e\80á\9f\8bá\9e\9fá\9f\84á\9e\98á\9e·á\9e\93á\9e±á\9f\92á\9e\99á\9e\80á\9f\82á\9e\94á\9f\92á\9e\9aá\9f\82â\80\8b។',
+'protectedpagetext' => 'á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9f\81á\9f\87á\9e\94á\9e¶á\9e\93á\9e\8fá\9f\92á\9e\9aá\9e¼á\9e\9cá\9e\80á\9e¶á\9e\9aá\9e\96á\9e¶á\9e\9aá\9e\98á\9e·á\9e\93á\9e±á\9f\92á\9e\99á\9e\80á\9f\82á\9e\94á\9f\92á\9e\9aá\9f\82â\80\8bá\9e¬á\9e\92á\9f\92á\9e\9cá\9e¾á\9e\9fá\9e\80á\9e\98á\9f\92á\9e\98á\9e\97á\9e¶á\9e\96á\9e\95á\9f\92á\9e\9fá\9f\81á\9e\84á\9e\91á\9f\80á\9e\8fá\9e\9bá\9e¾á\9e\9cá\9e។',
 'viewsourcetext' => 'អ្នកអាចមើលនិងចម្លងកូដរបស់ទំព័រនេះ៖',
 'viewyourtext' => "អ្នកអាចមើលនិងចម្លងកូដរបស់'''ការកែប្រែរបស់អ្នក'''ទៅកាន់ទំព័រនេះ៖",
 'protectedinterface' => 'ទំព័រនេះផ្ដល់នូវអត្ថបទអន្តរមុខសម្រាប់សូហ្វវែរនៅក្នុងវិគីនេះ និងត្រូវបានចាក់សោដើម្បីចៀសវាងការបំពាន។
 ដើម្បីបន្ថែមឬផ្លាស់ប្ដូរការបកប្រែសំរាប់វិគីទាំងអស់ សូមប្រើប្រាស់ [//translatewiki.net/ translatewiki.net] ដែលជាគំរោងបកប្រែរបស់MediaWiki។',
-'editinginterface' => "'''á\9e\94á\9f\92á\9e\9aá\9e\99á\9f\90á\9e\8fá\9f\92á\9e\93á\9f\96''' á\9e¢á\9f\92á\9e\93á\9e\80á\9e\80á\9f\86á\9e\96á\9e»á\9e\84á\9e\8fá\9f\82á\9e\80á\9f\82á\9e\94á\9f\92á\9e\9aá\9f\82á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\8aá\9f\82á\9e\9bá\9e\94á\9e¶á\9e\93á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bâ\80\8bá\9e\8aá\9e¾á\9e\98á\9f\92á\9e\94á\9e¸á\9e\95á\9f\92á\9e\8aá\9e\9bá\9f\8bá\9e\93á\9e¼á\9e\9cá\9e¢á\9e\93á\9f\92á\9e\8fá\9e\9aá\9e\98á\9e»á\9e\81á\9e\9fá\9e\98á\9f\92á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\95á\9f\92á\9e\93á\9f\82á\9e\80á\9e\91á\9e\93á\9f\8bâ\80\8bá\9f\94 á\9e\94á\9f\86á\9e\9bá\9e¶á\9e\9fá\9f\8bá\9e\94á\9f\92á\9e\8aá\9e¼á\9e\9aá\9e\85á\9f\86á\9e\96á\9f\84á\9f\87á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9f\81á\9f\87â\80\8bá\9e\93á\9e¹á\9e\84á\9e\94á\9f\89á\9f\87á\9e\96á\9e¶á\9e\9bá\9f\8bá\9e\8aá\9e\9bá\9f\8bá\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e¢á\9e\93á\9f\92á\9e\8fá\9e\9aá\9e\98á\9e»á\9e\81á\9e\93á\9f\83á\9e¢á\9f\92á\9e\93á\9e\80á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bâ\80\8bá\9e\87á\9e¶á\9e\85á\9f\92á\9e\9aá\9e¾á\9e\93 á\9e\8aá\9f\82á\9e\9bá\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\9cá\9e·á\9e\94á\9e\9fá\9e¶á\9e\99á\9e\93á\9f\81á\9f\87á\9f\94 á\9e\9fá\9e\98á\9f\92á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\80á\9e¶á\9e\9aá\9e\94á\9e\80á\9e\94á\9f\92á\9e\9aá\9f\82 á\9e\9fá\9e¼á\9e\98á\9e\96á\9e·á\9e\85á\9e¶á\9e\9aá\9e\8eá\9e¶á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8b [//translatewiki.net/wiki/Main_Page?setlang=km translatewiki.net] (á\9e\94á\9f\81á\9e\8fá\9e¶á\9e\9cá\9e·á\9e\82á\9e¸) á\9e\82á\9e\98á\9f\92á\9e\9aá\9f\84á\9e\84â\80\8bá\9e¢á\9e\93á\9f\92á\9e\8fá\9e\9aá\9e\87á\9e¶á\9e\8fá\9e¼á\9e\94á\9e\93á\9e¸á\9e\99á\9e\80á\9e\98á\9f\92á\9e\98â\80\8bá\9e\93á\9f\83មេឌាវិគី ។",
+'editinginterface' => "'''á\9e\94á\9f\92á\9e\9aá\9e\99á\9f\90á\9e\8fá\9f\92á\9e\93á\9f\96''' á\9e¢á\9f\92á\9e\93á\9e\80á\9e\80á\9f\86á\9e\96á\9e»á\9e\84á\9e\8fá\9f\82á\9e\80á\9f\82á\9e\94á\9f\92á\9e\9aá\9f\82á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\8aá\9f\82á\9e\9bá\9e\94á\9e¶á\9e\93á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bâ\80\8bá\9e\8aá\9e¾á\9e\98á\9f\92á\9e\94á\9e¸á\9e\95á\9f\92á\9e\8aá\9e\9bá\9f\8bá\9e\87á\9e¼á\9e\93á\9e¢á\9e\93á\9f\92á\9e\8fá\9e\9aá\9e\98á\9e»á\9e\81á\9e\9fá\9e\98á\9f\92á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\9fá\9e¼á\9e á\9f\92á\9e\9cá\9e\9cá\9f\82á\9e\9aá\9f\94 á\9e\94á\9f\86á\9e\9bá\9e¶á\9e\9fá\9f\8bá\9e\94á\9f\92á\9e\8aá\9e¼á\9e\9aá\9e\85á\9f\86á\9e\96á\9f\84á\9f\87á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9f\81á\9f\87â\80\8bá\9e\93á\9e¹á\9e\84á\9e\94á\9f\89á\9f\87á\9e\96á\9e¶á\9e\9bá\9f\8bá\9e\8aá\9e\9bá\9f\8bá\9e\91á\9f\92á\9e\9aá\9e\84á\9f\8bá\9e\91á\9f\92á\9e\9aá\9e¶á\9e\99á\9e\9aá\9e\94á\9e\9fá\9f\8bá\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e¢á\9e\93á\9f\92á\9e\8fá\9e\9aá\9e\98á\9e»á\9e\81á\9e\9fá\9f\86á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e¢á\9f\92á\9e\93á\9e\80á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bâ\80\8bá\9e\87á\9e¶á\9e\85á\9f\92á\9e\9aá\9e¾á\9e\93 á\9e\8aá\9f\82á\9e\9bá\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\9cá\9e·á\9e\82á\9e¸á\9e\93á\9f\81á\9f\87á\9f\94 á\9e\8aá\9e¾á\9e\98á\9f\92á\9e\94á\9e¸á\9e\94á\9e\93á\9f\92á\9e\90á\9f\82á\9e\98á\9e¬á\9e\95á\9f\92á\9e\9bá\9e¶á\9e\9fá\9f\8bá\9e\94á\9f\92á\9e\8aá\9e¼á\9e\9aá\9e\80á\9e¶á\9e\9aá\9e\94á\9e\80á\9e\94á\9f\92á\9e\9aá\9f\82â\80\8bá\9e\9fá\9f\86á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\9cá\9e·á\9e\82á\9e¸á\9e\91á\9e¶á\9f\86á\9e\84á\9e¢á\9e\9fá\9f\8b á\9e\9fá\9e¼á\9e\94á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8b  [//translatewiki.net/wiki/Main_Page?setlang=km translatewiki.net] á\9e\82á\9e\98á\9f\92á\9e\9aá\9f\84á\9e\84â\80\8bá\9e\94á\9e\80á\9e\94á\9f\92á\9e\9aá\9f\82á\9e\9aá\9e\94á\9e\9fá\9f\8bមេឌាវិគី ។",
 'sqlhidden' => '(ការអង្កេត SQL ត្រូវបិទបាំង)',
 'cascadeprotected' => 'ទំព័រនេះត្រូវបានការពារពីការការប្រែដោយសារវាមាន{{PLURAL:$1|ទំព័រ, ដែលមាន}} ដែលត្រូវបានការពារជាមួយជំរើស"ជាបណ្ដាក់"៖
 $2',
@@ -686,7 +686,7 @@ $2',
 'gotaccount' => "បើលោកអ្នកមានគណនីសម្រាប់ប្រើហើយ  សូម'''$1'''។",
 'gotaccountlink' => 'កត់ឈ្មោះចូល',
 'userlogin-resetlink' => 'តើអ្នកភ្លេចព័ត៌មានលំអិតសំរាប់កត់ឈ្មោះចូលហើយ?',
-'createaccountmail' => 'á\9e\8fá\9e¶á\9e\98á\9e\9aá\9e\99á\9f\88á\9e¢á\9f\8aá\9e¸á\9e\98á\9f\82á\9e\9b',
+'createaccountmail' => 'á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\96á\9e¶á\9e\80á\9f\92á\9e\99á\9e\9fá\9f\86á\9e\84á\9e¶á\9e\8fá\9f\8bá\9e\96á\9f\92á\9e\9aá\9f\80á\9e\84á\9e\94á\9e\8eá\9f\92á\9e\8aá\9f\84á\9f\87á\9e¢á\9e¶á\9e\9fá\9e\93á\9e»á\9f\92á\9e\93 á\9e\9aá\9e½á\9e\85á\9e\95á\9f\92á\9e\89á\9e¾á\9e\9cá\9e¶á\9e\91á\9f\85á\9e\80á\9e¶á\9e\93á\9f\8bá\9e¢á\9e¶á\9e\9fá\9e\99á\9e\8aá\9f\92á\9e\8bá\9e¶á\9e\93á\9e¢á\9f\8aá\9e¸á\9e\98á\9f\82á\9e\9bá\9e\81á\9e¶á\9e\84á\9e\80á\9f\92á\9e\9aá\9f\84á\9e\98',
 'createaccountreason' => 'មូលហេតុ៖',
 'badretype' => 'ពាក្យសំងាត់ដែលអ្នកបានបញ្ចូលនោះ គឺមិនស៊ីគ្នាទេ។',
 'userexists' => 'អត្តនាមដែលអ្នកបានវាយបញ្ចូលមានគេប្រើហើយ។
@@ -844,6 +844,7 @@ $2
 'changeemail-oldemail' => 'អាសយដ្ឋានអ៊ីមែលបច្ចុប្បន្ន៖',
 'changeemail-newemail' => 'អាសយដ្ឋានអ៊ីមែលថ្មី៖',
 'changeemail-none' => '(គ្មាន​)',
+'changeemail-password' => 'ពាក្យសំងាត់{{SITENAME}}របស់អ្នក:',
 'changeemail-submit' => 'ផ្លាស់ប្ដូរអ៊ីមែល',
 'changeemail-cancel' => 'បោះបង់',
 
@@ -1411,9 +1412,9 @@ $1",
 'prefs-emailconfirm-label' => 'បញ្ជាក់ទទួលស្គាល់អ៊ីមែល៖',
 'prefs-textboxsize' => 'ទំហំរបស់ផ្ទាំងកែប្រែទំព័រ',
 'youremail' => 'អ៊ីមែល៖',
-'username' => 'អត្តនាម៖',
-'uid' => 'អត្តលេខ៖',
-'prefs-memberingroups' => 'សមាជិកក្នុង{{PLURAL:$1|ក្រុម|ក្រុម}}៖',
+'username' => '{{GENDER:$1|អត្តនាម}}៖',
+'uid' => 'អត្តលេខ{{GENDER:$1|អ្នកប្រើប្រាស់}}៖',
+'prefs-memberingroups' => '{{GENDER:$2|សមាជិក}}ក្នុង{{PLURAL:$1|ក្រុម|ក្រុម}}៖',
 'prefs-registration' => 'កាលបរិច្ឆេទចុះឈ្មោះ៖',
 'yourrealname' => 'ឈ្មោះពិត៖',
 'yourlanguage' => 'ភាសា៖',
@@ -2154,8 +2155,8 @@ $1',
 'linksearch-ns' => 'លំហឈ្មោះ៖',
 'linksearch-ok' => 'ស្វែងរក',
 'linksearch-text' => 'Wildcards ដូចជា "*.wikipedia.org" អាចប្រើបាន។
\9e\8fá\9f\86á\9e\9aá\9e¼á\9e\9cá\9e¢á\9f\84á\9e\99á\9e\98á\9e¶á\9e\93á\9e\99á\9f\89á\9e¶á\9e\84á\9e á\9f\84á\9e\85á\9e\8eá\9e¶á\9e\9fá\9f\8bá\9e¢á\9f\84á\9e\99á\9e\98á\9e¶á\9e\93á\9e\8aá\9e¼á\9e\98á\9f\89á\9f\82á\9e\93á\9e\80á\9f\86á\9e\9aá\9e·á\9e\8fá\9e\9bá\9e¾á\9e\82á\9f\81 á\9e§á\9e\91á\9e¶á\9e á\9e¶á\9e\9aá\9e\8eá\9f\8d "*.org"á\9f\94<br />
-ប្រូតូខូលប្រើបាន៖ <code>$1</code>  (តាមលំនាំដើមជា http:// ប្រសិនបើគ្មានបញ្ជាក់ប្រូតូខូល)។',
+តំរូវអោយមានយ៉ាងហោចណាស់អោយមានដូម៉ែនកំរិតលើគេ ឧទាហរណ៍ "*.org"។<br />
+{{PLURAL:$2ប្រូតូខូល|ប្រូតូខូល}}ប្រើបាន៖ <code>$1</code>  (តាមលំនាំដើមជា http:// ប្រសិនបើគ្មានបញ្ជាក់ប្រូតូខូល)។',
 'linksearch-line' => '$1បានតភ្ជាប់ពី$2',
 
 # Special:ListUsers
@@ -2167,7 +2168,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'បញ្ជីរាយនាមអ្នកប្រើប្រាស់សកម្ម',
 'activeusers-intro' => 'នេះជាបញ្ជីរាយនាមអ្នកប្រើប្រាស់ដែលមានសកម្មភាពក្នុងរូបភាពណាមួយក្នុងរយៈពេល $1 {{PLURAL:$1|ថ្ងៃ|ថ្ងៃ}}ចុងក្រោយ។',
-'activeusers-count' => '$1 {{PLURAL:$1|កំនែប្រែ|កំនែប្រែ}}ក្នុងរយៈពេល{{PLURAL:$3|ថ្ងៃ|$3 ថ្ងៃ}}ចុងក្រោយ',
+'activeusers-count' => '{{PLURAL:$1|សកម្មភាព|សកម្មភាព}}ចំនួន$1 ក្នុងរយៈពេល{{PLURAL:$3|១ថ្ងៃ|$3 ថ្ងៃ}}ចុងក្រោយ',
 'activeusers-from' => 'បង្ហាញអត្តនាមផ្ដើមដោយ៖',
 'activeusers-hidebots' => 'លាក់រូបយន្ត',
 'activeusers-hidesysops' => 'លាក់អ្នកអភិបាល',
@@ -2229,7 +2230,7 @@ $1',
 'usermessage-editor' => 'ប្រព័ន្ធផ្ញើសារ',
 
 # Watchlist
-'watchlist' => 'បញ្ជីតាមដានរបស់ខ្ញុំ',
+'watchlist' => 'បញ្ជីតាមដាន',
 'mywatchlist' => 'បញ្ជីតាមដាន​',
 'watchlistfor2' => 'សំរាប់ $1 $2',
 'nowatchlist' => 'គ្មានអ្វីនៅក្នុងបញ្ជីតាមដានរបស់អ្នកទេ។',
@@ -2390,9 +2391,9 @@ $UNWATCHURL
 
 អ្នកអាចផ្លាស់ប្តូរកម្រិតការពារនៃ ទំព័រ ប៉ុន្តែវានឹងមិនប៉ះពាល់ដល់ការការពារជាថ្នាក់ទេ។',
 'protect-default' => 'អនុញ្ញាត​អ្នក​ប្រើ​ប្រាស់​ទាំង​អស់​',
-'protect-fallback' => 'á\9e\8fá\9e\98á\9f\92á\9e\9aá\9e¼á\9e\9cá\9e±á\9f\92á\9e\99á\9e\98á\9e¶á\9e\93á\9e\80á\9e¶á\9e\9aá\9e¢á\9e\93á\9e»á\9e\89á\9f\92á\9e\89á\9e¶á\9e\8fá\9e\93á\9f\83 "$1"',
-'protect-level-autoconfirmed' => 'á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8bá\9e¢á\9f\92á\9e\93á\9e\80á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\90á\9f\92á\9e\98á\9e¸â\80\8bá\9e\93á\9e¹á\9e\84â\80\8bá\9e¢á\9f\92á\9e\93á\9e\80â\80\8bâ\80\8bá\9e\98á\9e·á\9e\93á\9e\91á\9e¶á\9e\93á\9f\8bá\9e\85á\9e»á\9f\87á\9e\88á\9f\92á\9e\98á\9f\84á\9f\87',
-'protect-level-sysop' => 'á\9e\9fá\9e\98á\9f\92á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\8fá\9f\82á\9e¢á\9f\92á\9e\93á\9e\80á\9e\90á\9f\82á\9e\91á\9e¶á\9f\86á\9e\94á\9f\92á\9e\9aá\9e\96á\9f\90á\9e\93á\9f\92á\9e\92',
+'protect-fallback' => 'á\9e\9fá\9f\86á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\8fá\9f\82á\9e¢á\9f\92á\9e\93á\9e\80á\9e\8aá\9f\82á\9e\9bá\9e\98á\9e¶á\9e\93á\9e\80á\9e¶á\9e\9aá\9e¢á\9e\93á\9e»á\9e\89á\9f\92á\9e\89á\9e¶á\9e\8f "$1"',
+'protect-level-autoconfirmed' => 'á\9e\9fá\9f\86á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\8fá\9f\82á\9e¢á\9f\92á\9e\93á\9e\80á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\8aá\9f\82á\9e\9bá\9e\94á\9e¶á\9e\93á\9e\94á\9e\89á\9f\92á\9e\87á\9e¶á\9e\80á\9f\8bá\9e\91á\9e\91á\9e½á\9e\9bá\9e\9fá\9f\92á\9e\82á\9e¶á\9e\9bá\9f\8bá\9e\8aá\9f\84á\9e\99á\9e\9fá\9f\92á\9e\9cá\9f\90á\9e\99á\9e\94á\9f\92á\9e\9aá\9e\9cá\9e\8fá\9f\92á\9e\8fá\9e·',
+'protect-level-sysop' => 'á\9e\9fá\9e\98á\9f\92á\9e\9aá\9e¶á\9e\94á\9f\8bá\9e\8fá\9f\82á\9e¢á\9e\97á\9e·á\9e\94á\9e¶á\9e\9b',
 'protect-summary-cascade' => 'ការពារជា​ថ្នាក់',
 'protect-expiring' => 'ផុតកំណត់ $1 (UTC)',
 'protect-expiring-local' => 'ផុតកំណត់ $1',
@@ -2494,7 +2495,7 @@ $1',
 'blanknamespace' => '(ទូទៅ)',
 
 # Contributions
-'contributions' => 'ការរួមចំណែក​របស់អ្នកប្រើប្រាស់',
+'contributions' => 'ការរួមចំណែក​របស់{{GENDER:$1|អ្នកប្រើប្រាស់}}',
 'contributions-title' => 'ការរួមចំណែករបស់អ្នកប្រើប្រាស់ $1',
 'mycontris' => 'ការរួមចំណែក',
 'contribsub2' => 'សម្រាប់ $1 ($2)',
@@ -3538,6 +3539,7 @@ $5
 'version-software' => 'ផ្នែកទន់​ដែល​បានដំឡើង',
 'version-software-product' => 'ផលិតផល',
 'version-software-version' => 'កំណែ',
+'version-entrypoints-header-url' => 'URL',
 
 # Special:FilePath
 'filepath' => 'ផ្លូវនៃឯកសារ',
@@ -3572,7 +3574,7 @@ $5
 'specialpages-group-highuse' => 'ទំព័រដែលត្រូវបានប្រើច្រើន',
 'specialpages-group-pages' => 'បញ្ជីទំព័រនានា',
 'specialpages-group-pagetools' => 'ឧបករណ៍ទំព័រ',
-'specialpages-group-wiki' => 'ទិន្នន័យនិងឧបករណ៍វិគី',
+'specialpages-group-wiki' => 'ទិន្នន័យនិងឧបករណ៍',
 'specialpages-group-redirects' => 'ទំព័របញ្ជូនបន្តពិសេសៗ',
 'specialpages-group-spam' => 'ឧបករណ៍ស្ព៊ែម',
 
@@ -3644,7 +3646,6 @@ $5
 'logentry-newusers-create' => 'បានបង្កើតគណនីអ្នកប្រើប្រាស់ $1',
 'logentry-newusers-create2' => ' $3 បានបង្កើតគណនីអ្នកប្រើប្រាស់ $1',
 'logentry-newusers-autocreate' => 'គណនី $1 ត្រូវបានបង្កើតដោយស្វ័យប្រវត្តិ',
-'newuserlog-byemail' => 'ពាក្យសំងាត់ត្រូវបានផ្ញើតាមអ៊ីមែល',
 'logentry-rights-rights' => '$1 បានផ្លាស់ប្ដូរសមាជិកភាពរបស់ $3 ពី $4 ទៅជា $5',
 'logentry-rights-rights-legacy' => '$1បានផ្លាស់ប្ដូរសមាជិកភាពរបស់ $3',
 'logentry-rights-autopromote' => '$1 ត្រូវបានតំលើងសមាជិកភាពពី $4 ជា $5',
index b50820f..9804e26 100644 (file)
@@ -20,6 +20,7 @@
  * @author Nayvik
  * @author Nk rahul14
  * @author Omshivaprakash
+ * @author Prashwiki
  * @author Shankar
  * @author Shushruth
  * @author Teju2friends
@@ -1628,7 +1629,7 @@ $2',
 'whatlinkshere-hideredirs' => '$1 ಪುನರ್ನಿರ್ದೇಶನಗಳು',
 'whatlinkshere-hidetrans' => '$1 ಸೇರಿಸುವಿಕೆಗಳು',
 'whatlinkshere-hidelinks' => '$1 ಕೊಂಡಿಗಳು',
-'whatlinkshere-hideimages' => '$1 ಚಿತ್ರ ಕೊಂಡಿಗಳು',
+'whatlinkshere-hideimages' => '$1 ಚಿತ್ರ ಕೊಂಡಿಗಳು',
 'whatlinkshere-filters' => 'ಶೋಧಕಗಳು',
 
 # Block/unblock
index dcd9262..8470efd 100644 (file)
@@ -69,10 +69,10 @@ $specialPageAliases = array(
        'Allmessages'               => array( '모든메시지' ),
        'Allpages'                  => array( '모든문서' ),
        'Ancientpages'              => array( '오래된문서' ),
-       'Badtitle'                  => array( 'ì\9e\98못ë\90\9cì\9d´ë¦\84', 'ì\9d¸ì\8b\9dë¶\88ê°\80ì\9d´ë¦\84', 'ì\9e\98못ë\90\9cì \9c목', 'ì\9d¸ì\8b\9dë¶\88ê°\80ì \9c목' ),
+       'Badtitle'                  => array( 'ì\9e\98못ë\90\9cì \9c목', 'ì\9d¸ì\8b\9dë¶\88ê°\80ì \9c목', 'ì\9e\98못ë\90\9cì\9d´ë¦\84', 'ì\9d¸ì\8b\9dë¶\88ê°\80ì\9d´ë¦\84' ),
        'Blankpage'                 => array( '빈문서' ),
-       'Block'                     => array( '차단' ),
-       'Blockme'                   => array( '자가차단' ),
+       'Block'                     => array( '차단', 'IP차단', '사용자차단' ),
+       'Blockme'                   => array( 'ì\9e\90기차ë\8b¨', 'ì\9e\90ê°\80ì°¨ë\8b¨' ),
        'Booksources'               => array( '책찾기' ),
        'BrokenRedirects'           => array( '끊긴넘겨주기' ),
        'Categories'                => array( '분류' ),
@@ -96,7 +96,7 @@ $specialPageAliases = array(
        'Invalidateemail'           => array( '이메일인증취소', '이메일인증해제' ),
        'JavaScriptTest'            => array( '자바스크립트시험' ),
        'BlockList'                 => array( '차단된사용자', '차단목록' ),
-       'LinkSearch'                => array( '외부링크찾기', '외부링크검색' ),
+       'LinkSearch'                => array( '링크찾기', '링크검색' ),
        'Listadmins'                => array( '관리자', '관리자목록' ),
        'Listbots'                  => array( '봇', '봇목록' ),
        'Listfiles'                 => array( '파일', '그림', '파일목록', '그림목록' ),
@@ -129,7 +129,7 @@ $specialPageAliases = array(
        'Preferences'               => array( '환경설정' ),
        'Prefixindex'               => array( '접두어찾기' ),
        'Protectedpages'            => array( '보호된문서' ),
-       'Protectedtitles'           => array( '생성보호된문서', '만들기보호된문서' ),
+       'Protectedtitles'           => array( '만들기보호된문서', '생성보호된문서' ),
        'Randompage'                => array( '임의문서' ),
        'Randomredirect'            => array( '임의넘겨주기' ),
        'Recentchanges'             => array( '최근바뀜' ),
@@ -151,11 +151,11 @@ $specialPageAliases = array(
        'Unusedimages'              => array( '안쓰는파일', '안쓰는그림', '쓰이지않는파일', '쓰이지않는그림' ),
        'Unusedtemplates'           => array( '안쓰는틀', '쓰이지않는틀' ),
        'Unwatchedpages'            => array( '주시안되는문서' ),
-       'Upload'                    => array( '올리기', '파일올리기', '그림올리기' ),
+       'Upload'                    => array( '올리기', '파일올리기', '그림올리기', '업로드' ),
        'UploadStash'               => array( '올린비공개파일' ),
        'Userlogin'                 => array( '로그인' ),
        'Userlogout'                => array( '로그아웃' ),
-       'Userrights'                => array( '권한조정' ),
+       'Userrights'                => array( '권한조정', '관리자하기', '봇하기' ),
        'Version'                   => array( '버전' ),
        'Wantedcategories'          => array( '필요한분류' ),
        'Wantedfiles'               => array( '필요한파일', '필요한그림' ),
@@ -366,7 +366,7 @@ $messages = array(
 'tog-minordefault' => '사소한 편집을 기본적으로 선택하기',
 'tog-previewontop' => '편집 상자 앞에 미리 보기 보기',
 'tog-previewonfirst' => '처음 편집할 때 미리 보기 보기',
-'tog-nocache' => '브라우저의 문서 캐시 끄기',
+'tog-nocache' => '브라우저 문서 캐시 비활성화',
 'tog-enotifwatchlistpages' => '주시문서 목록에 속한 문서나 파일이 바뀌면 이메일로 알림',
 'tog-enotifusertalkpages' => '내 토론 문서가 바뀌면 이메일로 알림',
 'tog-enotifminoredits' => '문서나 파일의 사소한 편집도 이메일로 알림',
@@ -478,7 +478,7 @@ $messages = array(
 'newwindow' => '(새 창으로 열림)',
 'cancel' => '취소',
 'moredotdotdot' => '더 보기...',
-'morenotlisted' => '목ë¡\9dì\97\90 ì\97\86ë\8a\94 항목 더 보기...',
+'morenotlisted' => 'ë\8b¤ë¥¸ 항목 더 보기...',
 'mypage' => '문서',
 'mytalk' => '토론',
 'anontalk' => '익명 사용자 토론',
@@ -783,7 +783,7 @@ $2',
 'gotaccount' => '계정이 이미 있다면, $1.',
 'gotaccountlink' => '로그인하세요',
 'userlogin-resetlink' => '사용자 이름이나 비밀번호를 잊으셨나요?',
-'createaccountmail' => '이메일로 보내기',
+'createaccountmail' => 'ì\9e\84ì\8b\9c ì\9e\84ì\9d\98 ë¹\84ë°\80ë²\88í\98¸ë¥¼ ì\95\84ë\9e\98ì\97\90 ì§\80ì \95í\95\9c ì\9d´ë©\94ì\9d¼ë¡\9c ë³´ë\82´ê¸°',
 'createaccountreason' => '이유:',
 'badretype' => '입력한 비밀번호가 서로 다릅니다.',
 'userexists' => '입력하신 사용자 이름이 이미 등록되어 있습니다.
@@ -1099,7 +1099,7 @@ IP 주소는 여러 사용자가 공유할 수 있습니다.
 'longpageerror' => "'''오류: 문서의 크기가 {{PLURAL:$1|$1킬로바이트}}로 최대 크기인 {{PLURAL:$2|$2킬로바이트}}보다 큽니다.'''
 저장할 수 없습니다.",
 'readonlywarning' => "'''경고: 데이터베이스가 관리를 위해 잠겨 있습니다. 따라서 문서를 편집한 내용을 지금 저장할 수 없습니다.'''
-편집 내용을 복사 붙여넣기 등을 사용하여 일단 다른 곳에 저장한 후, 나중에 다시 시도해 주세요.
+편집 내용을 복사하여 붙여넣기 등을 사용하여 일단 다른 곳에 저장한 후, 나중에 다시 시도해 주세요.
 
 잠근 관리자가 남긴 설명은 다음과 같습니다: $1",
 'protectedpagewarning' => "'''경고: 이 문서는 관리자만 편집할 수 있도록 보호되어 있습니다.'''
@@ -1168,8 +1168,8 @@ $2개 보다 적게 써야 하지만 지금은 $1개를 쓰고 있습니다.",
 'node-count-exceeded-warning' => '문서가 노드 수를 초과하였습니다.',
 'expansion-depth-exceeded-category' => '문서가 확장 깊이를 초과하였습니다.',
 'expansion-depth-exceeded-warning' => '문서가 확장 깊이를 초과하였습니다',
-'parser-unstrip-loop-warning' => 'ì\8a¤í\8a¸ë¦½í\95\98ì§\80 ì\95\8aë\8a\94 ë°\98ë³µì\9d´ ê°\90ì§\80ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤',
-'parser-unstrip-recursion-limit' => '스트립하지 않는 재귀 한도가 초과됨 ($1)',
+'parser-unstrip-loop-warning' => 'Unstripì\9d\98 ë°\98ë³µì\9d\84 ê°\90ì§\80í\96\88ì\8aµë\8b\88ë\8b¤',
+'parser-unstrip-recursion-limit' => 'Unstrip의 재귀 한도를 초과했습니다 ($1)',
 'converter-manual-rule-error' => '언어 변환 규칙을 수동으로 지정하는 도중 오류',
 
 # "Undo" feature
@@ -1408,7 +1408,7 @@ $1",
 'search-interwiki-default' => '$1 결과:',
 'search-interwiki-more' => '(더 보기)',
 'search-relatedarticle' => '관련',
-'mwsuggest-disable' => 'AJAX 검색어 제안 끄기',
+'mwsuggest-disable' => '찾기 제안 비활성화',
 'searcheverything-enable' => '모든 이름공간에서 찾기',
 'searchrelated' => '관련',
 'searchall' => '모두',
@@ -1717,7 +1717,7 @@ HTML 태그를 확인하세요.',
 'action-sendemail' => '이메일 보내기',
 
 # Recent changes
-'nchanges' => '$1개 바뀜',
+'nchanges' => '$1개 {{PLURAL:$1|바뀜}}',
 'recentchanges' => '최근 바뀜',
 'recentchanges-legend' => '최근 바뀜 설정',
 'recentchanges-summary' => '위키의 최근 바뀜 내역이 나와 있습니다.',
@@ -1726,7 +1726,7 @@ HTML 태그를 확인하세요.',
 'recentchanges-label-minor' => '사소한 편집',
 'recentchanges-label-bot' => '봇의 편집',
 'recentchanges-label-unpatrolled' => '아직 검토하지 않은 편집',
-'rcnote' => "다음은 $4 $5 까지의 '''$2'''일동안 바뀐 문서 '''$1'''개입니다.",
+'rcnote' => "다음은 $4 $5 까지의 {{PLURAL:$2|'''$2'''일}}동안 {{PLURAL:$1|바뀐 문서 '''$1'''개입니다}}.",
 'rcnotefrom' => "다음은 '''$2'''에서부터 바뀐 문서 '''$1'''개입니다.",
 'rclistfrom' => '$1 이래로 바뀐 문서',
 'rcshowhideminor' => '사소한 편집을 $1',
@@ -1780,9 +1780,9 @@ HTML 태그를 확인하세요.',
 [[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 찾을 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.
 
 문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.
-* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때.
-* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 넓이를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때.
-* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할때.",
+* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때
+* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 넓이를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때
+* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할 때",
 'upload-permitted' => '허용하는 파일 확장자: $1',
 'upload-preferred' => '권장하는 파일 확장자: $1',
 'upload-prohibited' => '금지하는 파일 확장자: $1',
@@ -1839,14 +1839,14 @@ $2 형식만 사용할 수 있습니다.',
 'fileexists-extension' => '비슷한 이름의 파일이 존재합니다: [[$2|thumb]]
 * 올리려는 파일 이름: <strong>[[:$1]]</strong>
 * 존재하는 파일 이름: <strong>[[:$2]]</strong>
\8b¤ë¥¸ ì\9d´ë¦\84ì\9c¼ë¡\9c ì\8b\9cë\8f\84í\95´ ì£¼세요.',
\8b¤ë¥¸ ì\9d´ë¦\84ì\9c¼ë¡\9c ì\84 í\83\9dí\95\98세요.',
 'fileexists-thumbnail-yes' => '이 파일은 원본 그림이 아닌, 다른 그림의 크기를 줄인 섬네일 파일인 것 같습니다.
 [[$1|thumb]]
-<strong>[[:$1]]</strong> í\8c\8cì\9d¼ì\9d\84 í\99\95ì\9d¸í\95´ì£¼세요.
-해당 파일이 현재 올리려는 파일과 같다면, 더 작은 크기의 그림을 올릴 필요는 없습니다.',
+<strong>[[:$1]]</strong> í\8c\8cì\9d¼ì\9d\84 í\99\95ì\9d¸í\95\98세요.
+해당 파일이 현재 올리려는 파일과 같다면 더 작은 크기의 그림을 올릴 필요는 없습니다.',
 'file-thumbnail-no' => '파일 이름이 <strong>$1</strong>으로 시작합니다.
 이 파일은 원본 그림이 아닌, 다른 그림의 크기를 줄인 섬네일 파일인 것 같습니다.
\8d\94 í\95´ì\83\81ë\8f\84ê°\80 ì¢\8bì\9d\80 í\8c\8cì\9d¼ì\9d´ ì\9e\88ë\8b¤ë©´ ê·¸ í\8c\8cì\9d¼ì\9d\84 ì\98¬ë ¤ì£¼ì\84¸ì\9a\94. ì\95\84ë\8b\88ë©´ ì\98¬ë¦¬ë ¤ë\8a\94 í\8c\8cì\9d¼ ì\9d´ë¦\84ì\9d\84 ë°\94꾸ì\96´ ì£¼세요.',
\8d\94 í\95´ì\83\81ë\8f\84ê°\80 ì¢\8bì\9d\80 í\8c\8cì\9d¼ì\9d´ ì\9e\88ë\8b¤ë©´ ê·¸ í\8c\8cì\9d¼ì\9d\84 ì\98¬ë¦¬ê±°ë\82\98 ì\95\84ë\8b\88ë©´ ì\98¬ë¦¬ë ¤ë\8a\94 í\8c\8cì\9d¼ ì\9d´ë¦\84ì\9d\84 ë°\94꾸세요.',
 'fileexists-forbidden' => '같은 이름의 파일이 이미 있고, 덮어쓸 수 없습니다.
 그래도 파일을 올리시려면, 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다.
 [[File:$1|thumb|center|$1]]',
@@ -2302,7 +2302,7 @@ URL이 맞고 해당 웹사이트가 작동하는지 확인해주세요.',
 'cachedspecial-refresh-now' => '최신 버전 보기.',
 
 # Special:Categories
-'categories' => '분류',
+'categories' => '분류 목록',
 'categoriespagetext' => '{{PLURAL:$1}}문서나 자료를 담고 있는 분류 목록입니다.
 [[Special:UnusedCategories|사용되지 않는 분류]]는 여기에 보이지 않습니다.
 [[Special:WantedCategories|필요한 분류]]도 참고하세요.',
@@ -2335,7 +2335,7 @@ URL이 맞고 해당 웹사이트가 작동하는지 확인해주세요.',
 # Special:ActiveUsers
 'activeusers' => '활동적인 사용자 목록',
 'activeusers-intro' => '다음은 최근 $1일 동안 활동한 사용자의 목록입니다.',
-'activeusers-count' => '최근 $3일 사이의 편집 $1개',
+'activeusers-count' => '최근 {{PLURAL:$3|1일|$3일}} 사이의 {{PLURAL:$1|활동}} $1회',
 'activeusers-from' => '다음으로 시작하는 사용자를 보기:',
 'activeusers-hidebots' => '봇을 숨기기',
 'activeusers-hidesysops' => '관리자를 숨기기',
@@ -2620,7 +2620,7 @@ $UNWATCHURL
 'undeletehistory' => '문서를 되살리면 모든 역사가 같이 복구됩니다.
 문서가 삭제된 뒤 같은 이름의 문서가 만들어졌다면, 복구되는 역사는 지금 역사의 과거 부분에 나타날 것입니다.',
 'undeleterevdel' => '복구하려는 문서의 최신판이 삭제되어 있는 경우 문서를 복구시킬 수 없습니다.
-이러한 경우, 삭제된 최신판 문서의 체크박스를 선택 해제하거나 숨김을 해제해야 합니다.',
+이러한 경우 삭제된 최신판 문서의 확인 상자를 선택 해제하거나 숨김을 해제해야 합니다.',
 'undeletehistorynoadmin' => '이 문서는 삭제되었습니다.
 삭제된 이유와 삭제되기 전에 이 문서를 편집한 사용자가 아래에 나와 있습니다.
 삭제된 문서의 내용을 보려면 관리자 권한이 필요합니다.',
@@ -3144,7 +3144,7 @@ $1 사용자가 차단된 이유는 다음과 같습니다: "$2"',
 'tooltip-ca-nstab-category' => '분류 문서 내용을 봅니다.',
 'tooltip-minoredit' => '사소한 편집으로 표시하기',
 'tooltip-save' => '바뀜 저장하기',
-'tooltip-preview' => '편집 미리 보기. 저장하기 전에 꼭 미리 보기를 해 주세요!',
+'tooltip-preview' => '바뀜을 미리 봅니다. 저장하기 전에 꼭 미리 보기를 해 주세요!',
 'tooltip-diff' => '자신이 바꾼 것 보기',
 'tooltip-compareselectedversions' => '이 문서에서 선택한 두 판간의 차이를 비교',
 'tooltip-watch' => '이 문서를 주시문서 목록에 추가',
@@ -3232,8 +3232,9 @@ $1 사용자가 차단된 이유는 다음과 같습니다: "$2"',
 'pageinfo-robot-policy' => '검색 엔진 통계',
 'pageinfo-robot-index' => '색인 가능',
 'pageinfo-robot-noindex' => '색인 불가능',
-'pageinfo-views' => '읽힌 횟수',
+'pageinfo-views' => '읽은 수',
 'pageinfo-watchers' => '문서를 주시하는 사용자 수',
+'pageinfo-few-watchers' => '{{PLURAL:$1|주시하는 사용자}} $1명 미만',
 'pageinfo-redirects-name' => '이 문서로 넘겨주기',
 'pageinfo-redirects-value' => '$1개',
 'pageinfo-subpages-name' => '이 문서의 하위 문서',
@@ -3246,7 +3247,7 @@ $1 사용자가 차단된 이유는 다음과 같습니다: "$2"',
 'pageinfo-authors' => '총 서로 다른 편집자 수',
 'pageinfo-recent-edits' => '최근 편집 수 (지난 $1 이내)',
 'pageinfo-recent-authors' => '최근 기여자 수',
-'pageinfo-magic-words' => '매직 {{PLURAL:$1|워드}} ($1개)',
+'pageinfo-magic-words' => '특수 {{PLURAL:$1|명령}} ($1개)',
 'pageinfo-hidden-categories' => '숨은 {{PLURAL:$1|분류}} ($1개)',
 'pageinfo-templates' => '포함한 {{PLURAL:$1|틀}} ($1개)',
 'pageinfo-transclusions' => '포함한 {{PLURAL:$1|문서}} ($1개)',
@@ -3261,7 +3262,7 @@ $1 사용자가 차단된 이유는 다음과 같습니다: "$2"',
 'pageinfo-category-info' => '분류 정보',
 'pageinfo-category-pages' => '문서 수',
 'pageinfo-category-subcats' => '하위 분류 수',
-'pageinfo-category-files' => '파일 수',
+'pageinfo-category-files' => '파일 수',
 
 # Skin names
 'skinname-standard' => '클래식',
@@ -3327,7 +3328,7 @@ $1',
 'file-info-gif-looped' => '반복됨',
 'file-info-gif-frames' => '$1 프레임',
 'file-info-png-looped' => '반복됨',
-'file-info-png-repeat' => '$1 재생됨',
+'file-info-png-repeat' => '$1{{PLURAL:$1|번}} 재생됨',
 'file-info-png-frames' => '$1 프레임',
 'file-no-thumb-animation' => "'''참고: 기술적인 제한으로 인해 이 파일의 섬네일은 애니메이션을 지원하지 않습니다.'''",
 'file-no-thumb-animation-gif' => "'''참고: 기술적인 제한으로 인해 고해상도 GIF 그림 섬네일은 애니메이션을 지원하지 않습니다.'''",
@@ -3932,7 +3933,7 @@ $5
 'watchlistedit-normal-title' => '주시문서 목록 편집하기',
 'watchlistedit-normal-legend' => '주시문서 목록에서 문서 제거하기',
 'watchlistedit-normal-explain' => '주시문서 목록에 있는 문서의 제목이 아래에 나열되어 있습니다.
-주시문서 목록에서 제거하려는 문서가 있으면, 각 항목의 체크박스를 선택한 다음 "{{int:Watchlistedit-normal-submit}}"를 클릭해주세요.
+주시문서 목록에서 제거하려는 문서가 있으면 각 항목의 확인 상자를 선택한 다음 "{{int:Watchlistedit-normal-submit}}"를 클릭해주세요.
 또는 [[Special:EditWatchlist/raw|목록을 직접 편집]]할 수도 있습니다.',
 'watchlistedit-normal-submit' => '항목 삭제',
 'watchlistedit-normal-done' => '주시문서 목록에서 다음 {{PLURAL:$1|항목}}을 주시하지 않습니다:',
@@ -4027,7 +4028,7 @@ $5
 'specialpages-group-highuse' => '많이 쓰이는 문서 목록',
 'specialpages-group-pages' => '문서 목록',
 'specialpages-group-pagetools' => '문서 도구',
-'specialpages-group-wiki' => '위키 정보와 도구',
+'specialpages-group-wiki' => '데이터와 도구',
 'specialpages-group-redirects' => '넘겨주기 특수 문서',
 'specialpages-group-spam' => '스팸 처리 도구',
 
@@ -4056,7 +4057,7 @@ $5
 'tags-description-header' => '태그에 대한 설명',
 'tags-hitcount-header' => '태그된 바뀜',
 'tags-edit' => '편집',
-'tags-hitcount' => '$1개 바뀜',
+'tags-hitcount' => '$1개 {{PLURAL:$1|바뀜}}',
 
 # Special:ComparePages
 'comparepages' => '문서 비교',
@@ -4125,8 +4126,8 @@ $5
 'logentry-newusers-newusers' => '$1 사용자 계정을 만들었습니다.',
 'logentry-newusers-create' => '$1 사용자 계정을 만들었습니다.',
 'logentry-newusers-create2' => '$1 사용자가 $3 사용자 계정을 만들었습니다.',
+'logentry-newusers-byemail' => '$3 사용자 계정이 $1에 만들어졌고 비밀번호는 이메일로 보냈습니다',
 'logentry-newusers-autocreate' => '$1 사용자 계정을 자동적으로 만들었습니다.',
-'newuserlog-byemail' => '이메일로 보낸 비밀번호',
 'logentry-rights-rights' => '$1 사용자가 $3 사용자의 권한을 $4에서 $5으로 바꾸었습니다.',
 'logentry-rights-rights-legacy' => '$1 사용자가 $3 사용자의 권한을 바꾸었습니다.',
 'logentry-rights-autopromote' => '$1 사용자의 권한이 자동적으로 $4에서 $5으로 바뀌었습니다.',
@@ -4184,6 +4185,7 @@ $5
 'api-error-ok-but-empty' => '내부 오류: 서버에서 응답이 없습니다.',
 'api-error-overwrite' => '이미 있는 파일을 덮어쓸 수 없습니다.',
 'api-error-stashfailed' => '내부 오류: 서버가 임시 파일을 저장하지 못했습니다.',
+'api-error-publishfailed' => '내부 오류: 서버가 임시 파일을 게시하지 못했습니다.',
 'api-error-timeout' => '서버가 제 시간 내에 응답하지 않았습니다.',
 'api-error-unclassified' => '알 수 없는 오류가 발생했습니다.',
 'api-error-unknown-code' => '알 수 없는 오류: "$1".',
index 37955af..bc23d07 100644 (file)
@@ -39,6 +39,34 @@ $namespaceNames = array(
 // Remove Russian aliases
 $namespaceGenderAliases = array();
 
+$specialPageAliases = array(
+       'Activeusers'               => array( 'Тири_къошулуучула' ),
+       'Allmessages'               => array( 'Системаны_билдириулери' ),
+       'Allpages'                  => array( 'Бютеу_бетле' ),
+       'Blankpage'                 => array( 'Бош_бет' ),
+       'Block'                     => array( 'Блокла' ),
+       'Blockme'                   => array( 'Мени_блокла' ),
+       'Booksources'               => array( 'Китабланы_къайнакълары' ),
+       'BrokenRedirects'           => array( 'Джыртылгъан_редиректле' ),
+       'Categories'                => array( 'Категорияла' ),
+       'ChangeEmail'               => array( 'E-mail_ауушдур' ),
+       'ChangePassword'            => array( 'Пароль_ауушдур' ),
+       'ComparePages'              => array( 'Бетлени_тенглешдириу' ),
+       'Confirmemail'              => array( 'E-mail_тюзлюгюн_бегит' ),
+       'Contributions'             => array( 'Къошум' ),
+       'CreateAccount'             => array( 'Тергеу_джазыуну_къура', 'Къошулуучуну_къура', 'Зарегистрироваться' ),
+       'Deadendpages'              => array( 'Чыкъмазча_бетле' ),
+       'DeletedContributions'      => array( 'Кетерилген_къошум' ),
+       'Disambiguations'           => array( 'Кёб_магъаналы' ),
+       'DoubleRedirects'           => array( 'Экили_редирект' ),
+);
+
+$magicWords = array(
+       'redirect'                  => array( '0', '#джибериу', '#редирект', '#перенаправление', '#перенапр', '#REDIRECT' ),
+       'notoc'                     => array( '0', '__БАШЛАСЫЗ__', '__БЕЗ_ОГЛАВЛЕНИЯ__', '__БЕЗ_ОГЛ__', '__NOTOC__' ),
+       'nogallery'                 => array( '0', '_ГАЛЛЕРЕЯСЫЗ__', '__БЕЗ_ГАЛЕРЕИ__', '__NOGALLERY__' ),
+);
+
 $messages = array(
 # User preference toggles
 'tog-underline' => 'Джибериулени черт:',
@@ -173,6 +201,7 @@ $messages = array(
 'newwindow' => '(джангы терезеде ачылады)',
 'cancel' => 'Ызына алыу',
 'moredotdotdot' => 'Баргъаны…',
+'morenotlisted' => 'Энди джукъ джокъду...',
 'mypage' => 'Бет',
 'mytalk' => 'Сюзюу',
 'anontalk' => 'Бу IP-адресге сюзюу бет',
@@ -472,7 +501,7 @@ $2',
 'gotaccount' => 'Тергеу джазыуугъуз (аккаунтугъуз) энди бармыды? $1.',
 'gotaccountlink' => 'Кириу',
 'userlogin-resetlink' => 'Кирир ючюн билгилеригизни унутхан этгенмисиз?',
-'createaccountmail' => 'e-mail бла',
+'createaccountmail' => 'Эсде болмагъанлай генерация этилген болджаллы паролну хайырландыр эм тюбюрекде берилген электрон почта адресге ий:',
 'createaccountreason' => 'Чурум:',
 'badretype' => 'Джазгъан паролларыгъыз бир-бирине келишмейдиле.',
 'userexists' => 'Джазылгъан ат хайырландырылады.
@@ -1851,6 +1880,9 @@ URL-ни тюз , сайтны ачыкъ болгъанына ишексиз б
 'allpages-bad-ns' => '{{SITENAME}} сайтда «$1» ат алам джокъду.',
 'allpages-hide-redirects' => 'Башха бетлеге джиберген бетлени (редиректлени) джашыр',
 
+# SpecialCachedPage
+'cachedspecial-refresh-now' => 'Ахыр версиягъа къарау.',
+
 # Special:Categories
 'categories' => 'Категорияла',
 'categoriespagetext' => 'Ызындан келген {{PLURAL:$1|категория|категорияла}} бет неда медия-файл тутадыла.
@@ -1916,6 +1948,8 @@ URL-ни тюз , сайтны ачыкъ болгъанына ишексиз б
 'mailnologin' => 'Джиберирге адрес джокъду',
 'mailnologintext' => 'Башха къошулуучулагъа эл. почта джиберелир ючюн [[Special:UserLogin|системагъа кирирге]] керексиз эм [[Special:Preferences|джарашдырыуланы]] бетинде джараулу эл. почта адрес болургъа керекди.',
 'emailuser' => 'Къошулуучугъа письмо',
+'emailuser-title-target' => '{{GENDER:$1|Къошулуучугъа}} электрон джазма джазыу',
+'emailuser-title-notarget' => 'Электрон джазма джазыу',
 'emailpage' => 'Къошулуучугъа письмо джибер',
 'emailpagetext' => 'Бу къошулуучуну почтасына письмо джиберир ючюн бу форманы толтурургъа боллукъсуз.
 Ызына адрес болуб, сиз [[Special:Preferences|джарашдырыуларыгъызда]] джазгъан адрес белгиленникди, ол себебден сизни письмогъузну аллыкъ сизге тюз джууаб берирге мадарлы боллукъду.',
@@ -2081,6 +2115,7 @@ $2 тюрлендирген алгъаракъ версиясына къайты
 'unprotectedarticle' => '«[[$1]]» бетден джакълыкъ алыннганды',
 'movedarticleprotection' => 'Къоруулауну джарашдырыулары "[[$2]]" бетден "[[$1]]" бетге кёчюрюлгенди',
 'protect-title' => '"$1" ючюн къоруулау дараджаны сайлагъыз',
+'protect-title-notallowed' => '«$1» джакълау дараджагъа къара',
 'prot_1movedto2' => '[[$1]] бетни джангы аты: [[$2]]',
 'protect-legend' => 'Къоруулауну къабыл эт',
 'protectcomment' => 'Чурум:',
@@ -2101,6 +2136,7 @@ $2 тюрлендирген алгъаракъ версиясына къайты
 'protect-level-sysop' => 'Къуру администраторла',
 'protect-summary-cascade' => 'каскадлы',
 'protect-expiring' => 'бошалады $1 (UTC)',
+'protect-expiring-local' => '$1 бошалады',
 'protect-expiry-indefinite' => 'болджалсыз',
 'protect-cascade' => 'Бу бетге кирген бетлени джакъла (каскадлы джакълау)',
 'protect-cantedit' => 'Сиз бу бетни джакълау дараджасын тюрлендиреллик тюйюлсюз, бу бетни тюрлендирирге хакъыгъыз болмагъаны ючюн.',
@@ -2235,6 +2271,7 @@ $1',
 
 # Block/unblock
 'block' => 'Къошулуучуну блокла',
+'unblock' => 'Къошулуучуну блок этилиуюн алыу',
 'blockip' => 'Бу къошулуучуну блок эт',
 'blockip-title' => 'Къошулуучуну блокга салыу',
 'blockip-legend' => 'Къошулуучуну блокга салыу',
@@ -2666,6 +2703,8 @@ MediaWiki локализациясына юлюш къошаргъа излей
 'pageinfo-views' => 'Къарауланы саны',
 'pageinfo-watchers' => 'Бетни кёзде тутханланы саны',
 'pageinfo-redirects-name' => 'Бу бетге редиректле',
+'pageinfo-firstuser' => 'Бетле къураучу',
+'pageinfo-lastuser' => 'Ахыр редактор',
 'pageinfo-edits' => 'Бютеу тюрлендириулени саны',
 'pageinfo-authors' => 'Тюрлю-тюрлю авторланы саны',
 'pageinfo-toolboxlink' => 'Бетни юсюнден',
@@ -3520,7 +3559,6 @@ MediaWiki хайырлы боллукъду деген умут бла джай
 'logentry-newusers-create' => '$1 тергеу джазыу (аккаунт) къуралды',
 'logentry-newusers-create2' => '$1, $3 тергеу джазыуну къурады',
 'logentry-newusers-autocreate' => '$1 тергеу джазыу автомат халда къуралды',
-'newuserlog-byemail' => 'пароль электрон почта бла джиберилгенди',
 'logentry-rights-rights' => '$1 къошулуучу, $3 къошулуучуну членлигин $4 къауумдан $5 къауумгъа кёчюрдю',
 'logentry-rights-rights-legacy' => '$1 къошулуучу, $3 къушулуучуну къауумлада членлигин тюрлендирди',
 'logentry-rights-autopromote' => '$1 къошулуучу, $4 къауумдан автомат халда $5 къауумгъа кёчюрюлдю',
index 9f9eefa..e41f898 100644 (file)
@@ -24,6 +24,8 @@ $namespaceNames = array(
        NS_FILE_TALK        => 'فَیِل_بَحَژ',
        NS_MEDIAWIKI        => 'میڈیاوکی',
        NS_MEDIAWIKI_TALK   => 'میڈیاوکی_بَحَژ',
+       NS_TEMPLATE         => 'فرما',
+       NS_TEMPLATE_TALK    => 'فرما_بَحَژ',
        NS_HELP             => 'پَلزُن',
        NS_HELP_TALK        => 'پَلزُن_بَحَژ',
        NS_CATEGORY         => 'زٲژ',
index 99cdd86..0ec0de7 100644 (file)
  * @author Rk_kaul (on ks.wikipedia.org)
  */
 
+$namespaceNames = array(
+       NS_MEDIA            => 'मीडिया',
+       NS_SPECIAL          => 'खास',
+       NS_TALK             => 'बहज़',
+       NS_USER             => 'रुक्न',
+       NS_USER_TALK        => 'रुक्न_बहज़',
+       NS_PROJECT_TALK     => '$1_बहज़',
+       NS_FILE             => 'फ़ाइल',
+       NS_FILE_TALK        => 'फ़ाइल_बहज़',
+       NS_MEDIAWIKI        => 'मीडियाविकि',
+       NS_MEDIAWIKI_TALK   => 'मीडियाविकि_बहज़',
+       NS_TEMPLATE         => 'नमॆना',
+       NS_TEMPLATE_TALK    => 'नमॆना_बहज़',
+       NS_HELP             => 'म॒दत',
+       NS_HELP_TALK        => 'म॒दत_बहज़',
+       NS_CATEGORY         => 'ज़ॉज़',
+       NS_CATEGORY_TALK    => 'ज़ॉज़_बहज़',
+);
+
 $digitTransformTable = array(
        '0' => '०', # &#x0966;
        '1' => '१', # &#x0967;
index d2aeef2..272dc90 100644 (file)
@@ -243,7 +243,7 @@ $messages = array(
 'tog-externaleditor' => 'Nemm jedes Mol en extern Editor-Projramm (Doför bruchs de extra Enstellunge op Dingem Kompjutor. Dat es jet för Fachlück. Doh kanns De [//www.mediawiki.org/wiki/Manual:External_editors mieh drövver lässe])',
 'tog-externaldiff' => 'Nemm jedes Mol en extern Diff-Projramm (Doför bruchs de extra Enstellunge op Dingem Kompjutor. Dat es jet för Fachlück. Doh kanns De [//www.mediawiki.org/wiki/Manual:External_editors mieh drövver lässe])',
 'tog-showjumplinks' => '„Jangk-noh“-Links usjevve, die bei em „Zojang ohne Barrikad“ helfe dun',
-'tog-uselivepreview' => 'Dun de „Lebendije Vör-Aansich“ zeije (em Usprobierstadium, un bruch Java_Skripp)',
+'tog-uselivepreview' => 'Dun de „Lebendije Vör-Aansich“ zeije (bruch Java_Skripp)',
 'tog-forceeditsummary' => 'Froch noh, wann en däm Feld „Koot zosammejefass, Quell“ beim Avspeichere nix dren steiht',
 'tog-watchlisthideown' => 'Dun ming eije Änderunge <strong>nit</strong> en minger Oppassliss aanzeije',
 'tog-watchlisthidebots' => 'Dun jedes Mol dä Bots ehr Änderunge <strong>nit</strong> en minger Oppassliss zeije',
@@ -4106,7 +4106,7 @@ Die Datei weed jlich aanjezeig, odder med däm paßende Projramm op jemaat.",
 'tags-description-header' => 'Bedüggtening',
 'tags-hitcount-header' => 'Makeete Änderunge',
 'tags-edit' => 'ändere',
-'tags-hitcount' => '{{PLURAL:$1|Ein Änderong|$1 Änderonge|kein Änderonge}}',
+'tags-hitcount' => '{{PLURAL:$1|Ein Änderong|$1 Änderonge|Kein Änderonge}}',
 
 # Special:ComparePages
 'comparepages' => 'Sigge verjliesche',
@@ -4176,7 +4176,6 @@ die De häs han welle. Se künnt jet ällder un nit mieh aktoäll sin.',
 'logentry-newusers-create' => 'Dä neue Metmaacher $1 wood aanjelaat.',
 'logentry-newusers-create2' => 'Dä $1 hät dä $3 als ene neue Metmaacher aanjelaat.',
 'logentry-newusers-autocreate' => 'Dä $1 wood automattesch als Metmaacher aanjelaat.',
-'newuserlog-byemail' => 'dat Passwood wood med de e-mail loßjescheck',
 'logentry-rights-rights' => '{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} „$1“ hät däm Metmaacher „$3“ sing Jroppe-Räächde vun „$4“ op „$5“ ömjestallt.',
 'logentry-rights-rights-legacy' => '{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 hät däm Metmaacher $3 sing Räääschte-Jroppe verändert.',
 'logentry-rights-autopromote' => '{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 wood automattesch vum $4 zom $5 jemaat.',
index 89bc6c9..00fc62b 100644 (file)
@@ -662,7 +662,8 @@ Astengkirina dawî bi referansa li jêr hatiye piştrastkirin:',
 'userjspreview' => "'''Zanibe ku tu tenê JavaScript'a xwe diceribînî, ew hê nehatiye tomarkirin!'''",
 'updated' => '(Hate rojanekirin)',
 'note' => "'''Nîşe:'''",
-'previewnote' => "'''Ji bîr neke ku ev bi tenê çavdêriyek e, ev rûpel hîn nehatiye tomarkirin!'''",
+'previewnote' => "'''Ji bîr neke ku ev bi tenê çavdêriyek e.'''
+Ev rûpel hîn nehatiye tomarkirin!",
 'continue-editing' => 'Guhertinê bidomîne',
 'editing' => 'Biguherîne: "$1"',
 'creating' => '$1 tê çêkirin',
@@ -872,6 +873,7 @@ Sedema qedexekirina $3 ev e: ''$2''",
 'datedefault' => 'Tercih tune ne',
 'prefs-beta' => "Taybetmendiyên Beta'yê",
 'prefs-datetime' => 'Dîrok û dem',
+'prefs-user-pages' => 'Rûpelên bikarhêner',
 'prefs-personal' => 'Profîla bikarhêner',
 'prefs-rc' => 'Guherandinên dawî',
 'prefs-watchlist' => 'Lîsteya şopandinê',
@@ -1025,6 +1027,7 @@ Sedema qedexekirina $3 ev e: ''$2''",
 'action-browsearchive' => 'li rûpelên jêbirî bigere',
 'action-undelete' => 'vê rûpelê dîsa çêke',
 'action-userrights' => 'hemû mafên bikarhêneran biguherîne',
+'action-sendemail' => 'e-nameyan bişîne',
 
 # Recent changes
 'nchanges' => '$1 {{PLURAL:$1|guherandinek|guherandin}}',
@@ -1648,6 +1651,7 @@ Sedemekê binivîse!",
 'unblockiptext' => "Nivîsara jêr bikarwîne ji bo qebûlkirina nivîsandinê bikarhênerekî ya IP'yeka berê astengkirî.",
 'ipusubmit' => 'Vê astengkirinê rake',
 'unblocked' => '[[User:$1|$1]] niha vê astengkirinê ye',
+'unblocked-range' => '$1 hat astengkirin.',
 'unblocked-id' => '$1 dîsa vê astengkirinê ye',
 'blocklist' => 'Bikarhênerên astengkirî',
 'ipblocklist' => "Listek ji adresên IP'yan û bikarhêneran yê hatine astengkirin",
@@ -1910,6 +1914,9 @@ Ji ber ku girêdaneke derve di wê rûpelê de heye ev pirsgirêk pêk hat.',
 'bydate' => 'li gor dîrokê',
 'sp-newimages-showfrom' => 'Daneyên nû ji dema $1, saet $2 ve bibîne',
 
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'ago' => 'berî $1',
+
 # Variants for Kurdish language
 'variantname-ku-arab' => 'Tîpên erebî',
 'variantname-ku-latn' => 'Tîpên latînî',
@@ -2032,6 +2039,9 @@ Ji kerema xwe zanibe ku tu bi rastî dixwazî vê rûpelê dîsa çêkî.",
 'confirm_purge_button' => 'Baş e',
 'confirm-purge-top' => 'Bîra vê rûpelê jêbîbe ?',
 
+# action=watch/unwatch
+'confirm-watch-button' => 'Temam',
+
 # Multipage image navigation
 'imgmultipageprev' => '← rûpela berî vê',
 'imgmultipagenext' => 'rûpela din →',
@@ -2141,7 +2151,6 @@ Ji kerema xwe zanibe ku tu bi rastî dixwazî vê rûpelê dîsa çêkî.",
 'logentry-move-move_redir' => '$1 navê $3 guherand û kir $4',
 'logentry-newusers-newusers' => '$1 hesabekî bikarhêneriyê çêkir',
 'logentry-newusers-create' => '$1 hesabekî bikarhêneriyê çêkir',
-'newuserlog-byemail' => 'şîfre bi e-nameyê hate şandin',
 'rightsnone' => '(tune)',
 
 # Feedback
index 8a78f9c..e49779b 100644 (file)
@@ -60,52 +60,150 @@ $namespaceAliases = array(
 );
 
 $specialPageAliases = array(
-       'Allmessages'               => array( 'OllMessajow' ),
-       'Allpages'                  => array( 'OllFolednow' ),
-       'Ancientpages'              => array( 'FolednowKoth' ),
+       'Activeusers'               => array( 'DevnydhyoryonBew' ),
+       'Allmessages'               => array( 'OllMessajys' ),
+       'Allpages'                  => array( 'OllFolennow' ),
+       'Ancientpages'              => array( 'FolennowCoth' ),
        'Badtitle'                  => array( 'TitelDrog' ),
        'Blankpage'                 => array( 'FolenWag' ),
-       'Block'                     => array( 'Lettya' ),
-       'Booksources'               => array( 'PednfentynyowLyver' ),
-       'Categories'                => array( 'Klassys' ),
+       'Block'                     => array( 'Difen' ),
+       'Blockme'                   => array( 'DifenVy' ),
+       'Booksources'               => array( 'PennfentynyowLyver' ),
+       'BrokenRedirects'           => array( 'DaswedyansowTerrys' ),
+       'Categories'                => array( 'Classys' ),
        'ChangeEmail'               => array( 'ChanjyaEbost' ),
        'ChangePassword'            => array( 'ChanjyaGerTremena' ),
+       'ComparePages'              => array( 'KehevelyFolennow' ),
+       'Confirmemail'              => array( 'AfydhyaEbost' ),
        'Contributions'             => array( 'Kevrohow' ),
-       'CreateAccount'             => array( 'FormyaAkont' ),
+       'CreateAccount'             => array( 'FormyaAcont' ),
+       'Deadendpages'              => array( 'FolennowFordhDhall' ),
        'DeletedContributions'      => array( 'KevrohowDiles' ),
-       'EditWatchlist'             => array( 'ChanjyaRolGolyas' ),
+       'Disambiguations'           => array( 'Diamstyryansow' ),
+       'DoubleRedirects'           => array( 'DaswedyansowDewblek' ),
+       'EditWatchlist'             => array( 'ChanjyaOwRolGolyas' ),
        'Emailuser'                 => array( 'EbostyaDevnydhyer' ),
-       'Export'                    => array( 'Esperthi' ),
-       'Import'                    => array( 'Ymperthi' ),
-       'MIMEsearch'                => array( 'HwilansMIME' ),
+       'Export'                    => array( 'Esperthy' ),
+       'Fewestrevisions'           => array( 'AnLyhaAmendyansow' ),
+       'Filepath'                  => array( 'HensAnFolen' ),
+       'Import'                    => array( 'Ymperthy' ),
+       'Invalidateemail'           => array( 'DigomposaEbost' ),
+       'JavaScriptTest'            => array( 'PrevyansJavaScript' ),
+       'BlockList'                 => array( 'RolDhifen' ),
+       'LinkSearch'                => array( 'WhilasKevrennow' ),
+       'Listadmins'                => array( 'RolyaMenystroryon' ),
+       'Listbots'                  => array( 'RolyaBottys' ),
+       'Listfiles'                 => array( 'RolyaRestrennow' ),
+       'Listgrouprights'           => array( 'RolyaGwiryowBagas' ),
+       'Listredirects'             => array( 'RolyaDaswedyansow' ),
+       'Listusers'                 => array( 'RolyaDevnydhyoryon' ),
+       'Lockdb'                    => array( 'AlwhedhaDB' ),
+       'Log'                       => array( 'Covnoten', 'Covnotennow' ),
+       'Lonelypages'               => array( 'FolennowDigoweth' ),
+       'Longpages'                 => array( 'FolennowHir' ),
+       'MergeHistory'              => array( 'IstoryKesunya' ),
+       'MIMEsearch'                => array( 'WhilasMIME' ),
+       'Mostcategories'            => array( 'AnMoyhaClassys' ),
+       'Mostimages'                => array( 'AnMoyhaRestrennowKevennys' ),
+       'Mostinterwikis'            => array( 'AnMoyhaInterwikis' ),
+       'Mostlinked'                => array( 'AnMoyhaFolennowKevrennys' ),
+       'Mostlinkedcategories'      => array( 'AnMoyhaClassysKevrennys' ),
+       'Mostlinkedtemplates'       => array( 'AnMoyhaScantlynsKevrennys' ),
+       'Mostrevisions'             => array( 'AnMoyhaAmendyansow' ),
        'Movepage'                  => array( 'GwayaFolen' ),
        'Mycontributions'           => array( 'OwHevrohow' ),
        'Mypage'                    => array( 'OwFolen' ),
-       'Mytalk'                    => array( 'OwHows' ),
-       'Myuploads'                 => array( 'OwUghkargansow' ),
-       'Newimages'                 => array( 'RestrednowNowyth' ),
-       'Newpages'                  => array( 'FolednowNowyth' ),
+       'Mytalk'                    => array( 'OwHescows' ),
+       'Myuploads'                 => array( 'OwUghcargansow' ),
+       'Newimages'                 => array( 'RestrennowNowyth' ),
+       'Newpages'                  => array( 'FolennowNowyth' ),
        'PasswordReset'             => array( 'DassetyaGerTremena' ),
+       'PermanentLink'             => array( 'KevrenFast' ),
+       'Popularpages'              => array( 'FolennowGerysDa' ),
        'Preferences'               => array( 'Dowisyansow' ),
+       'Prefixindex'               => array( 'MenegvaRagerow' ),
+       'Protectedpages'            => array( 'FolennowDifresys' ),
+       'Protectedtitles'           => array( 'TitlysDifres' ),
        'Randompage'                => array( 'FolenDreJons' ),
+       'Randomredirect'            => array( 'DaswedyansDreJons' ),
        'Recentchanges'             => array( 'Chanjyow_a-dhiwedhes' ),
-       'Search'                    => array( 'Hwilas' ),
-       'Specialpages'              => array( 'FolednowArbednek' ),
-       'Uncategorizedcategories'   => array( 'KlassysHebKlass' ),
-       'Uncategorizedimages'       => array( 'RestrednowHebKlass' ),
-       'Uncategorizedpages'        => array( 'FolednowHebKlass' ),
-       'Uncategorizedtemplates'    => array( 'SkantlynsHebKlass' ),
-       'Upload'                    => array( 'Ughkarga' ),
-       'Userlogin'                 => array( 'Omgelmi' ),
-       'Userlogout'                => array( 'Digelmi' ),
+       'Recentchangeslinked'       => array( 'ChanjyowKelmys' ),
+       'Revisiondelete'            => array( 'DileaAmendyans' ),
+       'Search'                    => array( 'Whilas' ),
+       'Shortpages'                => array( 'FolennowCot' ),
+       'Specialpages'              => array( 'FolennowArbennek' ),
+       'Statistics'                => array( 'Statystygyon' ),
+       'Unblock'                   => array( 'DiswulDifennans' ),
+       'Uncategorizedcategories'   => array( 'ClassysHebClass' ),
+       'Uncategorizedimages'       => array( 'RestrennowHebClass' ),
+       'Uncategorizedpages'        => array( 'FolennowHebClass' ),
+       'Uncategorizedtemplates'    => array( 'ScantlynsHebClass' ),
+       'Undelete'                  => array( 'DiswulDileans' ),
+       'Unlockdb'                  => array( 'DialwhedhaDB' ),
+       'Unusedcategories'          => array( 'ClassysHebDevnydh' ),
+       'Unusedimages'              => array( 'RestrennowHebDevnydh' ),
+       'Unusedtemplates'           => array( 'ScantlynsHebDevnydh' ),
+       'Unwatchedpages'            => array( 'FolennowHebAgaHolyas' ),
+       'Upload'                    => array( 'Ughcarga' ),
+       'Userlogin'                 => array( 'Omgelmy' ),
+       'Userlogout'                => array( 'Digelmy' ),
        'Userrights'                => array( 'GwiryowDevnydhyer' ),
        'Version'                   => array( 'Versyon' ),
-       'Wantedcategories'          => array( 'KlassysHwansus' ),
-       'Wantedfiles'               => array( 'RestrednowHwansus' ),
-       'Wantedpages'               => array( 'FolednowHwansus' ),
-       'Wantedtemplates'           => array( 'SkantlynsHwansus' ),
+       'Wantedcategories'          => array( 'ClassysWhansus' ),
+       'Wantedfiles'               => array( 'RestrennowWhansus' ),
+       'Wantedpages'               => array( 'FolennowWhansus' ),
+       'Wantedtemplates'           => array( 'ScantlynsWhansus' ),
        'Watchlist'                 => array( 'Rol_golyas' ),
-       'Whatlinkshere'             => array( 'OwKevrednaObma' ),
+       'Whatlinkshere'             => array( 'OwKevrennaOmma' ),
+       'Withoutinterwiki'          => array( 'HebInterwiki' ),
+);
+
+$magicWords = array(
+       'redirect'                  => array( '0', '#DASWEDYANS', '#REDIRECT' ),
+       'numberofpages'             => array( '1', 'NIVERAFOLENNOW', 'NUMBEROFPAGES' ),
+       'numberofarticles'          => array( '1', 'NIVERAERTHYGLOW', 'NUMBEROFARTICLES' ),
+       'numberoffiles'             => array( '1', 'NIVERARESTRENNOW', 'NUMBEROFFILES' ),
+       'numberofusers'             => array( '1', 'NIVERADHEVNYDHYORYON', 'NUMBEROFUSERS' ),
+       'numberofactiveusers'       => array( '1', 'NIVERADHEVNYDHYORYONVEW', 'NUMBEROFACTIVEUSERS' ),
+       'numberofedits'             => array( '1', 'NIVERAJANJYOW', 'NUMBEROFEDITS' ),
+       'numberofviews'             => array( '1', 'NIVERAWELOW', 'NUMBEROFVIEWS' ),
+       'pagename'                  => array( '1', 'HANOWANFOLEN', 'PAGENAME' ),
+       'fullpagename'              => array( '1', 'HANOWLEUNANFOLEN', 'FULLPAGENAME' ),
+       'img_thumbnail'             => array( '1', 'skeusennik', 'thumbnail', 'thumb' ),
+       'img_manualthumb'           => array( '1', 'skeusennik=$1', 'thumbnail=$1', 'thumb=$1' ),
+       'img_right'                 => array( '1', 'dyhow', 'right' ),
+       'img_left'                  => array( '1', 'cledh', 'left' ),
+       'img_none'                  => array( '1', 'nagonan', 'none' ),
+       'img_center'                => array( '1', 'cresel', 'center', 'centre' ),
+       'img_framed'                => array( '1', 'fremys', 'framed', 'enframed', 'frame' ),
+       'img_frameless'             => array( '1', 'hebfram', 'frameless' ),
+       'img_page'                  => array( '1', 'folen=$1', 'folen_$1', 'page=$1', 'page $1' ),
+       'img_top'                   => array( '1', 'gwartha', 'top' ),
+       'img_text_top'              => array( '1', 'text-gwartha', 'text-top' ),
+       'img_middle'                => array( '1', 'cres', 'middle' ),
+       'img_bottom'                => array( '1', 'goles', 'bottom' ),
+       'img_text_bottom'           => array( '1', 'text-goles', 'text-bottom' ),
+       'img_link'                  => array( '1', 'kevren=$1', 'link=$1' ),
+       'sitename'                  => array( '1', 'HANOWANWIASVA', 'SITENAME' ),
+       'pageid'                    => array( '0', 'IDANFOLEN', 'PAGEID' ),
+       'server'                    => array( '0', 'SERVYER', 'SERVER' ),
+       'servername'                => array( '0', 'HANOWANSERVYER', 'SERVERNAME' ),
+       'grammar'                   => array( '0', 'GRAMASEK:', 'GRAMMAR:' ),
+       'fullurl'                   => array( '0', 'URLLEUN:', 'FULLURL:' ),
+       'displaytitle'              => array( '1', 'DISQWEDHESANTITEL', 'DISPLAYTITLE' ),
+       'language'                  => array( '0', '#YETH:', '#LANGUAGE:' ),
+       'numberofadmins'            => array( '1', 'NIVERAVENYSTRORYON', 'NUMBEROFADMINS' ),
+       'special'                   => array( '0', 'arbennek', 'special' ),
+       'filepath'                  => array( '0', 'HENSANFOLEN:', 'FILEPATH:' ),
+       'hiddencat'                 => array( '1', '__CLASSCUDHYS__', '__HIDDENCAT__' ),
+       'pagesincategory'           => array( '1', 'RESTRENNOWYNCLASS', 'PAGESINCATEGORY', 'PAGESINCAT' ),
+       'pagesize'                  => array( '1', 'MENSANRESTREN', 'PAGESIZE' ),
+       'index'                     => array( '1', '__MENEGVA__', '__INDEX__' ),
+       'noindex'                   => array( '1', '__HEBMENEGVA__', '__NOINDEX__' ),
+       'numberingroup'             => array( '1', 'NIVERYNBAGAS', 'NUMBERINGROUP', 'NUMINGROUP' ),
+       'url_path'                  => array( '0', 'HENS', 'PATH' ),
+       'pagesincategory_all'       => array( '0', 'oll', 'all' ),
+       'pagesincategory_pages'     => array( '0', 'folennow', 'pages' ),
 );
 
 $messages = array(
index a955942..929b697 100644 (file)
@@ -1751,7 +1751,6 @@ HTML-тегдеринин тууралыгын текшериңиз.',
 'logentry-newusers-create' => '$1 эсеп жазуусу жаратылды',
 'logentry-newusers-create2' => '$1 эсеп жазуусун жаратты',
 'logentry-newusers-autocreate' => 'Автоматтуу түрдө $1 эсеп жазуусу жаратылды',
-'newuserlog-byemail' => 'сырсөз эл. почта аркылуу жөнөтүлдү',
 'rightsnone' => '(жок)',
 
 # Feedback
index a5f9dd7..e7a1a67 100644 (file)
@@ -13,6 +13,7 @@
  * @author Esteban97
  * @author Kaganer
  * @author LeighvsOptimvsMaximvs
+ * @author MF-Warburg
  * @author McDutchie
  * @author MissPetticoats
  * @author Omnipaedista
@@ -1650,7 +1651,7 @@ Si pagina nova cum ipso nomine post deletionem creata est, emendationes restitut
 'blanknamespace' => '(principale)',
 
 # Contributions
-'contributions' => 'Conlationes usoris',
+'contributions' => 'Conlationes {{GENDER:$1|usoris}}',
 'contributions-title' => 'Conlationes usoris $1',
 'mycontris' => 'Conlationes',
 'contribsub2' => 'Pro $1 ($2)',
@@ -1968,6 +1969,20 @@ Paginae nomen petitum "[[:$1]]" iam existit. Vin tu eam delere ut pagina illic m
 'siteusers' => '{{PLURAL:$2|usor|usores}} {{grammar:genitive|{{SITENAME}}}} $1',
 'creditspage' => 'Auctores paginae',
 
+# Info page
+'pageinfo-title' => 'Res quae ad "$1" pertinent',
+'pageinfo-header-basic' => 'De hac pagina',
+'pageinfo-display-title' => 'Titulus ut in pagina ipsa monstratur',
+'pageinfo-length' => 'Magnitudo paginae (octeti)',
+'pageinfo-article-id' => 'Identificatio paginis',
+'pageinfo-language' => 'Lingua verborum in pagina',
+'pageinfo-firstuser' => 'Creator paginae',
+'pageinfo-firsttime' => 'Dies et tempus creationis paginae',
+'pageinfo-lastuser' => 'Usor qui ultimam recensionem fecit',
+'pageinfo-lasttime' => 'Dies ultimae emendationis',
+'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoria celata|Categoriae celatae}} ($1)',
+'pageinfo-toolboxlink' => 'De hac pagina',
+
 # Skin names
 'skinname-standard' => 'Norma',
 'skinname-cologneblue' => 'Caerulus Colonia',
@@ -2338,7 +2353,7 @@ Quaesumus, adfirma ut iterum hanc paginam crees.",
 'specialpages-group-users' => 'Usores eorumque potestates',
 'specialpages-group-pages' => 'Indices paginarum',
 'specialpages-group-pagetools' => 'Instrumenta paginarum',
-'specialpages-group-wiki' => 'Vici-data et instrumenta',
+'specialpages-group-wiki' => 'Data et instrumenta',
 'specialpages-group-redirects' => 'Paginae speciales redirigentes',
 'specialpages-group-spam' => 'Instrumenta contra praeconia incommoda',
 
@@ -2374,7 +2389,6 @@ Quaesumus, adfirma ut iterum hanc paginam crees.",
 'logentry-newusers-create' => 'Ratio usoris $1 creata est',
 'logentry-newusers-create2' => 'Ratio usoris $3 creata est ab usore $1',
 'logentry-newusers-autocreate' => 'Ratio $1 automatice creata est',
-'newuserlog-byemail' => 'tessera missa litteris electronicis',
 'rightsnone' => '(nullus)',
 
 # Search suggestions
index 3b6c0df..e1080cf 100644 (file)
@@ -1279,7 +1279,6 @@ Los otros campos se van a guardar por defecto.
 
 # New logging system
 'logentry-newusers-autocreate' => 'El cuento $1 fue crîado otomatika mente',
-'newuserlog-byemail' => 'kóddiche mandado con letral',
 
 # Feedback
 'feedback-subject' => 'Sujeto',
index 314f328..9be20ea 100644 (file)
@@ -11,6 +11,7 @@
  * @author Kaffi
  * @author Kaganer
  * @author Les Meloures
+ * @author MF-Warburg
  * @author Purodha
  * @author Reedy
  * @author Robby
@@ -156,7 +157,7 @@ $magicWords = array(
        'pagename'                  => array( '1', 'Säitennumm', 'SEITENNAME', 'PAGENAME' ),
        'namespace'                 => array( '1', 'Nummraum', 'NAMENSRAUM', 'NAMESPACE' ),
        'subjectspace'              => array( '1', 'Haaptnummraum', 'HAUPTNAMENSRAUM', 'SUBJECTSPACE', 'ARTICLESPACE' ),
-       'subjectpagename'           => array( '1', 'Haaptsäit', 'HAUPTSEITE', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ),
+       'subjectpagename'           => array( '1', 'Haaptsäit', 'HAUPTSEITE', 'HAUPTSEITENNAME', 'VORDERSEITE', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ),
        'img_thumbnail'             => array( '1', 'Miniatur', 'miniatur', 'mini', 'thumbnail', 'thumb' ),
        'img_right'                 => array( '1', 'riets', 'rechts', 'right' ),
        'img_left'                  => array( '1', 'lénks', 'links', 'left' ),
@@ -175,8 +176,8 @@ $magicWords = array(
        'formatnum'                 => array( '0', 'ZUELEFORMAT', 'ZAHLENFORMAT', 'FORMATNUM' ),
        'special'                   => array( '0', 'spezial', 'special' ),
        'hiddencat'                 => array( '1', '__VERSTOPPT_KATEGORIE__', '__VERSTECKTE_KATEGORIE__', '__WARTUNGSKATEGORIE__', '__HIDDENCAT__' ),
-       'pagesincategory_pages'     => array( '0', 'Säiten', 'pages' ),
-       'pagesincategory_files'     => array( '0', 'Fichieren', 'files' ),
+       'pagesincategory_pages'     => array( '0', 'Säiten', 'seiten', 'pages' ),
+       'pagesincategory_files'     => array( '0', 'Fichieren', 'dateien', 'files' ),
 );
 
 $messages = array(
@@ -615,7 +616,7 @@ Vergiesst net fir Är [[Special:Preferences|{{SITENAME}} Astellungen]] z'ännere
 'gotaccount' => "Dir hutt schonn e Benotzerkont? '''$1'''.",
 'gotaccountlink' => 'Umellen',
 'userlogin-resetlink' => "Hutt Dir d'Detailer vun Ärem Login vergiess?",
-'createaccountmail' => 'Via E-Mail',
+'createaccountmail' => 'En temporäert Passwuert benotzen an et per E-Mail un déi E-Mailadress schécken déi hei drënner steet',
 'createaccountreason' => 'Grond:',
 'badretype' => 'Är Passwierder stëmmen net iwwerdeneen.',
 'userexists' => 'De Benotzernumm deen agi gouf gëtt scho benotzt.
@@ -690,6 +691,7 @@ Waart w.e.g. ier Dir et nach eng Kéier versicht.",
 # E-mail sending
 'php-mail-error-unknown' => 'Onbekannte Feeler an der PHP-Mail-Fonctioun',
 'user-mail-no-addy' => 'Huet versicht eng Mail ouni Mailadress ze schécken',
+'user-mail-no-body' => 'Et gouf probéiert eng E-Mail ouni Text oder mat engem ze kuerzen Text ze schécken.',
 
 # Change password dialog
 'resetpass' => 'Passwuert änneren',
@@ -910,11 +912,12 @@ Dir verspriecht ausserdeem datt Dir dësen Text selwer verfaasst hutt, oder aus
 'copyrightwarning2' => "W.e.g. notéiert datt all Kontributiounen op {{SITENAME}} vun anere Benotzer verännert oder geläscht kënne ginn. Wann dir dat net wëllt, da setzt näischt heihinner.<br />
 Dir verspriecht ausserdeem datt dir dësen Text selwer verfaasst hutt, oder aus dem Domaine public oder anere fräie Quelle kopéiert hutt. (cf. $1 fir méi Detailler). '''DROT KEE COPYRECHTLECH GESCHÜTZTE CONTENU AN!'''",
 'longpageerror' => "'''FEELER: Den Text, den Dir Versicht ze späicheren, huet {{PLURAL:$1|1 Kilobyte|$1 Kilobytes}}. Dëst ass méi wéi den erlaabte Maximum vun  {{PLURAL:$2|1 Kilobyte|$2 Kilobytes}}''' Dofir kann den Text net gespäichert ginn.",
-'readonlywarning' => "'''OPGEPASST: D'Datebank gouf wéinst Maintenanceaarbechte fir Säitenännerunge gespaart, dofir kënnt Dir déi Säit den Ament net ofspäicheren. Versuergt den Text a versicht d'Ännerunge méi spéit nach emol ze maachen.'''
+'readonlywarning' => "'''OPGEPASST: D'Datebank gouf wéinst Maintenanceaarbechte gespaart, dofir kënnt Dir Är Ännerungen den Ament net ofspäicheren.'''
+Dir kënnt den Text kopéieren an an een Textfichier drasetzen an deen ofspäicheren fir méi spéit.
 
 Den Administrateur den d'Datebank gespaart huet, huet dës Erklärung ginn: $1",
 'protectedpagewarning' => "'''OPGEPASST: Dës Säit gouf gespaart a kann nëmme vun engem Administrateur geännert ginn.''' Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
-'semiprotectedpagewarning' => "'''Bemierkung:''' Dës Säit gouf esou gespaart, datt nëmme ugemellte Benotzer s'ännere kënnen. Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
+'semiprotectedpagewarning' => "'''Bemierkung:''' Dës Säit gouf esou gespaart, datt nëmme ugemellt Benotzer s'ännere kënnen. Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
 'cascadeprotectedwarning' => "'''Passt op:''' Dës Säit gouf gespaart a kann nëmme vu Benotzer mat Administreursrechter geännert ginn. Si ass an dës {{PLURAL:$1|Säit|Säiten}} agebonnen, déi duerch Cascadespäroptioun gespaart {{PLURAL:$1|ass|sinn}}:'''",
 'titleprotectedwarning' => "'''OPGEPASST: Dës Säit gouf gespaart sou datt [[Special:ListGroupRights|spezifesch Rechter]] gebraucht gi fir se uleeën ze kënnen.''' Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
 'templatesused' => '{{PLURAL:$1|Schabloun|Schablounen}} déi op dëser Säit am Gebrauch sinn:',
@@ -1203,7 +1206,7 @@ Denkt w.e.g drunn datt d'Navigatiounslinken d'Wiel vun de Versiounen nees zréck
 'search-interwiki-default' => '$1 Resultater:',
 'search-interwiki-more' => '(méi)',
 'search-relatedarticle' => 'A Verbindung',
-'mwsuggest-disable' => 'Ajax-Virschléi ausschalten',
+'mwsuggest-disable' => 'Sich-Virschléi ausschalten',
 'searcheverything-enable' => 'An allen Nummraim sichen',
 'searchrelated' => 'a Verbindng',
 'searchall' => 'all',
@@ -1519,7 +1522,7 @@ Si muss manner wéi $1 {{PLURAL:$1|Zeechen|Zeechen}} hunn.',
 'rclistfrom' => 'Nei Ännerunge vu(n) $1 u weisen',
 'rcshowhideminor' => 'Kleng Ännerunge $1',
 'rcshowhidebots' => 'Botte $1',
-'rcshowhideliu' => 'Ugemellte Benotzer $1',
+'rcshowhideliu' => 'Ugemellt Benotzer $1',
 'rcshowhideanons' => 'Anonym Benotzer $1',
 'rcshowhidepatr' => 'iwwerwaacht Ännerunge $1',
 'rcshowhidemine' => 'Meng Ännerunge $1',
@@ -2083,7 +2086,7 @@ Et muss mindestens en Top-Level-Domaine ugi ginn, wéi z. Bsp. ".org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Lëscht vun den aktive Benotzer',
 '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|Ännerung|Ännerungen}} {{PLURAL:$3|gëschter|an de leschten $3 Deeg}}',
+'activeusers-count' => '$1 {{PLURAL:$1|Aktioun|Aktiounen}} {{PLURAL:$3|gëschter|an de leschten $3 Deeg}}',
 'activeusers-from' => 'Benotzer weisen, ugefaang bäi:',
 'activeusers-hidebots' => 'Botte verstoppen',
 'activeusers-hidesysops' => 'Administrateure verstoppen',
@@ -2146,7 +2149,7 @@ D\'E-Mailadress, déi Dir an [[Special:Preferences|Ären Astellungen]] aginn hut
 'usermessage-editor' => 'Benoriichtegungs-System',
 
 # Watchlist
-'watchlist' => 'Meng Iwwerwaachungslëscht',
+'watchlist' => 'Iwwerwaachungslëscht',
 'mywatchlist' => 'Iwwerwaachungslëscht',
 'watchlistfor2' => 'Vum $1 $2',
 'nowatchlist' => 'Är Iwwerwaachungslëscht ass eidel.',
@@ -2195,9 +2198,7 @@ All weider Ännerungen op dëser Säit an der assoziéierter Diskussiounssäit g
 'enotif_anon_editor' => 'Anonyme Benotzer $1',
 'enotif_body' => 'Léiwe $WATCHINGUSERNAME,
 
-D\'{{SITENAME}}-Säit "$PAGETITLE" gouf vum $PAGEEDITOR den $PAGEEDITDATE $CHANGEDORCREATED. Aktuell Versioun: $PAGETITLE_URL
-
-$NEWPAGE
+$PAGEINTRO $NEWPAGE
 
 Resumé vum Mataarbechter: $PAGESUMMARY $PAGEMINOREDIT
 
@@ -2206,21 +2207,22 @@ E-Mail: $PAGEEDITOR_EMAIL
 Wiki: $PAGEEDITOR_WIKI
 
 Et gi soulaang keng weider Maile geschéckt, bis Dir d\'Säit nees emol besicht hutt.
-Op Ärer Iwwerwaachungslëscht kënnt Dir all Benoorichtigungsmarkeren zesummen zrécksetzen.
+Op Ärer Iwwerwaachungslëscht kënnt Dir all Benoorichtigungsmarkeren zesummen zErécksetzen.
 
 
-             Äre frëndleche {{SITENAME}} Benoriichtigungssystem
+Äre frëndleche {{SITENAME}} Benoriichtigungssystem
 
 --
 
-Fir d\'Astellungen op Ã¤ren E-Mailbenoriichtigungen z\'änneren, besicht w.e.g.
+Fir d\'Astellungen op Ã\84ren E-Mailbenoriichtigungen z\'änneren, besicht w.e.g.
 {{canonicalurl:{{#special:Preferences}}}}
 
 
-Fir d\'Astellungen vun Ã¤rer Iwwerwaachungslëscht z\'änneren, besicht w.e.g.
+Fir d\'Astellungen vun Ã\84rer Iwwerwaachungslëscht z\'änneren, besicht w.e.g.
 {{canonicalurl:Special:Watchlist/edit}}
 
-
+Feedback a weider Hëllef:
+{{canonicalurl:{{MediaWiki:Helppage}}}}
 Fir d\'Säit vun Ärer Iwwerwaachungslëscht erofzehuelen, gitt w.e.g. op
 $UNWATCHURL
 
@@ -2349,7 +2351,7 @@ Hei sinn déi aktuell Astellunge fir d'Säit '''$1''':",
 
 # Restriction levels
 'restriction-level-sysop' => 'ganz gespaart',
-'restriction-level-autoconfirmed' => 'hallef-gespaart (nëmmen ugemellte Benotzer déi net nei sinn)',
+'restriction-level-autoconfirmed' => 'hallef gespaart (nëmmen ugemellt Benotzer déi net nei sinn)',
 'restriction-level-all' => 'alleguerten',
 
 # Undelete
@@ -2411,7 +2413,7 @@ $1',
 'blanknamespace' => '(Haapt)',
 
 # Contributions
-'contributions' => 'Kontributioune vum Benotzer $1',
+'contributions' => '{{GENDER:$1|Benotzer}}kontributiounen',
 'contributions-title' => 'Kontributioune vum $1',
 'mycontris' => 'Kontributiounen',
 'contribsub2' => 'Fir $1 ($2)',
@@ -2508,8 +2510,8 @@ Kuckt d'[[Special:BlockList|Spär-Lëscht]] fir all Spären nozekucken.",
 'unblocked' => "D'Spär fir de [[User:$1|Benotzer $1]] gouf opgehuewen",
 'unblocked-range' => "D'Spär vum $1 gouf opgehuewen",
 'unblocked-id' => "D'Spär $1 gouf opgehuewen",
-'blocklist' => 'Gespaarte Benotzer',
-'ipblocklist' => 'Gespaarte Benotzer',
+'blocklist' => 'Gespaart Benotzer',
+'ipblocklist' => 'Gespaart Benotzer',
 'ipblocklist-legend' => 'No engem gespaarte Benotzer sichen',
 'blocklist-userblocks' => 'Benotzerspäre verstoppen',
 'blocklist-tempblocks' => 'Temporär Späre verstoppen',
@@ -2607,18 +2609,18 @@ Fir d'Datebank ze spären oder fir d'Spär opzehiewen muss dëse Fichier vum Web
 # Move page
 'move-page' => 'Réckel $1',
 'move-page-legend' => 'Säit réckelen',
-'movepagetext' => "Wann dir dëse Formulaire benotzt, réckelt dir eng komplett Säit mat hirem Historique op en neien Numm.
-Den alen Titel déngt als Viruleedung op déi nei Säit.
+'movepagetext' => "Wann dir dëse Formulaire benotzt gitt Dir enger Säit en aneren Numm a réckelt se mat hirem Historique op den neien Numm.
+Den alen Titel gëtt eng Viruleedung op déi nei Säit.
 Dir kënnt Viruleedungen déi op déi al Säit ginn automatesch aktualiséieren.
-Wann Dir dat net maacht, da vergewëssert iech datt keng [[Special:DoubleRedirects|duebel]] oder [[Special:BrokenRedirects|futtis Viruleedungen]] am Spill sinn.
-Dir sidd responsabel datt d'Linke weiderhinn dohinner pointéieren, wou se hi sollen.
+Wann Dir dat net maacht, da vergewëssert Iech datt keng [[Special:DoubleRedirects|duebel]] oder [[Special:BrokenRedirects|futtis Viruleedungen]] am Spill sinn.
+Dir sidd responsabel datt d'Linke weiderhin dohinner pointéieren, wou se hi sollen.
 
 Beuecht w.e.g. datt d'Säit '''net''' geréckelt gëtt, wann et schonns eng Säit mat deem Titel gëtt, ausser déi ass eidel, ass eng Viruleedung oder huet keen Historique.
-Dëst bedeit datt dir eng Säit ëmbenenne kënnt an datt dir keng Säit iwwerschreiwe kënnt, déi et schonns gëtt.
+Dëst bedeit datt dir eng Säit zréck op hiren ursprénglechen Numm ëmbenenne kënnt wann Dir Iech geiert hat an datt Dir keng Säit iwwerschreiwe kënnt, déi et schonns gëtt.
 
 '''OPGEPASST!'''
 Dëst kann en drastesche Changement fir eng populär Säit bedeiten;
-verstitt w.e.g. d'Konsequenze vun Ã¤rer Handlung Ã©ier Dir d'Säit réckelt.",
+verstitt w.e.g. d'Konsequenze vun Ã\84rer Handlung Ã©ier Dir dëst maacht.",
 'movepagetext-noredirectfixer' => "Wann Dir dëse Formulaire benotzt, réckelt dir eng komplett Säit mat hirem Historique op en neien Numm.
 Den alen Titel gëtt eng Viruleedung op den neien Titel.
 Dir kënnt Viruleedungen déi op déi al Säit ginn automatesch aktualiséieren.
@@ -2791,6 +2793,7 @@ Späichert en op Ärem Computer of a luet en hei nees erop.',
 'import-error-interwiki' => 'D\'Säit  "$1" gouf net importéiert well deen Numm fir extern Linken (Interwiki) reservéiert ass.',
 'import-error-special' => 'D\'Säit "$1" gouf net importéiert well se zu engem speziellen Nummraum gehéiert an deem et keng Säite gëtt.',
 'import-error-invalid' => 'D\'Säit "$1" gouf net importéiert well hiren Numm net valabel ass.',
+'import-error-unserialize' => 'D\'Versioun $2 vun der Säit "$1" konnt net deserialiséiert ginn. Et gouf uginn datt déi Versioun den Inhaltsmodell $3 benotzt deen als $4 serialiséiert ass.',
 'import-options-wrong' => 'Falsch {{PLURAL:$2|Optioun|Optiounen}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Déi Basis-Säit déi Dir uginn hutt ass kee valabelen Titel.',
 'import-rootpage-nosubpage' => 'Am Nummraum "$1" vun der Basis-Säit si keng Ënnersäiten erlaabt.',
@@ -2932,9 +2935,12 @@ Dëst warscheinlech duerch en externe Link den op der schwaarzer Lëscht (blackl
 'pageinfo-length' => 'Gréisst vun der Säit (a Bytes)',
 'pageinfo-article-id' => 'ID (Nummer) vun der Säit',
 'pageinfo-language' => 'Sprooch vum Inhalt vun der Säit',
+'pageinfo-robot-policy' => 'Sichmaschinnestatus',
+'pageinfo-robot-index' => 'Indexéierbar',
 'pageinfo-robot-noindex' => 'Net indexéierbar',
 'pageinfo-views' => 'Zuel vun de Kéieren déi dës Säit gekuckt gouf',
 'pageinfo-watchers' => "Zuel vun de Benotzer déi d'Säit iwwerwaachen",
+'pageinfo-few-watchers' => 'Manner wéi $1 {{PLURAL:$1|Benotzer deen iwwerwaacht|Benotzer déi iwwerwaachen}}',
 'pageinfo-redirects-name' => 'Viruleedungen op dës Säit',
 'pageinfo-subpages-name' => 'Ënnersäite vun dëser Säit',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|Viruleedung|Viruleedungen}}; $3 {{PLURAL:$3|Ënnersäit|Ënnersäiten}})',
@@ -2949,6 +2955,7 @@ Dëst warscheinlech duerch en externe Link den op der schwaarzer Lëscht (blackl
 'pageinfo-magic-words' => '{{PLURAL:$1|Magescht Wuert|Magesch Wierder}} ($1)',
 'pageinfo-hidden-categories' => 'Verstoppte {{PLURAL:$1|Kategorie|Kategorien}} ($1)',
 'pageinfo-templates' => 'Agebonne {{PLURAL:$1|Schabloun|Schabloune}} ($1)',
+'pageinfo-transclusions' => 'Agebonnen {{PLURAL:$1|an eng Säit|a(n) $1 Säiten}}',
 'pageinfo-toolboxlink' => "Informatiounen iwwert d'Säit",
 'pageinfo-redirectsto' => 'Viruleedung op',
 'pageinfo-redirectsto-info' => 'Informatioun',
@@ -3681,7 +3688,7 @@ Den ugefrote Fichier gëtt direkt gewise respektiv mat enger verbonner Applikati
 'specialpages-group-highuse' => 'Dacks benotzte Säiten',
 'specialpages-group-pages' => 'Lëschte vu Säiten',
 'specialpages-group-pagetools' => 'Handwierksgeschir fir Säiten',
-'specialpages-group-wiki' => 'Systemdaten an Handwierksgeschir',
+'specialpages-group-wiki' => 'Daten an Handwierksgeschir',
 'specialpages-group-redirects' => 'Spezialsäiten déi viruleeden',
 'specialpages-group-spam' => 'Handwierksgeschir géint de Spam',
 
@@ -3775,8 +3782,8 @@ Den ugefrote Fichier gëtt direkt gewise respektiv mat enger verbonner Applikati
 'logentry-newusers-newusers' => 'De Benotzerkont $1 gouf ugeluecht',
 'logentry-newusers-create' => 'De Benotzerkont $1 gouf ugeluecht',
 'logentry-newusers-create2' => 'De Benotzerkont $3 gouf vum $1 ugeluecht',
+'logentry-newusers-byemail' => "De Benotzerkont $3 gouf vum $1 ugeluecht an d'Passwuert gouf per E-Mail geschéckt.",
 'logentry-newusers-autocreate' => 'De Benotzerkont $1 gouf automatesch ugeluecht',
-'newuserlog-byemail' => "d'Passwuert gouf per E-Mail geschéckt",
 'logentry-rights-autopromote' => "De Benotzer $1 huet d'Benotzerrechter automatesch vu(n) $4 op $5 geännert",
 'rightsnone' => '(keen)',
 
@@ -3832,6 +3839,7 @@ Soss kënnt Dir den einfache Formulär hei drënner benotzen. Är Bemierkung gë
 'api-error-ok-but-empty' => 'Interne Feeler: keng Äntwert vum Server.',
 'api-error-overwrite' => "D'Iwwerschreiwe vun engem Fichier ass net erlaabt.",
 'api-error-stashfailed' => 'Interne Feeler: de Server konnt den temporäre Fichier net späicheren.',
+'api-error-publishfailed' => 'Interne Feeler: de Server konnt den temporäre Fichier net publizéieren.',
 'api-error-timeout' => 'De Server huet net bannen där Zäit geäntwert déi virgesinn ass.',
 'api-error-unclassified' => 'En onbekannte Feeler ass geschitt',
 'api-error-unknown-code' => 'Onbekannte Feeler: "$1"',
index 4863025..c878725 100644 (file)
@@ -279,7 +279,7 @@ $messages = array(
 'nstab-main' => 'Ччин',
 'nstab-user' => 'Уртахдин ччин',
 'nstab-media' => 'Медия ччин',
-'nstab-special' => 'Куьмекчи ччин',
+'nstab-special' => 'Квимекдин ччин',
 'nstab-project' => 'Проектдин ччин',
 'nstab-image' => 'Файл',
 'nstab-mediawiki' => 'Малумат',
@@ -398,7 +398,7 @@ $messages = array(
 'subject' => 'Тема/кьилинцIар',
 'minoredit' => 'ГъвечIи дуьзар хъувун',
 'watchthis' => 'И ччин гуьзетун',
-'savearticle' => 'ЧÑ\87ин Ñ\85Ñ\83Ñ\8cн',
+'savearticle' => 'ЧÑ\8aин Ñ\85вин',
 'preview' => 'Сифтедин килигун',
 'showpreview' => 'Сифтедин килигун къалурун',
 'showlivepreview' => 'Фад сифтедин килигун',
@@ -523,7 +523,7 @@ $messages = array(
 'revertmerge' => 'Ччара авун',
 
 # Diffs
-'history-title' => 'Masak\'avilerin q\'isa "$1"',
+'history-title' => '$1  -  масакӀавилерин тарих',
 'lineno' => 'ЦIар $1:',
 'compareselectedversions' => 'Хкягъай жуьреяр гекъигун',
 'editundo' => 'гьич авун',
@@ -597,7 +597,7 @@ $messages = array(
 'prefs-edits' => 'Дьузар хъувунрин кьадар',
 'prefsnologin' => 'Куьне гьахьнавач',
 'changepassword' => 'Парол дегишарун',
-'prefs-skin' => 'КЪайдадиз ттунин тема',
+'prefs-skin' => 'Къайдадиз ттунин тема',
 'skin-preview' => 'Сифтедин килигун',
 'datedefault' => 'Туькlуьрмир',
 'prefs-beta' => 'Бета-мумкинвилер',
@@ -613,7 +613,7 @@ $messages = array(
 'prefs-changeemail' => 'Э-почта дегишарун',
 'prefs-setemail' => 'Э-почта эцигна туькIуьрун',
 'prefs-email' => 'E-mail туькlуьрунин кьадарар',
-'prefs-rendering' => 'КЪецепатан  акунар',
+'prefs-rendering' => 'Къецепатан акунар',
 'saveprefs' => 'Хуьн',
 'resetprefs' => 'Хуьн тавунвай дегишвилер алудун',
 'restoreprefs' => 'Авайл хьиз кьунвай низамарунар туькIуьр хъувун',
@@ -749,7 +749,7 @@ $messages = array(
 'recentchangeslinked-toolbox' => 'Галкlанвай масакIавилер',
 'recentchangeslinked-title' => '"$1" галаз галкlанавай масакIавилер',
 'recentchangeslinked-noresult' => 'Ганвай чlава галкlанавай ччинра са масакIавални хьанвайд туш',
-'recentchangeslinked-summary' => 'Им къалурай ччиниз (ва я къалурай категориядиз гьатзавай ччинриз) элячIзавай ччинра мукьвара хьайи масакIавилерин сиягь я. Куь [[Special:Watchlist| вилив хуьнин сиягь ]]диз гьатзавай  ччинар яцlу шрифтдал къалурнава.',
+'recentchangeslinked-summary' => 'Им къалурай ччиниз (ва я къалурай категориядиз гьатзавай ччинриз) элячӀзавай ччинра мукьвара хьайи масакӀавилерин сиягь я. Куь [[Special:Watchlist|вилив хуьнин сиягь диз]] гьатзавай ччинар яцӀу шрифтдал къалурнава.',
 'recentchangeslinked-page' => 'Ччинин тlвар:',
 'recentchangeslinked-to' => 'Аксина, къалурай ччиниз элячlзавай ччинра масакIавилер къалура',
 
@@ -1054,7 +1054,7 @@ $messages = array(
 'whatlinkshere-hideredirs' => '$1 рахкъурунар',
 'whatlinkshere-hidetrans' => '$1 кутунар',
 'whatlinkshere-hidelinks' => '$1 элячlунар',
-'whatlinkshere-hideimages' => '$1 Ñ\88икилÑ\80из Ñ\8dлÑ\8fÑ\87Ó\80унар',
+'whatlinkshere-hideimages' => '$1 Ñ\84аjлÑ\80ин Ñ\8dлаÑ\87lунар',
 'whatlinkshere-filters' => 'Куьзунагар',
 
 # Block/unblock
@@ -1197,7 +1197,7 @@ $messages = array(
 'file-info-size' => '$1 × $2 пикселар, файлдин кьадар: $3, MIME жуьре: $4',
 'file-nohires' => 'Идалайни хъсан ери авайд туш',
 'svg-long-desc' => 'SVG файл, номилдаказ $1 $2 × пикселяр, файлдин кьадар: $3',
-'show-big-image' => 'Цlарафа хвена тунвай жергедай',
+'show-big-image' => 'ЦӀарафа хвена тунвай жергедай',
 
 # Bad image list
 'bad_image_list' => 'Формат гьихьтинди хьана кlанда:
index 0ecdb96..f050977 100644 (file)
@@ -3647,7 +3647,6 @@ Aafbeildinge waere in häör vollejige resolutie getoeandj. Anger bestandjstypes
 'logentry-newusers-create' => "$1 haet 'ne gebroeker aangemaak",
 'logentry-newusers-create2' => "$1 haet 'ne gebroeker $3 aangemaak",
 'logentry-newusers-autocreate' => 'De gebroeker $1 is autematis aangemaak',
-'newuserlog-byemail' => 'wachwaord is versjik per e-mail',
 'rightsnone' => '(gein)',
 
 # Feedback
index 7bdd6f2..b58684d 100644 (file)
@@ -7,6 +7,7 @@
  * @ingroup Language
  * @file
  *
+ * @author Audriusa
  * @author Auwris
  * @author Break Through Pain
  * @author Dark Eagle
@@ -315,6 +316,7 @@ $messages = array(
 'newwindow' => '(atsidaro naujame lange)',
 'cancel' => 'Atšaukti',
 'moredotdotdot' => 'Daugiau...',
+'morenotlisted' => 'Daugiau nėra',
 'mypage' => 'Naudotojo puslapis',
 'mytalk' => 'Mano aptarimas',
 'anontalk' => 'Šio IP aptarimas',
@@ -338,7 +340,7 @@ $messages = array(
 'vector-action-protect' => 'Užrakinti',
 'vector-action-undelete' => 'Atkurti',
 'vector-action-unprotect' => 'Keisti apsaugą',
-'vector-simplesearch-preference' => 'Įjungti išplėstinius paieškos pasiūlymus (tik „Vector“ išvaizda)',
+'vector-simplesearch-preference' => 'Supaprastinta paieška (tik „Vector“ išvaizda)',
 'vector-view-create' => 'Kurti',
 'vector-view-edit' => 'Redaguoti',
 'vector-view-history' => 'Istorija',
@@ -500,9 +502,9 @@ Egzistuojančių specialiųjų puslapių sąrašą galite rasti [[Special:Specia
 # General errors
 'error' => 'Klaida',
 'databaseerror' => 'Duomenų bazės klaida',
-'dberrortext' => 'Įvyko duomenų bazės užklausos sintaksės klaida.
-Tai gali reikšti klaidą programinėje įrangoje.
-Paskutinė mėginta duomenų bazės užklausa buvo:
+'dberrortext' => 'Neteisinga duomenų bazės užklausos sintaksė.
+Galima klaida programinėje įrangoje.
+Paskutinė mėginta užklausa:
 <blockquote><tt>$1</tt></blockquote>
 iš funkcijos: „<tt>$2</tt>“.
 Duomenų bazė grąžino klaidą „<tt>$3: $4</tt>“.',
@@ -690,6 +692,7 @@ Palaukite prieš bandant vėl.',
 # E-mail sending
 '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ė.',
 
 # Change password dialog
 'resetpass' => 'Keisti slaptažodį',
@@ -933,6 +936,8 @@ Greičiausiai jis yra ištrintas.',
 'edit-already-exists' => 'Negalima sukurti naujo puslapio.
 Jis jau egzistuoja.',
 'defaultmessagetext' => 'Numatytasis pranešimo tekstas',
+'invalid-content-data' => 'Neleistinas turinys.',
+'content-not-allowed-here' => 'Turinys "$1" puslapyje [[$2]] nėra leistinas.',
 
 # Content models
 'content-model-wikitext' => 'wikitekstas',
@@ -1089,7 +1094,8 @@ Prašome patikrinti sąrašus.',
 'revdelete-only-restricted' => 'Klaida slepiant $1 $2 elementą: jūs negalite paslėpti elementų nuo administratorių peržiūros nepasirenkant vieno iš kitų matomumo nustatymų.',
 'revdelete-reason-dropdown' => '*Dažnos trynimo priežastys
 ** Autorinių teisių pažeidimas
-** Netinkama asmeninė informacija
+** Netinkamas komentaras ar asmeninė informacija
+** Netinkamas naudotojo vardas
 ** Informacija, kuri gali būti šmeižikiška',
 'revdelete-otherreason' => 'Kita/papildoma priežastis:',
 'revdelete-reasonotherlist' => 'Kita priežastis',
@@ -2086,6 +2092,7 @@ Palaikomi protokolai: <code>$1</code> (nei vieno iš jų nenurodykite paieškoje
 '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-notarget' => 'El. pašto vartotojas',
 'emailpage' => 'Siųsti el. laišką naudotojui',
 'emailpagetext' => 'Jūs gali pasinaudoti šia forma norėdami nusiųsti el. laišką šiam naudotojui.
@@ -2158,6 +2165,16 @@ taip pat bus '''paryškinti''' [[Special:RecentChanges|naujausių keitimų sąra
 'enotif_mailer' => '{{SITENAME}} Pranešimų sistema',
 'enotif_reset' => 'Pažymėti visus puslapius kaip aplankytus',
 'enotif_impersonal_salutation' => '{{SITENAME}} naudotojau',
+'enotif_subject_deleted' => '{{GENDER:$2|Naudotojas}} ištrynė puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_created' => '{{GENDER:$2|Naudotojas}} sukūrė puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_moved' => '{{GENDER:$2|Naudotojas}} pervardino puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_restored' => '{{GENDER:$2|Naudotojas}} atstatė puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_changed' => '{{GENDER:$2|Naudotojas}} redagavo puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_body_intro_deleted' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} ištrynė puslapį $1, priklausantį projektui {{SITENAME}}, žr.                     $3.',
+'enotif_body_intro_created' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} sukūrė puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
+'enotif_body_intro_moved' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} pervardino puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
+'enotif_body_intro_restored' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} atstatė puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
+'enotif_body_intro_changed' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} redagavo puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
 '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',
@@ -2261,6 +2278,8 @@ Dabar veikiančių puslapių apsaugų sąrašą rasite [[Special:ProtectedPages|
 'prot_1movedto2' => '[[$1]] pervadintas į [[$2]]',
 'protect-badnamespace-title' => 'Neapsaugota vardų sritis',
 'protect-badnamespace-text' => 'Puslapiai šioje vardų srityje negali būti apsaugoti.',
+'protect-norestrictiontypes-text' => 'Šis puslapis negali būti apsaugotas nes neturi galimų apribojimų tipų.',
+'protect-norestrictiontypes-title' => 'Neapsaugomas puslapis',
 'protect-legend' => 'Užrakinimo patvirtinimas',
 'protectcomment' => 'Priežastis:',
 'protectexpiry' => 'Baigia galioti:',
@@ -2926,6 +2945,10 @@ Leidžia pridėti atmetimo priežastį komentaruose',
 'pageinfo-contentpage' => 'Priskirtas turinio puslapiams',
 'pageinfo-contentpage-yes' => 'Taip',
 'pageinfo-protect-cascading-yes' => 'Taip',
+'pageinfo-category-info' => 'Informacija apie kategoriją',
+'pageinfo-category-pages' => 'Puslapių skaičius',
+'pageinfo-category-subcats' => 'Dukterinių kategorijų skaičius',
+'pageinfo-category-files' => 'Failų skaičius',
 
 # Skin names
 'skinname-standard' => 'Klasikinė',
@@ -2948,6 +2971,8 @@ Leidžia pridėti atmetimo priežastį komentaruose',
 'markedaspatrollederror' => 'Negalima pažymėti, kad patikrinta',
 'markedaspatrollederrortext' => 'Jums reikia nurodyti versiją, kurią pažymėti kaip patikrintą.',
 'markedaspatrollederror-noautopatrol' => 'Jums neleidžiama pažymėti savo paties keitimų kaip patikrintų.',
+'markedaspatrollednotify' => '$1 keitimas pažymėtas patikrintu.',
+'markedaspatrollederrornotify' => 'Nepavyko pažymėti kaip patikrinto.',
 
 # Patrol log
 'patrol-log-page' => 'Patikrinimų sąrašas',
@@ -3622,6 +3647,7 @@ Jūs taip pat galite [[Special:EditWatchlist|naudoti standartinį redaktorių]].
 'version-license' => 'Licencija',
 'version-poweredby-credits' => "Šis projektas naudoja '''[//www.mediawiki.org/ MediaWiki]''', autorystės teisės © 2001-$1 $2.",
 'version-poweredby-others' => 'kiti',
+'version-credits-summary' => 'Už indėlį kuriant [[Special:Version|MediaWiki]] dėkojame',
 'version-license-info' => 'MediaWiki yra nemokama programinė įranga; galite ją platinti ir/arba modifikuoti pagal GNU General Public License, kurią publikuoja Free Software Foundation; taikoma 2-oji licenzijos versija arba (Jūsų pasirinkimu) bet kuri vėlesnė versija. 
 
 MediaWiki yra platinama su viltimi, kad ji bus naudinga, bet BE JOKIOS GARANTIJOS; be jokios numanomos PARDAVIMO arba TINKAMUMO TAM TIKRAM TIKSLUI garantijos. Daugiau informacijos galite sužinoti GNU General Public License. 
@@ -3764,8 +3790,8 @@ Paveikslėliai yra rodomi pilna raiška, kiti failų tipai paleidžiami tiesiogi
 'logentry-newusers-newusers' => '$1 sukūrė naudotojo paskyrą',
 'logentry-newusers-create' => '$1 sukūrė naudotojo paskyrą',
 'logentry-newusers-create2' => '$1 sukūrė naudotojo paskyrą $3',
+'logentry-newusers-byemail' => 'Naudotojas $1 sukūrė paskyrą $3, slaptažodis išsiųstas E-paštu.',
 'logentry-newusers-autocreate' => 'Paskyra $1 buvo sukurta automatiškai',
-'newuserlog-byemail' => 'slaptažodis nusiųstas elektroniniu paštu',
 'logentry-rights-rights' => '$1 pakeista narystė grupėje $3 iš $4 į $5',
 'logentry-rights-rights-legacy' => '$1 pakeista narystė grupėje $3',
 'logentry-rights-autopromote' => '$1 buvo automatiškai pervestas iš $4 į $5',
@@ -3789,6 +3815,7 @@ Kitu atveju, galite naudotis žemiau esančia paprastesne forma. Jūsų komentar
 
 # Search suggestions
 'searchsuggest-search' => 'Ieškoti',
+'searchsuggest-containing' => 'turintys',
 
 # API errors
 'api-error-badaccess-groups' => 'Jums neleidžiama įkelti failus į šią wiki.',
index 57e4127..645a78d 100644 (file)
@@ -1918,7 +1918,6 @@ A bak zawng chu thuhrûk sa vek a ni ang.
 'logentry-newusers-create' => '$1 hian hmangtu siangchan a siam.',
 'logentry-newusers-create2' => '$1 hian hmangtu siangchan $3 a siam.',
 'logentry-newusers-autocreate' => 'Siangchan $1 hi amahin a insiam.',
-'newuserlog-byemail' => 'thurûk e-lehkha hmanga thawn a ni.',
 
 # Feedback
 'feedback-subject' => 'Thupui:',
index 51f38b6..39ab154 100644 (file)
@@ -3113,7 +3113,6 @@ Var arī lietot [[Special:EditWatchlist|standarta izmainīšanas lapu]].',
 'logentry-newusers-create' => 'Lietotāja konts $1 tika izveidots',
 'logentry-newusers-create2' => 'Lietotāja kontu $3 izveidoja $1',
 'logentry-newusers-autocreate' => 'Konts $1 tika izveidots automātiski',
-'newuserlog-byemail' => 'parole nosūtīta pa e-pastu',
 'rightsnone' => '(nav)',
 
 # Feedback
index 407a06e..9f64387 100644 (file)
@@ -2830,7 +2830,6 @@ MediaWiki乃為用之發,無擔之責也;亦無售目之默擔也。參GNU
 # New logging system
 'revdelete-restricted' => '應限至有秩',
 'revdelete-unrestricted' => '除限自有秩',
-'newuserlog-byemail' => '號發自電郵',
 'rightsnone' => '(凡)',
 
 );
index 78181c1..0af7144 100644 (file)
@@ -7,6 +7,7 @@
  * @ingroup Language
  * @file
  *
+ * @author Amire80
  * @author Ashishanchinhar
  * @author Dhirendra.maithili
  * @author Ggajendra
@@ -160,7 +161,7 @@ $messages = array(
 'cancel' => 'समाप्त',
 'moredotdotdot' => 'आर...',
 'mypage' => 'हमर पन्ना',
-'mytalk' => 'हमर à¤µà¤¾à¤°à¥\8dतà¥\8dता',
+'mytalk' => 'वार्त्ता',
 'anontalk' => 'ऐ अनिकेत पता लेल विमर्श',
 'navigation' => 'संचार',
 'and' => '&#32;आर',
@@ -1048,7 +1049,7 @@ $3 द्वारा देल कारण अछि ''$2''",
 
 # Preferences page
 'preferences' => 'विकल्प',
-'mypreferences' => 'हमर à¤\96ासमà¤\96ास',
+'mypreferences' => 'खासमखास',
 'prefs-edits' => 'सम्पादनक संख्या',
 'prefsnologin' => 'सम्प्रवेशित नै',
 'prefsnologintext' => 'अहाँ <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} logged in]</span> प्रयोक्ता विकल्प निर्धारण लेल प्रयोग करू।',
@@ -1924,8 +1925,8 @@ $1',
 'usermessage-template' => 'मीडियाविकी:प्रयोक्ता संदेश',
 
 # Watchlist
-'watchlist' => 'हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dषसà¥\82à¤\9aà¥\80',
-'mywatchlist' => 'हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80',
+'watchlist' => 'साकांक्षसूची',
+'mywatchlist' => 'साकांक्ष-सूची',
 'watchlistfor2' => '$1 $2 लेल',
 'nowatchlist' => 'अहाँक साकांक्ष-सूचीमे कोनो बौस्तु नै अछि।',
 'watchlistanontext' => 'कृपा कऽ $1 अहाँक साकांक्ष-सूचीकेँ देखबा वा सम्पादित करबा लेल।',
@@ -2182,7 +2183,7 @@ $1',
 # Contributions
 'contributions' => 'प्रयोक्ताक योगदान सभ',
 'contributions-title' => '$1 लेल प्रयोक्ताक अवदान',
-'mycontris' => 'हमर à¤¯à¥\8bà¤\97दान',
+'mycontris' => 'योगदान',
 'contribsub2' => '$1 ($2) लेल',
 'nocontribs' => 'कोनो परिवर्तन ऐ सँ मेल नै खाइए।',
 'uctop' => '(शिखर)',
@@ -2223,7 +2224,7 @@ $1',
 'whatlinkshere-hideredirs' => '$1 घुरबैए',
 'whatlinkshere-hidetrans' => '$1 परागत',
 'whatlinkshere-hidelinks' => '$1 सम्बन्ध सभ',
-'whatlinkshere-hideimages' => '$1 à¤\9aितà¥\8dरà¤\95 लागि सभ',
+'whatlinkshere-hideimages' => '$1 à¤«à¤¾à¤\87ल लागि सभ',
 'whatlinkshere-filters' => 'चलनी सभ',
 
 # Block/unblock
@@ -3527,7 +3528,6 @@ $5
 'logentry-newusers-create' => '$1 {{लिंग:$2|बनाएल}} एकटा प्रयोक्ता खाता',
 'logentry-newusers-create2' => '$1 {{लिंग:$2|बनाएल}} {{लिंग:$4|एकटा प्रयोक्ता खाता}} $3',
 'logentry-newusers-autocreate' => 'खाता $1 छल {{लिंग:$2|बनाएल}} स्वतः',
-'newuserlog-byemail' => 'कूटशब्द ई-पत्र द्वारा पठाएल गेल',
 'rightsnone' => '(कोनो नै)',
 
 # API errors
index bf1105e..008c3b9 100644 (file)
@@ -2887,7 +2887,6 @@ $5
 # New logging system
 'revdelete-restricted' => 'нолдаф тевс кардафксне системонь вятиксненди',
 'revdelete-unrestricted' => 'системонь вятиксненди кардафксне валхтфт',
-'newuserlog-byemail' => 'сувама валце кучф электрононь сёрмаса',
 'rightsnone' => '(аш)',
 
 );
index 7b5450e..fd1d848 100644 (file)
@@ -8,6 +8,7 @@
  * @file
  *
  * @author Alno
+ * @author Hoo
  * @author Jagwar
  * @author The Evil IP address
  * @author Urhixidur
@@ -863,8 +864,8 @@ Raha toa moa ka tsy nieritreritra ny hamorona ity takelaka ity ianao dia miveren
 'anontalkpagetext' => "----<i>Ity pejy ity dia pejin-dresak'olona tsy nanokatra na tsy nampiasa ny kaontiny.
 Noho izany dia ilainay ny mampiasa ny adiresy IP-ny hanondroana azy. Mety zarazarain'olona maro ny adiresy IP iray. Raha mpikambana tsy nisoratra anarana ianao, ka raha mahita resaka ts ho anao, azonao atao ny [[Special:UserLogin/signup|manokatra kaonty]], na [[Special:UserLogin|miditra]] mba tsy ho voafangarao amin'ny mpikambana hafa tsy nisoratra anarana.</i>",
 'noarticletext' => "'''Tsy mbola nisy namorona io lahatsoratra io.
-Azonao atao ny [[Special:Search/{{PAGENAME}}||Tadiavo ny momba ny {{PAGENAME}}]].'''
-* '''[{{SERVER}}{{localurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} Na forony eto ny lahatsoratra momba ny {{PAGENAME}}]'''.",
+Azonao atao ny [[Special:Search/{{PAGENAME}}|Tadiavo ny momba ny {{PAGENAME}}]].'''
+* '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} Na forony eto ny lahatsoratra momba ny {{PAGENAME}}]'''.",
 'noarticletext-nopermission' => "Mbola tsy misy lahatsoratra ao amin'io pejy io.
 
 Azonao atao ny [[Special:Search/{{PAGENAME}}|mikaroka ity lohateny ity]] eny amin'ny pejy hafa na <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mitady ao amin'ny laogy misy fifandraisana]</span>, fa tsy azonao atao ny mamorona ity pejy ity.",
@@ -1318,7 +1319,7 @@ Fenoy araka ny datin'ny solosainan'ny mpitsidika",
 'timezoneregion-europe' => 'Eoropa',
 'timezoneregion-indian' => 'Ranomasimbe Indianina',
 'timezoneregion-pacific' => 'Ranomasimbe Pasifika',
-'allowemail' => "Ekeo ny handraisana imailaka avy amin'ny mpikambana hafa",
+'allowemail' => "Hanaiky ny fandefasana mailaka avy amin'ny mpikambana hafa",
 'prefs-searchoptions' => 'Karoka',
 'prefs-namespaces' => "Toeran'anarana",
 'defaultns' => "Fikarohana tsipalotra anatin'ireo anaran-tsehatra ireo :",
@@ -1988,7 +1989,7 @@ Aza manadino manamarina raha tsy misy rohy makany amin'ny endrika hafa alohan'ny
 'listusers-creationsort' => "Afantina amin'ny daty fanokafana",
 'usereditcount' => 'fanovana $1 {{PLURAL:}}',
 'usercreated' => "Noforonina ny {{GENDER:$3}} $1 tamin'ny $2",
-'newpages' => 'pejy Vaovao',
+'newpages' => 'Pejy vaovao',
 'newpages-username' => 'Solonanarana:',
 'ancientpages' => 'Ireo pejy tranainy indrindra',
 'move' => 'Hamindra azy toerana',
@@ -3306,8 +3307,7 @@ Aseho amin'ny tena habeny ny sary aseho, ny hafa dia alefa miaraka amin'ny rindr
 'logentry-newusers-newusers' => 'Noforonina ny kaontim-pikambana $1',
 'logentry-newusers-create' => 'Noforonina ny kaontim-pikambana $1',
 'logentry-newusers-create2' => "Noforonin'i $1 ny kaomtim-pikambana $3",
-'logentry-newusers-autocreate' => 'Noforonina ho azy ny kaontim-pikambana $&',
-'newuserlog-byemail' => "tenimiafina nalefa tamin'ny imailaka",
+'logentry-newusers-autocreate' => 'Noforonina ho azy ny kaontim-pikambana $1',
 'logentry-rights-rights' => "$1 dia nanova ny sokajim-pikambana isian'i $3 avy amin'ny $4 lasa $5",
 'logentry-rights-rights-legacy' => "$1 nanova ny vonodrom-pikambana isian'i $3",
 'logentry-rights-autopromote' => 'Lasa $5 ho azy i $1 izay $4 taloha',
index 23a0feb..29a9ad8 100644 (file)
 
 $fallback = 'id';
 
+$namespaceNames = array(
+       NS_FILE             => 'Berkas',
+       NS_TEMPLATE         => 'Templat',
+);
+
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Garih bawahi link:',
+'tog-underline' => 'Garih bawahi tautan:',
 'tog-justify' => 'Ratokan paragraf',
 'tog-hideminor' => 'Suruakkan suntingan ketek di parubahan tabaru',
 'tog-hidepatrolled' => 'Suruakkan suntingan nan lah dijago di parubahan tabaru',
-'tog-newpageshidepatrolled' => 'Suruakkan halaman nan lah dijago dari senarai halaman baru',
-'tog-extendwatchlist' => 'Kambangkan senarai pantauan untuak malihek sado parubahan, indak nan baru se',
-'tog-usenewrc' => 'Kalompok parubahan dek laman dalam parubahan tabaru jo daftar pantauan (paralu JavaScript)',
+'tog-newpageshidepatrolled' => 'Suruakkan laman nan lah dijago dari dafta laman baru',
+'tog-extendwatchlist' => 'Kambangkan dafta pantau untuak malihek sado parubahan, indak nan baru se',
+'tog-usenewrc' => 'Gunokan tampilan parubahan tingkek lanjuik (paralu JavaScript)',
 'tog-numberheadings' => 'Agiah nomor judua sacaro otomatis',
 'tog-showtoolbar' => 'Tampilkan bilah suntiang (paralu JavaScript)',
-'tog-editondblclick' => 'Suntiang laman jo klik ganda (JavaScript)',
-'tog-editsection' => 'Fungsikan penyuntingan subbagian malalui [sunting] pranala',
-'tog-editsectiononrightclick' => 'Hiduikan bagian panyuntiangan jo mangklik kanan pado judul bagian (JavaScript)',
-'tog-showtoc' => 'Caliakkan dafta isi (untuak laman nan mampunyoi labiah dari 3 subbagian)',
-'tog-rememberpassword' => 'Kana log masuak denai di peramban ko (salamo $1 {{PLURAL:$1|hari|hari}})',
-'tog-watchcreations' => 'Tambahkan laman nan den buek jo gambar nan den unggah ka daftar pantauan',
-'tog-watchdefault' => 'Tambahkan laman jo gambar nan den suntiang ka daftar pantauan',
-'tog-watchmoves' => 'Tambahkan laman jo gambar nan den pindah ka daftar pantauan',
-'tog-watchdeletion' => 'Tambahkan laman jo gambar nan den hapuih ka daftar pantauan',
+'tog-editondblclick' => 'Suntiang laman jo klik duo kali (paralu JavaScript)',
+'tog-editsection' => 'Fungsikan penyuntiangan subbagian malalui [sunting] tautan',
+'tog-editsectiononrightclick' => 'Hiduikkan bagian panyuntiangan jo mangklik kanan pado judul bagian (paralu JavaScript)',
+'tog-showtoc' => 'Tunjuakkan dafta isi (untuak laman nan labiah dari 3 subbagian)',
+'tog-rememberpassword' => 'Ingek log masuak denai di paramban ko (salamo $1 {{PLURAL:$1|hari}})',
+'tog-watchcreations' => 'Tambahkan laman nan den buek jo gambar nan den unggah ka dafta pantau',
+'tog-watchdefault' => 'Tambahkan laman jo gamba nan den suntiang ka dafta pantau',
+'tog-watchmoves' => 'Tambahkan laman jo gamba nan den pindah ka dafta pantau',
+'tog-watchdeletion' => 'Tambahkan laman jo gamba nan den hapuih ka dafta pantau',
 'tog-minordefault' => 'Tandoi sadoalah suntiangan sabagai suntiangan ketek sacaro baku',
 'tog-previewontop' => 'Tampilkan pratonton sabalun kotak suntiang',
-'tog-previewonfirst' => 'Caliakkan pratayang pado suntiangan patamo',
-'tog-nocache' => 'Matikan panyinggahan laman peramban',
-'tog-enotifwatchlistpages' => 'Kirimkan surel kalau laman atau gambar pado daftar pantauan lah barubah',
-'tog-enotifusertalkpages' => 'E-mail ambo jiko laman barundiang denai lah barubah',
+'tog-previewonfirst' => 'Tunjuakkan pratonton pado suntiangan patamo',
+'tog-nocache' => 'Matikan panyinggahan laman paramban',
+'tog-enotifwatchlistpages' => 'Kirimkan surel, kok laman atau gambar pado dafta pantau Ambo lah barubah',
+'tog-enotifusertalkpages' => 'Kirimkan surel, koq laman diskusi Ambo lah barubah',
 'tog-enotifminoredits' => 'Kirimkan surel juo untuk saketek suntingan pado laman jo gambar',
-'tog-enotifrevealaddr' => 'Cogokan alamaik e-mail den pado e-mail notifikasi',
-'tog-shownumberswatching' => 'Tujuakkan jumlah pamantau',
+'tog-enotifrevealaddr' => 'Tunjuakkan alamaik surel ambo pado pambaritauan surel',
+'tog-shownumberswatching' => 'Tunjuakkan jumlah pamantau',
 'tog-oldsig' => 'Tando tangan kini:',
-'tog-fancysig' => 'Palakuan tando tangan sabagai teks wiki (tanpa suatu tautan otomatis)',
-'tog-externaleditor' => 'Gunokan editor eksternal sacaro bawaan (untuak nan ahli sajo, kabutuahan pangaturan khusus pado komputer Sanak [//www.mediawiki.org/wiki/Manual:External_editors Informasi labiah lanjuik.].)',
+'tog-fancysig' => 'Jadikan tando tangan manjadi teks wiki (indak jo tautan otomatis)',
+'tog-externaleditor' => 'Gunokan editor dari lua sacaro bawaan (untuak nan ahli sajo, butuah pangaturan khusus di komputer Sanak [//www.mediawiki.org/wiki/Manual:External_editors Informasi labiah lanjuik.])',
 'tog-externaldiff' => 'Gunokan diff eksternal sacaro bawaan (untuak nan ahli sajo, kabutuahan pangaturan khusus pado komputer Sanak [//www.mediawiki.org/wiki/Manual:External_editors Informasi labiah lanjuik.].)',
 'tog-showjumplinks' => 'Aktifkan tautan pambantu "langsuang ka"',
 'tog-uselivepreview' => 'Gunokan pratayang langsuang (JavaScript) (eksperimental)',
 'tog-forceeditsummary' => 'Ingekkan awak bilo kotak ringkasan suntiangan masih kosoang',
-'tog-watchlisthideown' => 'Sambunyikan suntiangan awak di dafta pantauan',
-'tog-watchlisthidebots' => 'Sambunyikan suntiangan bot di dafta pantauan',
-'tog-watchlisthideminor' => 'Sambunyikan suntiangan ketek di dafta pantauan',
-'tog-watchlisthideliu' => 'Sambunyikan suntiangan pangguno masuak log di dafta pantauan',
-'tog-watchlisthideanons' => 'Sambunyikan suntiangan pangguno indak di kana di dafta pantauan',
-'tog-watchlisthidepatrolled' => 'Sambunyikan suntiangan tapatroli di dafta pantauan',
-'tog-ccmeonemails' => 'Kiriman awak salinan surel nan awak kiriman ka urang lain',
+'tog-watchlisthideown' => 'Suruakkan suntiangan surang di dafta pantau',
+'tog-watchlisthidebots' => 'Suruakkan suntiangan bot di dafta pantau',
+'tog-watchlisthideminor' => 'Suruakkan suntiangan ketek di dafta pantau',
+'tog-watchlisthideliu' => 'Suruakkan suntiangan pangguno masuak log di dafta pantau',
+'tog-watchlisthideanons' => 'Suruakkan suntiangan pangguno indak di kana di dafta pantau',
+'tog-watchlisthidepatrolled' => 'Suruakkan suntiangan tapatroli di dafta pantau',
+'tog-ccmeonemails' => 'Kiriman Ambo salinan surel nan dikiriman ka urang lain',
 'tog-diffonly' => 'Jan tampilan isi laman di bawah pabedoan suntiangan',
 'tog-showhiddencats' => 'Tampilan kategori tasambunyi',
 'tog-norollbackdiff' => 'Jan tampilan pabedoan sasudah malakukan pangambalian',
@@ -82,7 +87,7 @@ $messages = array(
 'tuesday' => 'Salaso',
 'wednesday' => "Raba'a",
 'thursday' => 'Kamih',
-'friday' => 'Jumek',
+'friday' => 'Jumaik',
 'saturday' => 'Sabtu',
 'sun' => 'Min',
 'mon' => 'Sin',
@@ -101,7 +106,7 @@ $messages = array(
 'august' => 'Agustus',
 'september' => 'September',
 'october' => 'Oktober',
-'november' => 'November',
+'november' => 'Nopember',
 'december' => 'Desember',
 'january-gen' => 'Januari',
 'february-gen' => 'Pebruari',
@@ -113,7 +118,7 @@ $messages = array(
 'august-gen' => 'Agustus',
 'september-gen' => 'September',
 'october-gen' => 'Oktober',
-'november-gen' => 'November',
+'november-gen' => 'Nopember',
 'december-gen' => 'Desember',
 'jan' => 'Jan',
 'feb' => 'Peb',
@@ -122,49 +127,50 @@ $messages = array(
 'may' => 'Mai',
 'jun' => 'Jun',
 'jul' => 'Jul',
-'aug' => 'Agu',
+'aug' => 'Ags',
 'sep' => 'Sep',
 'oct' => 'Okt',
-'nov' => 'Nov',
+'nov' => 'Nop',
 'dec' => 'Des',
 
 # Categories related messages
-'pagecategories' => '{{PLURAL:$1|Kategori|Kategori}}',
-'category_header' => 'Laman dalam kategori "$1"',
+'pagecategories' => '{{PLURAL:$1|Kategori}}',
+'category_header' => 'Laman pado kategori "$1"',
 'subcategories' => 'Subkategori',
 'category-media-header' => 'Laman/Media dalam kategori "$1"',
-'category-empty' => "''Kini ko, indak ado terdapat laman ataupun media dalam kategori iko.''",
-'hidden-categories' => '{{PLURAL:$1|Kategori tapandam|Kategori tapandam}}',
+'category-empty' => "''Kini ko, indak ado laman ataupun media dalam kategori ko.''",
+'hidden-categories' => '{{PLURAL:$1|Kategori tapandam}}',
 'hidden-category-category' => 'Kategori tasambunyi',
-'category-subcat-count' => '{{PLURAL:$2|Kategori ko hanyo punyo subkategori berikut.|Kategori ko punyo {{PLURAL:$1|subkategori|$1 subkategori}}, dari total $2.}}',
-'category-subcat-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|subkategori|$1 subkategori}} barikuik.',
-'category-article-count' => '{{PLURAL:$2|Kategori ko hanyo punyo laman berikut.|Kategori ko punyo  {{PLURAL:$1|laman|$1 laman}} dari total $2.}}',
-'category-article-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|ciek laman|$1 laman}} barikuik.',
-'category-file-count' => '{{PLURAL:$2|Kategori iko hanyo mamiliki ciek laman barikuik.|Kategori iko mamiliki {{PLURAL:$1|laman|$1 laman}} barikuik, dari total $2.}}',
-'category-file-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|laman|$1 laman}} barikuik.',
-'listingcontinuesabbrev' => 'lanjuik',
+'category-subcat-count' => '{{PLURAL:$2|Kategori ko punyo {{PLURAL:$1|$1 subkategori}}, dari total $2.}}',
+'category-subcat-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|$1 subkategori}} barikuik.',
+'category-article-count' => '{{PLURAL:$2|Kategori ko punyo {{PLURAL:$1|$1 laman}}, dari total $2.}}',
+'category-article-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|$1 laman}} barikuik.',
+'category-file-count' => '{{PLURAL:$2|Kategori ko ado {{PLURAL:$1|$1 laman}}, dari $2 laman.}}',
+'category-file-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|$1 laman}} barikuik.',
+'listingcontinuesabbrev' => 'samb.',
 'index-category' => 'Laman nan diindeks',
 'noindex-category' => 'Laman nan indak diindeks',
-'broken-file-category' => 'Laman jo gambar rusak',
+'broken-file-category' => 'Laman jo gamba rusak',
 
-'about' => 'Tentang',
+'about' => 'Perihal',
 'article' => 'Artikel',
-'newwindow' => '(buka di jandela baru)',
+'newwindow' => '(bukak di jandela baru)',
 'cancel' => 'Batalkan',
 'moredotdotdot' => 'Lainnyo...',
+'morenotlisted' => 'Salabiahnyo...',
 'mypage' => 'Laman',
 'mytalk' => 'Maota',
-'anontalk' => 'Ota IP iko',
+'anontalk' => 'Diskusi IP ko',
 'navigation' => 'Pinteh',
 'and' => '&#32;jo',
 
 # Cologne Blue skin
-'qbfind' => 'Pencarian',
-'qbbrowse' => 'Browse',
+'qbfind' => 'Pancarian',
+'qbbrowse' => 'Jalajah',
 'qbedit' => 'Suntiang',
 'qbpageoptions' => 'Laman ko',
 'qbmyoptions' => 'Laman denai',
-'qbspecialpages' => 'Halaman istimewa',
+'qbspecialpages' => 'Laman istimewa',
 'faq' => 'FAQ',
 'faqpage' => 'Project:FAQ',
 
@@ -172,21 +178,21 @@ $messages = array(
 'vector-action-addsection' => 'Bagian baru',
 'vector-action-delete' => 'Hapuih',
 'vector-action-move' => 'Pindahkan',
-'vector-action-protect' => 'Lindungi',
+'vector-action-protect' => 'Linduangkan',
 'vector-action-undelete' => 'Pambatalan panghapusan',
 'vector-action-unprotect' => 'Tuka palinduangan',
 'vector-simplesearch-preference' => 'Aktifkan kotak pancarian sadarano (hanyo kulik Vector)',
 'vector-view-create' => 'Buek',
 'vector-view-edit' => 'Suntiang',
-'vector-view-history' => 'Caliak riwayaik nan lalu',
+'vector-view-history' => 'Riwayaik lalu',
 'vector-view-view' => 'Baco',
 'vector-view-viewsource' => 'Caliak sumber',
 'actions' => 'Tindakan',
 'namespaces' => 'Ruang namo:',
-'variants' => 'Variasi:',
+'variants' => 'Varian:',
 
 'navigation-heading' => 'Menu navigasi',
-'errorpagetitle' => 'Kesalahan',
+'errorpagetitle' => 'Kasalahan',
 'returnto' => 'Baliak ka $1',
 'tagline' => 'Dari {{SITENAME}}',
 'help' => 'Bantuan',
@@ -194,11 +200,11 @@ $messages = array(
 'searchbutton' => 'Cari',
 'go' => 'Tuju',
 'searcharticle' => 'Tuju',
-'history' => 'Riwayaik halaman',
+'history' => 'Riwayaik laman',
 'history_short' => 'Riwayaik',
 'updatedmarker' => 'diubah sajak kunjuangan tarakhir ambo',
 'printableversion' => 'Versi cetak',
-'permalink' => 'Pranala parmanen',
+'permalink' => 'Pautan parmanen',
 'print' => 'Cetak',
 'view' => 'Tampilkan',
 'edit' => 'Suntiang',
@@ -209,16 +215,16 @@ $messages = array(
 'deletethispage' => 'Hapuih laman iko',
 'undelete_short' => 'Batal hapuih $1 {{PLURAL:$1|suntiangan|suntiangan}}',
 'viewdeleted_short' => 'Liek {{PLURAL:$1|ciek suntiangan|$1 suntiangan}} nan dihapuih',
-'protect' => 'Lindungi',
+'protect' => 'Linduangkan',
 'protect_change' => 'ubah',
 'protectthispage' => 'Lindungi laman iko',
 'unprotect' => 'Tuka palinduangan',
 'unprotectthispage' => 'Tuka palindungan laman ko',
 'newpage' => 'Laman baru',
 'talkpage' => 'Musyawarahkan laman ko',
-'talkpagelinktext' => 'Maota',
+'talkpagelinktext' => 'maota',
 'specialpage' => 'Laman istimewa',
-'personaltools' => 'Pakakeh paribadi',
+'personaltools' => 'Pakakeh pribadi',
 'postcomment' => 'Bagian baru',
 'articlepage' => 'Liek isi laman',
 'talk' => 'Rundiang',
@@ -231,23 +237,23 @@ $messages = array(
 'templatepage' => 'Caliak laman templat',
 'viewhelppage' => 'Caliak laman bantuan',
 'categorypage' => 'Caliak laman kategori',
-'viewtalkpage' => 'Caliak laman ota',
+'viewtalkpage' => 'Caliak laman diskusi',
 'otherlanguages' => 'Dalam bahaso lain',
 'redirectedfrom' => '(Dialiahkan dari $1)',
-'redirectpagesub' => 'Laman pengalihan',
+'redirectpagesub' => 'Laman pangaliahan',
 'lastmodifiedat' => 'Laman ko taakia diubah pado $2, $1.',
-'viewcount' => 'Laman iko alah diakses sabanyak {{PLURAL:$1|ciek kali|$1 kali}}.<br />',
-'protectedpage' => 'Laman nan dilindungi',
+'viewcount' => 'Laman ko lah dicaliak {{PLURAL:$1|$1 kali}}.',
+'protectedpage' => 'Laman nan dilinduangi',
 'jumpto' => 'Lompek ka:',
 'jumptonavigation' => 'pinteh',
 'jumptosearch' => 'cari',
-'view-pool-error' => 'Maaf, server sadang sibuak pado kini ko.
-Talalu banyak pangguno barusaho mancaliak laman iko.
-Tunggu sabanta sabalum Sanak mancubo baliak mangakses laman iko.
+'view-pool-error' => 'Maaf, server sadang kalabiahan baban.
+Banyak bana nan barusaho mancaliak laman ko.
+Tunggu santa koq nio mancubo baliak ka laman ko.
 
 $1',
-'pool-timeout' => 'Lewat waktu manunggu kunci',
-'pool-queuefull' => 'Kumpulan antrean panuah',
+'pool-timeout' => 'Abih wakatu',
+'pool-queuefull' => 'Antrian panuah',
 'pool-errorunknown' => 'Kasalahan nan indak dikatahui',
 
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
@@ -260,51 +266,54 @@ $1',
 'disclaimers' => 'Sanggah',
 'disclaimerpage' => 'Project:Sanggahan umum',
 'edithelp' => 'Bantuan suntiangan',
-'edithelppage' => 'Help:Suntingan',
-'helppage' => 'Help:Takadia',
-'mainpage' => 'Laman Utamo',
-'mainpage-description' => 'Laman utamo',
+'edithelppage' => 'Help:Panyuntiangan',
+'helppage' => 'Help:Isi',
+'mainpage' => 'Palanta',
+'mainpage-description' => 'Palanta',
 'policy-url' => 'Project:Kabijakan',
 'portal' => 'Portal komunitas',
 'portal-url' => 'Project:Portal komunitas',
 'privacy' => 'Kecipehan privasi',
 'privacypage' => 'Project:Kecipehan privasi',
 
-'badaccess' => 'Kesalahan hak akses',
-'badaccess-group0' => 'Sanak indak diizinkan untuak malakukan tindakan nan Sanak minta.',
-'badaccess-groups' => 'Tindakan nan Sanak minta dibatasi untuak pangguno dalam {{PLURAL:$2|kalompok|ciek dari kelompok}}: $1.',
+'badaccess' => 'Kasalahan hak akses',
+'badaccess-group0' => 'Sanak indak diizinkan untuak malakukan tindakan nan Sanak nio.',
+'badaccess-groups' => 'Tindakan nan Sanak nio dibatasi untuak pangguno dalam {{PLURAL:$2|kalompok}}: $1.',
 
 'versionrequired' => 'Dibutuahkan MediaWiki versi $1',
-'versionrequiredtext' => 'MediaWiki versi $1 dibutuahkan untuak manggunokan laman ijo. Caliak [[Special:Version|laman versi]]',
+'versionrequiredtext' => 'MediaWiki versi $1 dibutuahkan untuak manggunokan laman ko. Caliak [[Special:Version|versi laman]]',
 
 'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}} bahaso Minang',
+'pagetitle-view-mainpage' => '{{SITENAME}} bahaso Minang',
+'backlinksubtitle' => '← $1',
 'retrievedfrom' => 'Didapek dari "$1"',
 'youhavenewmessages' => 'Awak punyo $1 ($2).',
 'newmessageslink' => 'pasan baru',
-'newmessagesdifflink' => 'parubahan terakhir',
-'youhavenewmessagesfromusers' => 'Sanak mandapek $1 dari {{PLURAL:$3|another user|$3 users}} ($2)',
+'newmessagesdifflink' => 'parubahan tarakhia',
+'youhavenewmessagesfromusers' => 'Sanak mandapek $1 dari {{PLURAL:$3|$3 pangguno}} ($2)',
 'youhavenewmessagesmanyusers' => 'Sanak mandapek $1 dari banyak pangguno ($2)',
-'newmessageslinkplural' => '{{PLURAL:$1|sabuah pasan baru|pasan baru}}',
+'newmessageslinkplural' => '{{PLURAL:$1|pasan baru}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|parubahan}} taakhia',
-'youhavenewmessagesmulti' => 'Awak ang mandapek pasan baru pado $1',
+'youhavenewmessagesmulti' => 'Sanak mandapek pasan baru pado $1',
 'editsection' => 'suntiang',
 'editold' => 'suntiang',
 'viewsourceold' => 'caliak sumber',
 'editlink' => 'suntiang',
 'viewsourcelink' => 'caliak sumber',
 'editsectionhint' => 'Suntiang bagian: $1',
-'toc' => 'Daftar isi',
+'toc' => 'Dafta isi',
 'showtoc' => 'tampilkan',
 'hidetoc' => 'suruakkan',
 'collapsible-collapse' => 'Ketekan',
 'collapsible-expand' => 'Kambangan',
 'thisisdeleted' => 'Caliak atau kambalian $1?',
 'viewdeleted' => 'Caliak $1?',
-'restorelink' => 'Caliak {{PLURAL:$1|ciek suntiangan|$1 suntiangan}} nan dihapuih',
+'restorelink' => '{{PLURAL:$1|$1 suntiangan}} lah dihapuih',
 'feedlinks' => 'Umpan:',
 'feed-invalid' => 'Tipe pamintaan umpan indak tapek.',
-'feed-unavailable' => 'Umpan sindikasi indak tasadio',
-'site-rss-feed' => '$1 RSS Umpan',
+'feed-unavailable' => 'Sindikasi umpan indak tasadio',
+'site-rss-feed' => '$1 Umpan RSS',
 'site-atom-feed' => 'Umpan Atom $1',
 'page-rss-feed' => 'Umpan RSS "$1"',
 'page-atom-feed' => '"$1" umpan Atom',
@@ -326,7 +335,7 @@ $1',
 
 # Main script and global functions
 'nosuchaction' => 'Indak ado tindakan tasabuik',
-'nosuchactiontext' => 'Tindakan nan diminta oleh URL tasabuik indak valid. Sanak mungkin salah mangetikkan URL, atau mangikuti suatu pranala nan ndak batua. Hal iko juo mungkin mangindikasikan suatu bug pado parangkaik lunak nan digunokan oleh {{SITENAME}}.',
+'nosuchactiontext' => 'Tindakan nan diminta dek URL tasabuik indak valid. Sanak mungkin salah mangetikkan URL, atau mangikuiki suatu pautan nan indak batua. Hal iko mungkin juo manunjuakan adonyo suatu bug pado parangkaik lunak nan dipagunoan dek {{SITENAME}}.',
 'nosuchspecialpage' => 'Indak ado laman istimewa tarsabuik',
 'nospecialpagetext' => '<strong>Sanak maminta laman istimewa nan indak sah.</strong>
 
@@ -350,12 +359,12 @@ Basis data manghasilkan kasalahan "$3: $4".',
 'readonly' => 'Basis data dikunci',
 'enterlockreason' => 'Masuakkan alasan panguncian, tamasuak pakiraan bilo kunci akan dibuka',
 'readonlytext' => 'Basis data sadang dikunci tahadok masuakan baru. Panguruih nan malakukan panguncian mamberikan panjalehan sabagai berikut: <p>$1',
-'missing-article' => 'Basis data indak dapek manamukan teks dari laman nan saharuihnyo ado, yaitu "$1" $2.
+'missing-article' => 'Basisdata indak dapek manamukan teks dari laman nan saharuihnyo ado, yaitu "$1" $2.
 
-Hal ko biasonyo disababkan dek pranala usang ka pabaikkan tadahulu laman nan alah dihapuih.
+Hal ko biasonyo disababkan dek pautan usang ka pabaikkan tadahulu laman nan alah dihapuih.
 
-Jikok bukan iko panyababnyo, Sanak mungkin alah manamukan sabuah bug dalam pakakeh lunak.
-Silakan laporkan hal iko ka [[Special:ListUsers/sysop|Pangurus]], dangan manyabuikkan alamaik URL nan dituju.',
+Jikok bukan ko panyababnyo, Sanak mungkin alah manamukan sabuah bug dalam pakakeh lunak.
+Silakan laporkan hal iko ka [[Special:ListUsers/sysop|pangurus]], sarato manyabuikkan alamaik URL nan dituju.',
 'missingarticle-rev' => '(revisi#: $1)',
 'missingarticle-diff' => '(Bedo: $1, $2)',
 'readonly_lag' => 'Basis data alah dikunci otomatis salagi basis data sakunder malakukan sinkronisasi jo basis data utamo',
@@ -374,11 +383,11 @@ Silakan laporkan hal iko ka [[Special:ListUsers/sysop|Pangurus]], dangan manyabu
 'badarticleerror' => 'Tindakan iko indak dapek dilaksanakan di laman iko.',
 'cannotdelete' => 'Laman atau berkas "$1" indak dapek dihapuih.
 Mungkin alah dihapuih jo urang lain.',
-'cannotdelete-title' => 'Indak bisa mangapuih halaman "$1"',
+'cannotdelete-title' => 'Indak dapek mangapuih laman "$1"',
 'delete-hook-aborted' => 'Pengapusan batal jo hook.
 Indak ado keterangan.',
 'badtitle' => 'Judul indak sah',
-'badtitletext' => 'Permintaan judul laman indak sah, kosong, atau antarbaso atau antarwiki yang salah sambuang. Mungkin juo ado kandungan karakter yang indak buliah digunoan untuak judul.',
+'badtitletext' => 'Pamintaan judul laman indak sah, kosong, atau antarbaso atau antarwiki nan salah sambuang. Mungkin juo ado kandungan karakter nan indak buliah digunoan untuak judul.',
 'perfcached' => 'Data barikuik ko diambiak dari singgahan dan mungkin indak data nan baru. Nan tabanyak dari {{PLURAL:$1|suatu hasil dari|$1 hasilnyo}} ado di singgahan.',
 'perfcachedts' => 'Data barikuik ko singgahan, dan tarakhir diperbarui $1. Nan tabanyak dari {{PLURAL:$1|suatu hasil dari|$1 hasilnyo}} ado di singgahan.',
 'querypage-no-updates' => 'Pamutakhiran dari laman iko sadang dimatian. Data nan ado di siko saat iko indak akan dimuaik ulang.',
@@ -389,7 +398,7 @@ Indak ado keterangan.',
 'actionthrottledtext' => 'Anda dibatasi untuak malakuan tindakan iko talalu banyak dalam waktu singkek. Sila mancubo laik satalah bara menit.',
 'protectedpagetext' => 'Laman ko alah dikunci untuak manghindari panyuntiangan.',
 'viewsourcetext' => 'Sanak dapek malihek atau manyalin sumber laman iko:',
-'viewyourtext' => 'Sanak bisa mancaliak dan mangopi sumber untuak "editan sanak" ka halaman iko',
+'viewyourtext' => 'Sanak dapek mancaliak jo mangkopi sumber untuak "suntiangan sanak" ka laman ko',
 'protectedinterface' => 'Laman iko baisi teks antarmuko untuak digunoan dek parangkaik lunak di wiki iko sajo, dan alah dikunci untuak maindaan kasalahan. 
 Untuak manambah atau maubah tajamahan di sadonyo wiki, harap gunoan [//translatewiki.net/ translatewiki.net], yaitu proyek palokalan MediaWiki.',
 'editinginterface' => "'''Paringatan:''' Sanak manyuntiang laman nan digunoan untuak manyadiokan teks antarmuko untuak parangkaik lunak.
@@ -410,7 +419,7 @@ Pangurus nan manguncinyo manawarkan penjelasan: "$3"',
 'invalidtitle-knownnamespace' => '↓Judul nan indak sah jo ruangnamo "$2" dan teks "$3"',
 'invalidtitle-unknownnamespace' => 'Judul nan tak sah jo nomor ruang namo indak diketahui $1 dan teks "$2"',
 'exception-nologin' => 'Indak log masuak',
-'exception-nologin-text' => 'Halaman ko hanyo bisa disuntiang dek pangguno badaftar.',
+'exception-nologin-text' => 'Laman ko hanyo dapek disuntiang dek pangguno nan mandaftar.',
 
 # Virus scanner
 'virus-badscanner' => "Kasalahan konfigurasi: pamindai virus indak dikenal: ''$1''",
@@ -441,12 +450,12 @@ Parhatian bahawa bara laman mungkin masih taruih manunjukkan bahawa Sanak masih
 'userlogout' => 'Kalua log',
 'notloggedin' => 'Alun masuak log',
 'nologin' => "Alun mampunyoi akun? '''$1'''.",
-'nologinlink' => 'Cipta akun baru',
-'createaccount' => 'Buek akun baharu',
-'gotaccount' => "Alah tadaftar sabagai pangguno? '''$1'''.",
+'nologinlink' => 'Buek akun baru',
+'createaccount' => 'Buek akun',
+'gotaccount' => "Alah tadafta sabagai pangguno? '''$1'''.",
 'gotaccountlink' => 'Masuak log',
-'userlogin-resetlink' => 'Lupo detail info masuak Sanak?',
-'createaccountmail' => 'malalui surel',
+'userlogin-resetlink' => 'Lupo rincian info masuak Sanak?',
+'createaccountmail' => 'Pakai kato sandi sumbarang samantaro, lalu kirim ka alamaik surel nan di bawah ko',
 'createaccountreason' => 'Alasan:',
 'badretype' => 'Kato sandi nan Sanak masuakkan salah.',
 'userexists' => 'Namo pangguno nan dipiliah alah tapakai.
@@ -469,7 +478,7 @@ Pastian Sanak alah mangaktifan kuki, lalu muek ulang laman iko dan cubo baliak.'
 Namo psngguno msmbedokan kapitalisasi.
 Pariso baliak ejaan Sanak, atau [[Special:UserLogin/signup|buek akun baharu]].',
 'nosuchusershort' => 'Indak ado pangguno jo namo "$1".
-Sila pariso baliak ejaan Sanak.',
+Cubo pariso baliak ejaan Sanak.',
 'nouserspecified' => 'Sanak harus mamasuakkan namo pangguno.',
 'login-userblocked' => 'Pangguno iko diblokir. Indak diizinan/dipabuliahan untuak masuak log.',
 'wrongpassword' => 'Kato sandi nan Sanak masuakkan salah. Sila cubo baliak.',
@@ -494,7 +503,7 @@ Untuak manghindari panyalahgunoan, hanyo ciek kato sandi nan akan dikiriman sati
 'mailerror' => 'Kasalahan dalam mangirimkan surel: $1',
 'acct_creation_throttle_hit' => 'Pangunjung wiki iko jo alamaik IP nan samo jo Sanak alah mambuek {{PLURAL:$1|1 akun|$1 akun}} dalam sahari tarakhir, hinggo jumlah maksimum nan diizinan.
 Karanonyo, pangunjuang jo alamaik IP iko indak dapek baliak mambuek akun lain untuak samantaro.',
-'emailauthenticated' => 'Alamaik surel Sanak alah dikonfirmasi pado $3, $2.',
+'emailauthenticated' => 'Alamaik surel Sanak lah dikonfirmasi pado $3, $2.',
 'emailnotauthenticated' => 'Alamaik surel Sanak alum dikonfirmasi. Sabalun dikonfirmasi Sanak ndak bisa manggunokan fitur surel.',
 'noemailprefs' => 'Sanak harus mamasukan alamaik surel di preferensi Sanak untuak dapek manggunokan fitur-fitur iko.',
 'emailconfirmlink' => 'Konfirmasikan alamaik surel Sanak',
@@ -518,6 +527,7 @@ Sila manunggu sabalun mancubo baliak.',
 # E-mail sending
 'php-mail-error-unknown' => 'Kasalahan nan indak dikana dalam fungsi mail() PHP',
 'user-mail-no-addy' => 'Mancubo mangirim e-mail tanpa alamat e-mail nan sah.',
+'user-mail-no-body' => 'Mancubo kirim surel kosong atau pasan talalu pendek',
 
 # Change password dialog
 'resetpass' => 'Tuka kato sandi',
@@ -571,94 +581,94 @@ ingin maubahnyo, Sanak dapek maabaikan pasan iko dan taruih manggunokan sandi la
 'passwordreset-emailelement' => 'Namo pangguno: $1
 Sandi samantaro: $2',
 'passwordreset-emailsent' => 'Surel pangingek alah dikiriman.',
-'passwordreset-emailsent-capture' => 'E-mail paringatan alah dikirim, nan tacaliak di bawah ko.',
+'passwordreset-emailsent-capture' => 'Surel paringatan alah dikirim, nan nampak di bawah ko.',
 'passwordreset-emailerror-capture' => 'Surel pangingek, nan ditampilkan di bawah, alah dibuek, tapi pengirimannyo gagal ka pangguno: $1',
 
 # Special:ChangeEmail
 'changeemail' => 'Tuka alamat e-mail.',
 'changeemail-header' => 'Ganti alamat e-mail.',
-'changeemail-text' => 'Panuahan formulir iko untuak mangganti alamat e-mail. Sanak harus mamasuakkan kato kunci untuak mangonfirmasi.',
-'changeemail-no-info' => 'Sanak harus masuak log untuak mangakses halaman ko.',
-'changeemail-oldemail' => 'Alamat e-mail kini:',
-'changeemail-newemail' => 'Alamat e-mail baharu:',
+'changeemail-text' => 'Isi formulir ko untuak mangganti alamat surel. Sanak harus mamasuakkan kato sandi untuak mayakinkan parubahan.',
+'changeemail-no-info' => 'Sanak harus masuak log untuak mangakses laman ko.',
+'changeemail-oldemail' => 'Alamat surel kini:',
+'changeemail-newemail' => 'Alamat surel baru:',
 'changeemail-none' => '(indak ado)',
 'changeemail-password' => 'Sandi {{SITENAME}} Sanak:',
-'changeemail-submit' => 'Ganti e-mail.',
+'changeemail-submit' => 'Ganti surel.',
 'changeemail-cancel' => 'Batalkan',
 
 # Edit page toolbar
-'bold_sample' => 'Teks dicetak taba',
-'bold_tip' => 'Teks dicetak taba',
-'italic_sample' => 'Teks dicetak miriang',
-'italic_tip' => 'Teks dicetak miriang',
-'link_sample' => 'Judul pranala',
-'link_tip' => 'Pranala dalam',
-'extlink_sample' => 'http://www.example.com judul pranala',
-'extlink_tip' => 'Pranala lua (ingek awalannyo http://)',
-'headline_sample' => 'Teks tajuk',
-'headline_tip' => 'Tingkek 2 tajuk',
-'nowiki_sample' => 'Masuakkan disiko teks yang indak diformat',
-'nowiki_tip' => 'Abaikan pemformatan wiki',
+'bold_sample' => 'Teks taba',
+'bold_tip' => 'Teks taba',
+'italic_sample' => 'Teks miriang',
+'italic_tip' => 'Teks miriang',
+'link_sample' => 'Judua pautan',
+'link_tip' => 'Pautan dalam',
+'extlink_sample' => 'http://www.anyo-contoh.com judua pautan',
+'extlink_tip' => 'Pautan lua (ingek awalannyo http://)',
+'headline_sample' => 'Teks judul',
+'headline_tip' => 'Tingkek 2 judul',
+'nowiki_sample' => 'Masuakkan disiko teks nan indak baformat',
+'nowiki_tip' => 'Abaikan format wiki',
 'image_tip' => 'Cantumkan berkas',
-'media_tip' => 'Pranala berkas',
-'sig_tip' => 'Tandotangan awak jo tando waktu',
-'hr_tip' => 'Garih horizontal',
+'media_tip' => 'Pautan berkas',
+'sig_tip' => 'Tandotangan sanak jo waktu',
+'hr_tip' => 'Garih mandata',
 
 # Edit pages
-'summary' => 'Ringkasan:',
-'subject' => 'Subjek/tajuk:',
-'minoredit' => 'Iko disuntiang saketek',
+'summary' => 'Ikhtisar:',
+'subject' => 'Subjek/judul:',
+'minoredit' => 'Suntiangan ketek',
 'watchthis' => 'Pantau laman ko',
-'savearticle' => 'Simpan halaman',
-'preview' => 'Pratonton',
+'savearticle' => 'Simpan laman',
+'preview' => 'Caliak',
 'showpreview' => 'Caliak pratonton',
 'showlivepreview' => 'Pratayang langsuang',
 'showdiff' => 'Caliak parubahan',
-'anoneditwarning' => "'''Peringatan:''' Awak alun masuak log.
-Alamat IP awak akan tacatat pado riwayat suntingan laman ko.",
+'anoneditwarning' => "'''Ingek:''' Sanak alun masuak log.
+Alamat IP sanak tacatat pado riwayaik suntiangan laman ko.",
 'anonpreviewwarning' => "''Sanak alun masuak log. Manyimpan laman akan manyababkan alamaik IP Sanak tacatat pado riwayat suntiangan laman iko.''",
 'missingsummary' => "'''Paringatan:''' Sanak indak mamasuakan ringkasan panyuntiangan. Jikok Sanak baliak manakan tombol Simpan, suntiangan Sanak akan disimpan tanpa ringkasan panyuntiangan.",
 'missingcommenttext' => 'Sila masuakan komenta di bawah iko.',
 'missingcommentheader' => "'''Paringatan:''' Sanak alun maagihan subjek atau judul untuak komenta Sanak. Jikok Sanak baliak manakan \"{{int:savearticle}}\", suntiangan Sanak akan disimpan tanpa komenta tasabuik.",
-'summary-preview' => 'Pratonton ringkasan:',
-'subject-preview' => 'Pratayang sabyek/tajuak:',
+'summary-preview' => 'Ringkasan pratayang:',
+'subject-preview' => 'Pratayang subyek/judul:',
 'blockedtitle' => 'Pangguno diblokir',
-'blockedtext' => "'''Namo pangguno atau alamaik IP Sanak alah diblokir.'''
+'blockedtext' => "'''Namo pangguno atau alamaik IP Sanak alah kanai sakek.'''
 
-Blokir dilakuan oleh $1.
+Sakek dibuek dek $1.
 Alasan nan diagiahan adolah ''$2''.
 
-* Diblokir sajak: $8
-* Blokir kadaluwarsa pado: $6
-* Sasaran pamblokiran: $7
+* Kanai sakek sajak: $8
+* Maso sakek habih pado: $6
+* Sasaran nan disakek: $7
 
-Sanak dapek mahubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|pangurus lainnyo]] untuak mambicarokan hal iko.
+Sanak dapek manghubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|panguruih lainnyo]] untuak mambicarokan hal iko.
 
-Sanak indak dapek manggunoan fitur 'Kirim surel ka pangguna iko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|preferensi akun]] dan Sanak indak diblokir untuak manggunoannyo.
+Sanak indak dapek manggunoan fitua 'Kirim surel ka pangguna iko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|pangaturan akun]] dan Sanak indak sadang disakek untuak manggunoannyo.
 
-Alamaik IP Sanak adolah $3, dan ID pamblokiran adolah $5.
-Toloang saratokan ciek atau kaduo informasi ini pado satiok patanyaan nan Sanak buek.",
-'autoblockedtext' => 'Alamaik IP Sanak alah tablokir sacaro otomatis karano digunokan oleh pangguno lain, nan diblokir oleh $1. Pamblokiran dilakuan ateh alasan:
+Alamaik IP Sanak adolah $3, dan ID panyakek adolah $5.
+Tolong saratoan informasi di ateh pado satiok patanyaan nan Sanak buek.",
+'autoblockedtext' => "Alamaik IP Sanak alah kanai sakek sacaro otomatis dek digunoan jo pangguno lain, nan sakek dek $1. Panyakek ko dibuek dek alasan:
 
-:\'\'$2\'\'
+:''$2''
 
-* Diblokir sajak: $8
-* Blokir kadaluwarsa pado: $6
-* Sasaran pamblokiran: $7
+* Kanai sakek sajak: $8
+* Maso sakek habih pado: $6
+* Sasaran nan disakek: $7
 
-Sanak dapek mahubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|pengurus lainnya]] untuak mambicarokan hal iko.
+Sanak dapek mahubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|penguruih lainnya]] untuak mambicarokan hal iko.
 
-Sanak indak dapek manggunoan fitur "kirim surel ka pangguno iko" kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|preferensi akun]] Sanak dan Sanak indak diblokir untuak manggunoannyo.
+Sanak indak dapek manggunoan fitua 'Kirim surel ka pangguna iko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|pangaturan akun]] dan Sanak indak sadang disakek untuak manggunoannyo.
 
-Alamat IP Sanak saat ini adolah $3, dan ID pamblokiran adolah #$5.
-Toloang saratokan informasi-informasi iko dalam satiok patanyaan Sanak.',
+Alamaik IP Sanak adolah $3, dan ID panyakek adolah $5.
+Tolong saratoan informasi di ateh pado satiok patanyaan nan Sanak buek.",
 'blockednoreason' => 'indak ado alasan nan diagiah.',
-'whitelistedittext' => 'Sanak harus $1 untuak dapek manyuntiang laman.',
-'confirmedittext' => 'Sanak harus mangkonfirmasian dahulu alamaik surel Sanak sabalun manyuntiang laman.
-Harap masuakan dan validasian alamaik surel Sanak malalui [[Special:Preferences|laman preferensi pangguno]] Sanak.',
+'whitelistedittext' => 'Sanak musti $1 untuak manyuntiang laman.',
+'confirmedittext' => 'Sanak musti mangkonfirmasian alamaik surel sabalun manyuntiang laman.
+Masuakan dan validasian alamaik surel Sanak pado [[Special:Preferences|pangaturan pangguno]] Sanak.',
 'nosuchsectiontitle' => 'Bagian indak ditamuan',
 'nosuchsectiontext' => 'Sanak mancubo manyuntiang suatu subbagian nan indak ado.
-Subbagian iko mungkin dipindahan atau dihapuih katiko Sanak mambukanyo.',
+Subbagian ko mungkin lah dipindahan atau dihapuih sangkek Sanak mambukaknyo.',
 'loginreqtitle' => 'Harus masuak log',
 'loginreqlink' => 'masuak log',
 'loginreqpagetext' => 'Sanak harus $1 untuak dapek maliek laman lainnyo.',
@@ -675,17 +685,16 @@ Jadi, kami tapaso harus mamakai alamat IP nan basangkutan untuak maidentifikasik
 Jikok Sanak adolah saurang pangguno anonim dan marasa mandapekkan komentar-komentar nan indak relevan nan ditujuan langsung kapado Sanak, sila [[Special:UserLogin/signup|mambuek akun]] atau [[Special:UserLogin|masuak log]] untuak mahindari karancuan jo pangguno anonim lainnya di lain wakatu.''",
 'noarticletext' => 'Kini ko indak ada teks di laman iko.
 Sanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancarian untuak judul laman iko]] di laman-laman lain, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancari log takaik], atau [{{fullurl:{{FULLPAGENAME}}|action=edit}} manyuntiang laman iko]</span>.',
-'noarticletext-nopermission' => 'Kini ko indak ado teks dalam laman iko.
-
-Sanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancahari untuak judul laman iko]] di laman lain, atau <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancahari log takaik] </span>, tapi Sanak indak punyo izin untuak mambuek laman iko.',
+'noarticletext-nopermission' => 'Kini ko indak ado teks dalam laman ko.
+Sanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancarian untuak judul laman ko]] di laman lain, atau <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancahari log takaik] </span>, tapi Sanak indak punyo izin untuak mambuek laman ko.',
 'missing-revision' => 'Revisi $1 di laman nan banamo "{{PAGENAME}}" ko indak ado.
 
-Hal iko biasonyo disababkan dek pranala sijarah nan alah kadaluarsa ka laman nan alah dihapuih.
-Rinciannyo dapek dicaliak di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log panghapuihan].',
+Hal iko biasonyo disababkan dek pautan sijarah nan alah kadaluarsa ka laman nan alah diapuih.
+Rinciannyo dapek dicaliak di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log pangapuihan].',
 'userpage-userdoesnotexist' => 'Akun pangguno "<nowiki>$1</nowiki>" indak tadafta.',
 'userpage-userdoesnotexist-view' => 'Pangguno "$1" indak tadafta.',
-'blocked-notice-logextract' => 'Pangguno iko sadang diblokir.
-Entri log pamblokiran tabaharu iko disadioan di bawah iko untuak referensi:',
+'blocked-notice-logextract' => 'Pangguno ko tangah diblokir.
+Entri log pamblokiran tabaru disadioan di bawah ko untuak referensi:',
 'clearyourcache' => "'''Catatan:''' Sasudah menyimpan, Sanak mungkin harus meminteh singgahan paramban Sanak untuak maliek parubahan.
 * '''Firefox / Safari:''' Tahan ''Shift'' sambia mangklik ''Reload'', atau takan ''Ctrl-F5'' atau ''Ctrl-R'' (''⌘-R'' di Mac)
 * '''Google Chrome:''' Takan ''Ctrl-Shift-R'' (''⌘-Shift-R'' di Mac)
@@ -703,7 +712,7 @@ Pratayang iko alun disimpan!'''",
 'userinvalidcssjstitle' => "'''Paringatan:''' Kulik \"\$1\" indak ditamuan. Harap diingek bahawa laman .css dan .js manggunokan huruf kecil, contoh {{ns:user}}:Foo/vector.css dan bukannyo {{ns:user}}:Foo/Vector.css.",
 'updated' => '(Dipabaharui)',
 'note' => "'''Catatan:'''",
-'previewnote' => "'''Ingek bahasonyo iko hanyo pratonton'''
+'previewnote' => "'''Ingek ko hanyo pratonton'''
 Parubahan Sanak alun disimpan!",
 'continue-editing' => 'Pai ka area mangedit.',
 'previewconflict' => 'Pratayang iko mancaminan teks pado bagian ateh kotak suntiangan teks sabagaimano akan taliek bilo Sanak manyimpannyo.',
@@ -744,10 +753,10 @@ Awak musti bajanji juo bahaso iko adolah asia karya awak surang, atau disalin da
 '''Jan dikirim karya bahak cipta nan indak baizin!'''",
 'copyrightwarning2' => "Parhatikan bahawa sadoalah kontribusi terhadap {{SITENAME}} dapek disuntiang, diubah, atau dihapuih oleh panyumbang lainnyo. Jikok Sanak indak ingin tulisan Sanak disuntiang urang lain, jan kiriman ka siko.<br />Sanak jua bajanji bahawa iko adolah hasil karyo Sanak surang, atau disalin dari sumber miliak umum atau sumber bebas nan lain (liek $1 untuak informasi labiah lanjuik). '''JAN KIRIMAN KARYO NAN DILINDUNGI HAK CIPTA TANPA IJIN!'''",
 'longpageerror' => "'''KASALAHAN: Teks nan Sanak kiriman sagadang {{PLURAL:$1|kilobita|$1 kilobita}}, nan barati labiah gadang dari jumlah maksimum {{PLURAL:$2|kilobita|$2 kilobita}}. Teks indak dapek disimpan.'''",
-'readonlywarning' => "'''PARINGATAN: Basis data sadang dikunci karano pamaliharaan, sahinggo saat iko Sanak indak dapek manyimpan hasil suntiangan Sanak.
-Sanak mungkin paralu manyalin teks suntiangan Sanak iko dan manyimpannyo ka sabuah berkas teks dan mamuekannyo baliak sausai pamaliharaan usai.'''
+'readonlywarning' => "'''PARINGATAN: Basis data sadang dikunci untuak pamaliharaan, sahinggo saat iko Sanak indak dapek manyimpan hasil suntiangan.''' 
+Sanak mungkin paralu manyalin teks suntiangan Sanak ko dan simpankan ka sabuah berkas teks guno mamuekannyo baliak kundian.
 
-Pangurus nan mangunci basis data magiahan panjalehan barikuik: $1",
+Panguruih nan mangunci basis data maagiahan panjalehan barikuik: $1",
 'protectedpagewarning' => "'''Paringatan: Laman iko sadang dilinduangi sahinggo hanyo pangguno jo hak akses pangurus nan dapek manyuntiangnyo.'''
 Entri catatan tarakhir disadioan di bawah untuak referensi:",
 'semiprotectedpagewarning' => "'''Paringatan: Laman iko sadang dilinduangi sahinggo hanyo pangguno tadafta nan bisa manyuntiangnyo.'''
@@ -755,12 +764,12 @@ Entri catatan tarakhir disadioan di bawah untuak referensi:",
 'cascadeprotectedwarning' => "'''PARINGATAN:''' Laman iko sadang dilinduangi sahinggo hanyo pangguno jo hak akses pangurus sajo nan dapek manyuntiangnyo karano disaratokan dalam {{PLURAL:$1|laman|laman-laman}} barikuik nan alah dilinduangi jo opsi 'palinduangan runtun':",
 'titleprotectedwarning' => "'''Paringatan: Laman iko alah dilinduangi sahinggo diparaluan [[Special:ListGroupRights|hak khusus]] untuak mambueknyo.'''
 Entri catatan tarakhir disadioan di bawah untuak referensi:",
-'templatesused' => '{{PLURAL:$1|Templat|Templat}} yang digunoan di laman iko:',
+'templatesused' => '{{PLURAL:$1|Templat}} yang digunoan di laman ko:',
 'templatesusedpreview' => '{{PLURAL:$1|Templat|Templat}} yang digunoan dalam pratonton ko:',
 'templatesusedsection' => '{{PLURAL:$1|Templat|Templat}} nan digunoan di bagian iko:',
 'template-protected' => '(dilinduangi)',
 'template-semiprotected' => '(semi-perlindungan)',
-'hiddencategories' => 'Laman ko marupokan kalompok dari {{PLURAL:$1|1 kategori tapandam|$1 kategori tapandam}}:',
+'hiddencategories' => 'Laman ko marupokan kalompok dari {{PLURAL:$1|$1 kategori tapandam}}:',
 'nocreatetext' => '{{SITENAME}} alah mambatasi pambuekan laman-laman baharu.
 Sanak dapek baliak dan manyuntiang laman nan alah ado, atau sila [[Special:UserLogin|masuak log atau mambuek akun]].',
 'nocreate-loggedin' => 'Sanak ndak mampunyoi hak akses untuak mambuek laman baharu.',
@@ -768,23 +777,23 @@ Sanak dapek baliak dan manyuntiang laman nan alah ado, atau sila [[Special:UserL
 'sectioneditnotsupported-text' => 'Panyuntiangan bagian indak didukuang di laman suntiang iko.',
 'permissionserrors' => 'Kasalahan Hak Akses',
 'permissionserrorstext' => 'Sanak ndak mampunyoi hak untuak malakuan hal itu karano {{PLURAL:$1|alasan|alasan-alasan}} barikuik:',
-'permissionserrorstext-withaction' => 'Awak indak punyo hak akses untuak $2, karano {{PLURAL:$1|alasan|alasan}} berikut:',
-'recreate-moveddeleted-warn' => "'''Paringatan: Sanak mambuek ulang suatu laman nan alah parnah dihapuih.'''
+'permissionserrorstext-withaction' => 'Awak indak punyo hak akses untuak $2, karano {{PLURAL:$1|alasan}} barikuik:',
+'recreate-moveddeleted-warn' => "'''Ingek: Sanak mambuek ulang suatu laman nan alah dihapuih.'''
 
-Harap patimbangan apokah layak untuak malanjutan suntiangan Sanak.
-Barikuik adolah log panghapuihan dan pamindahan dari laman iko:",
-'moveddeleted-notice' => 'Laman iko alah dihapuih.
-Sabagai referensi, barikuik adolah log panghapusan dan pamindahan laman iko.',
+Harap ditimbang apo rancak malanjuikan suntiangan Sanak.
+Barikuik ko log panghapuihan jo pamindahan dari laman ko:",
+'moveddeleted-notice' => 'Laman ko alah dihapuih.
+Sabagai referensi, barikuik adolah log panghapuihan dan pamindahannyo.',
 'log-fulllog' => 'Liek saluruah log',
 'edit-hook-aborted' => 'Suntiangan dibatalan samo kait parser
 tanpa ado katarangan.',
-'edit-gone-missing' => 'Indak bisa mamperbarui halaman.
+'edit-gone-missing' => 'Indak dapek mampabarui laman.
 Mungkin alah dihapuih.',
 'edit-conflict' => 'Konflik suntingan.',
 'edit-no-change' => 'Suntiangan sanak ditulak, karano indak ado parubahan nan tajadi ka teks.',
-'edit-already-exists' => 'Indak bisa mambuek halaman baru.
-Alah ado.',
-'defaultmessagetext' => 'Teks pasan default.',
+'edit-already-exists' => 'Indak dapek mambuek aman baru.
+Nyo alah ado.',
+'defaultmessagetext' => 'Teks baku.',
 'content-failed-to-parse' => 'Gagal manjabarkan konten $2 untuak model $1: $3',
 'invalid-content-data' => 'Data kanduangan indak valid.',
 'content-not-allowed-here' => 'Konten "$1" indak diizinan di laman [[$2]]',
@@ -796,16 +805,16 @@ Alah ado.',
 'content-model-css' => 'CSS',
 
 # Parser/template warnings
-'expensive-parserfunction-warning' => "'''Warning:''' Laman ko manganduang talalu banyak panggilan fungsi parser.
+'expensive-parserfunction-warning' => "'''Paringatan:''' Laman ko manganduang talalu banyak panggilan fungsi parser.
 
-Seharusnyo kurang dari $2 {{PLURAL:$2|panggilan|$2 panggilan}}, tapi {{PLURAL:$1|kini ado $1 panggilan|kini ko ado $1 panggilan}}.",
+Seharusnyo kurang dari $2 {{PLURAL:$2|panggilan}}, tapi {{PLURAL:$1|kini ado $1 panggilan}}.",
 'expensive-parserfunction-category' => 'Laman nan talalu banyak panggilan fungsi parser',
 'post-expand-template-inclusion-warning' => "'''Peringatan:''' Ukuran templat talalu gadang.
 Babarapo templat akan diabaikan.",
 'post-expand-template-inclusion-category' => 'Laman nan ukurannyo templatnyo malabiahi bateh',
-'post-expand-template-argument-warning' => 'Peringatan: Laman ko barisi satidaknyo ciek uraian templat na baukuran ekspansi nan talalu gadang. 
+'post-expand-template-argument-warning' => 'Paringatan: Laman ko barisi satidaknyo ciek uraian templat na ukuran ekspansinyo talalu gadang. 
 Uraian-uraian tu alah diabaikan.',
-'post-expand-template-argument-category' => 'Laman nan barisi uraian template nan diabaikan',
+'post-expand-template-argument-category' => 'Laman nan barisi uraian templat nan diabaikan',
 'parser-template-loop-warning' => 'Hubungan barulang templat tadeteksi: [[$1]]',
 'parser-template-recursion-depth-warning' => 'Limit kadalaman hubungan barulang templat lah talampau ($1)',
 'language-converter-depth-warning' => 'Bateh kadalaman pangonversi bahaso lah talampau ($1)',
@@ -813,67 +822,127 @@ Uraian-uraian tu alah diabaikan.',
 'node-count-exceeded-warning' => 'Laman hitungan-node lah talampau',
 'expansion-depth-exceeded-category' => 'Laman dima kadalaman ekspansi lah talampau',
 'expansion-depth-exceeded-warning' => 'Laman kadalaman ekspansi lah talampau',
+'parser-unstrip-loop-warning' => 'Unstrip loop detected',
+'parser-unstrip-recursion-limit' => 'Unstrip recursion limit exceeded ($1)',
 'converter-manual-rule-error' => 'Kasalahan tadeteksi di aturan manual konversi bahaso',
 
 # "Undo" feature
-'undo-success' => 'Suntiangan iko dapek dibatalan. 
-Tolong cek pabandiangan di bawah untuak mayakinkan bahwa bana itu nan Sanak ingin buek, lalu simpan parubahan tasabuik untuak manyalasaikan pambatalan suntiangan.',
+'undo-success' => 'Suntiangan ko dapek dibatalan. 
+Tolong cek pabedoan di bawah untuak mayakinkan bahwa bana nan tu Sanak nio buek, lalu simpan parubahan tasabuik untuak manyalasaikan pambatalan suntiangan.',
 'undo-failure' => 'Suntiangan ko indak dapek dibatalan dek konflik panyuntiangan antaro.',
 'undo-norev' => 'Suntiangan ko indak dapek dibatalan dek laman indak ditamukan atau lah dihapuih.',
-'undo-summary' => 'Mambatalan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])',
+'undo-summary' => 'Mambatalan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|maota]])',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'Indak dapek mambuek akun',
+'cantcreateaccount-text' => "Mambuek akun dari alamat IP ko ('''$1''') alah diblok jo [[User:$3|$3]].
+
+Alasan nan diagiah jo $3 adolah ''$2''",
 
 # History pages
 'viewpagelogs' => 'Caliak log untuak laman ko',
-'currentrev-asof' => 'Revisi terkini pado $1',
+'nohistory' => 'Indak ado sajarah panyuntiangan untuak laman ko',
+'currentrev' => 'Revisi tabaru',
+'currentrev-asof' => 'Revisi tabaru pado $1',
 'revisionasof' => 'Pabaikkan per $1',
 'revision-info' => 'Revisi sajak $1 dek $2',
 'previousrevision' => '← Pabaikkan sabalunnyo',
-'nextrevision' => 'Revisi selanjutnyo →',
-'currentrevisionlink' => 'Revisi terkini',
+'nextrevision' => 'Revisi selanjuiknyo →',
+'currentrevisionlink' => 'Revisi tabaru',
 'cur' => 'kini',
+'next' => 'lanjuik',
 'last' => 'sabalun',
-'histlegend' => "Membandingkan pilihan: Tandoi antaro duo versi nan ingin dibandingan dangan mamilih kotak radionyo, dan takan tombol ''Bandiangan versi tapiliah''.<br />
-Legend: '''({{int:kini}})''' = perbedaan jo versi taakhia, '''({{int:dulu}})''' = pabedoan jo versi sabalunnyo, '''{{int:k}}''' = suntiangan ketek, '''{{int:b}}''' = suntiangan bot.",
+'page_first' => 'awal',
+'page_last' => 'akhir',
+'histlegend' => "Bandiangkan pilihan: Tandoi revisi untuak mambandiangkan dan takan enter atau tombol di bawah.<br />
+Contoh: '''({{int:cur}})''' = bedo jo versi tarakhia, '''({{int:last}})''' = bedo jo versi sabalunnyo, '''{{int:minoreditletter}}''' = suntiangan ketek.",
 'history-fieldset-title' => 'Talusuri riwayaik',
 'history-show-deleted' => 'Hanyo nan dihapuih',
 'histfirst' => 'Nan lamo',
 'histlast' => 'Nan baru',
+'historysize' => '({{PLURAL:$1|$1  bita}})',
+'historyempty' => '(kosong)',
 
 # Revision feed
+'history-feed-title' => 'Riwayat revisi',
+'history-feed-description' => 'Riwayat revisi laman ko di wiki',
 'history-feed-item-nocomment' => '$1 pado $2',
+'history-feed-empty' => 'Laman nan dicari indak ado.
+Mungkin alah dihapuih dari wiki, atau diagiah namo baru.
+Cuba [[Special:Search|cari dulu]] untuak laman lain nan relevan.',
 
 # Revision deletion
+'rev-deleted-comment' => '(ringkasan suntiangan dihapuih)',
+'rev-deleted-user' => '(namo pangguno dihapuih)',
+'rev-deleted-event' => '(isi dihapuih)',
+'rev-deleted-user-contribs' => '[namo pangguno atau alamat IP dihapuih - suntiangan disuruakkan pad dafta kontribusi]',
+'rev-deleted-text-permission' => "Revisi laman ko alah '''dihapuih'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log panghapuihan]",
+'rev-deleted-text-unhide' => "Revisi laman ko alah '''dihapuih'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapuihan].
+Angku masih dapek [$1 maliek revisi ko] ko' amuah.",
+'rev-suppressed-text-unhide' => "Revisi laman ko alah '''tabanam'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} log pambanaman].
+Angku masih dapek [$1 maliek revisi ko] ko' amuah.",
+'rev-deleted-text-view' => "Laman revisi ko alah '''dihapuih'''.
+Angku dapek mancaliaknyo; rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapuihan].",
+'rev-suppressed-text-view' => "Revisi laman ko alah '''tabanam'''.
+Angku dapek malieknyo; rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log pambanaman]",
+'rev-deleted-no-diff' => "Angku indak dapek maliek pabedoan ko dek salah satu dari revisinyo alah '''dihapuih'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapuihan].",
 'rev-delundel' => 'tampilkan/suruakkan',
+'rev-showdeleted' => "tunjua'an",
+'revdelete-show-file-submit' => 'Yo',
+'revdelete-radio-set' => 'Yo',
+'revdelete-radio-unset' => 'Indak',
+'revdelete-log' => 'Alasan:',
 'revdel-restore' => 'ganti tampilan',
 'revdel-restore-deleted' => 'suntiangan nan alah dihapuih',
 'revdel-restore-visible' => 'tampilan revisi',
+'pagehist' => 'Riwayaik laman',
+'revdelete-otherreason' => 'Alasan lain/tambahan:',
+'revdelete-reasonotherlist' => 'Alasan lain',
+'revdelete-edit-reasonlist' => 'Alasan mangapuih laman',
+
+# History merging
+'mergehistory-reason' => 'Alasan:',
 
 # Merge log
-'revertmerge' => 'Bata bagabuang',
+'mergelog' => 'Log panggabuangan',
+'revertmerge' => 'Batal gabuang',
 
 # Diffs
-'history-title' => 'Riwayaik pabaiakkan dari "$1"',
+'history-title' => 'Riwayaik revisi dari "$1"',
+'difference-title' => 'Pabedoan antaro revisi dari "$1"',
+'difference-title-multipage' => 'Pabedoan antaro laman "$1" jo "$2"',
+'difference-multipage' => '(Pabedoan antaro laman)',
 'lineno' => 'Barih $1:',
 'compareselectedversions' => 'Bandiangan versi tapiliah',
-'editundo' => 'batalan',
-'diff-multi' => '({{PLURAL:$1|ciek |$1 revisi antaro}} oleh {{PLURAL:$2|ciek|$2 pangguno}} indak ditampilkan)',
+'showhideselectedversions' => 'Tampilkan/suruakan versi tapiliah',
+'editundo' => 'batal',
+'diff-multi' => '({{PLURAL:$1|$1 revisi antaro}} oleh {{PLURAL:$2|$2 pangguno}} indak ditampilkan)',
 
 # Search results
-'searchresults' => 'Asia pancarian',
+'searchresults' => 'Hasil pancarian',
 'searchresults-title' => 'Hasil pancarian untuak "$1"',
 'searchresulttext' => 'Untuak informasi labiah lanjuik tantang pancarian {{SITENAME}}, caliak [[{{MediaWiki:Helppage}}|{{int:help}}]].',
-'searchsubtitle' => 'Awak mancari \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|sado laman yang dimulai jo "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|sado laman nan tapauik ka "$1"]])',
-'searchsubtitleinvalid' => "Awak mancari '''$1'''",
+'searchsubtitle' => 'Sanak mancari \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|sado laman nan dimulai jo "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|sado laman nan tapauik ka "$1"]])',
+'searchsubtitleinvalid' => "Sanak mancari '''$1'''",
+'titlematches' => 'Judul laman pas',
 'notitlematches' => 'Indak ado judul nan pas',
+'textmatches' => 'Teks laman pas',
 'notextmatches' => 'Indak ado judul nan pas',
 'prevn' => '{{PLURAL:$1|$1}} sabalunnyo',
-'nextn' => '{{PLURAL:$1|$1}} salanjuiknyo',
-'prevn-title' => '$1 {{PLURAL:$1|Hasil|Hasil-hasil}} sabalunnyo',
-'nextn-title' => '$1 {{PLURAL:$1|Hasil|Hasil-hasil}} barikuiknyo',
-'shown-title' => 'Tampilkan $1 {{PLURAL:$1|hasil|hasil-hasil}} per laman',
+'nextn' => '{{PLURAL:$1|$1}} barikuiknyo',
+'prevn-title' => '$1 {{PLURAL:$1|hasil}} sabalunnyo',
+'nextn-title' => '$1 {{PLURAL:$1|hasil}} barikuiknyo',
+'shown-title' => 'Tampilkan $1 {{PLURAL:$1|hasil}} per laman',
 'viewprevnext' => 'Caliakkan ($1 {{int:pipe-separator}} $2) ($3)',
+'searchmenu-legend' => 'Atua pancarian',
 'searchmenu-exists' => "'''Ado laman nan banamo \"[[:\$1]]\" pado wiki ko.'''",
 'searchmenu-new' => "'''Buek laman \"[[:\$1]]\" di wiki ko!'''",
+'searchhelp-url' => 'Help:Isi',
+'searchmenu-prefix' => '[[Special:PrefixIndex/$1|Cari laman jo awalan ko]]',
 'searchprofile-articles' => 'Laman isi',
 'searchprofile-project' => 'Laman Bantuan jo Proyek',
 'searchprofile-images' => 'Multimedia',
@@ -884,19 +953,23 @@ Legend: '''({{int:kini}})''' = perbedaan jo versi taakhia, '''({{int:dulu}})'''
 'searchprofile-images-tooltip' => 'Cari untuak berkas',
 'searchprofile-everything-tooltip' => 'Cari sadoalahnyo (tamasuak laman maota)',
 'searchprofile-advanced-tooltip' => 'Pacarian di ruang namo tatantu',
-'search-result-size' => '$1 ({{PLURAL:$2|1 kato|$2 kato}})',
-'search-result-category-size' => '{{PLURAL:$1|1 anggota|$1 anggota}} ({{PLURAL:$2|1 subkategori|$2 subkategori}}, {{PLURAL:$3|1 berkas|$3 berkas}})',
+'search-result-size' => '$1 ({{PLURAL:$2|$2 kato}})',
+'search-result-category-size' => '{{PLURAL:$1|$1 anggota}} ({{PLURAL:$2|$2 subkategori}}, {{PLURAL:$3|$3 berkas}})',
+'search-result-score' => 'Relevansi: $1%',
 'search-redirect' => '(pangaliahan $1)',
 'search-section' => '(bagian $1)',
-'search-suggest' => 'Mungkin maksud awak: $1',
+'search-suggest' => 'Mungkin makasuiknyo: $1',
 'search-interwiki-caption' => 'Proyek badunsanak',
 'search-interwiki-default' => 'Hasil $1:',
-'search-interwiki-more' => '(selanjutnyo)',
+'search-interwiki-more' => '(salanjuiknyo)',
+'search-relatedarticle' => 'Bakaitan',
+'mwsuggest-disable' => 'Matian saran pancarian',
+'searcheverything-enable' => 'Cari di sagalo ruang namo',
 'searchrelated' => 'bakaitan',
 'searchall' => 'sado',
-'showingresults' => "Di bawah iko dikaluaan inggo {{PLURAL:$1|'''1''' asia|'''$1''' asia}}, dimulai dari #'''$2'''.",
-'showingresultsnum' => "Di bawah iko dikaluaan {{PLURAL:$3|'''1'''|'''$3'''}} asia, dimulai dari #'''$2'''.",
-'showingresultsheader' => "{{PLURAL:$5|Hasil '''$1''' dari '''$3'''|Hasil '''$1 - $2''' dari '''$3'''}} untuak '''$4'''",
+'showingresults' => "Di bawah ko dikaluaan sampai {{PLURAL:$1|'''$1''' hasil}}, dimulai dari #'''$2'''.",
+'showingresultsnum' => "Di bawah ko dikaluaan {{PLURAL:$3|'''$3'''}} hasil mulai dari #'''$2'''.",
+'showingresultsheader' => "{{PLURAL:$5|Hasil '''$1 - $2''' dari '''$3'''}} untuak '''$4'''",
 'nonefound' => "'''Catatan''': hanyo babarapo ruangnamo yang dicari sacaro default.
 Cubo awali permintaan awak tu jo ''all:'' untuak mancari sado kandungan (tamasuak laman ota, templat, dll), atau gunoan ruangnamo yang diinginkan sabagai awalan.",
 'search-nonefound' => 'Indak ado hasil nan cocok sasuai jo parmintaan',
@@ -905,23 +978,156 @@ Cubo awali permintaan awak tu jo ''all:'' untuak mancari sado kandungan (tamasua
 'powersearch-ns' => 'Mancari di ruangnamo:',
 'powersearch-redir' => 'Dafta pangaliahan',
 'powersearch-field' => 'Mancari',
+'powersearch-togglelabel' => 'Piliah:',
+'powersearch-toggleall' => 'Sadonyo',
+'powersearch-togglenone' => 'Dak ado',
 
 # Preferences page
-'preferences' => 'Preferensi',
-'mypreferences' => 'Preferensi',
-'prefs-beta' => 'Corak Beta',
-'prefs-labs' => 'Corak Uji',
-'youremail' => 'Surek Elektronik:',
+'preferences' => 'Pangaturan',
+'mypreferences' => 'Pangaturan',
+'prefs-edits' => 'Jumlah suntiangan:',
+'prefsnologintext' => 'Sanak musti <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} masuak log]</span> untuak mengeset pangaturan.',
+'changepassword' => 'Tuka kato sandi',
+'prefs-skin' => 'Kulik',
+'skin-preview' => 'Caliak',
+'datedefault' => 'Indak usah diatua',
+'prefs-beta' => 'Baru dicubo (Beta)',
+'prefs-datetime' => 'Tangga jo wakatu',
+'prefs-labs' => 'Alaik uji',
+'prefs-user-pages' => 'Laman pangguno',
+'prefs-personal' => 'Profil pangguno',
+'prefs-rc' => 'Parubahan tabaru',
+'prefs-watchlist' => 'Dafta pantau',
+'prefs-watchlist-days' => 'Lamonyo dalam dafta pantau:',
+'prefs-watchlist-days-max' => 'Maksimum $1 {{PLURAL:$1|hari}}',
+'prefs-watchlist-edits' => 'Jumlah suntiangan maksimum nan ditampilkan didafta pantaun nan labiah langkok:',
+'prefs-watchlist-edits-max' => 'Nilai maksimum: 1000',
+'prefs-watchlist-token' => 'Token pantauan:',
+'prefs-misc' => 'Lain-lain',
+'prefs-resetpass' => 'Tuka kato sandi',
+'prefs-changeemail' => 'Tuka alamaik surel',
+'prefs-setemail' => 'Atua alamaik surel',
+'prefs-email' => 'Opsi surel',
+'prefs-rendering' => 'Tampilan',
+'saveprefs' => 'Simpan',
+'resetprefs' => 'Batalan parubahan',
+'restoreprefs' => 'Baliakan ka setelan awal',
+'prefs-editing' => 'Panyuntiangan',
+'prefs-edit-boxsize' => 'Ukuran kotak panyuntiangan.',
+'rows' => 'Barih:',
+'columns' => 'Kolom',
+'searchresultshead' => 'Cari',
+'resultsperpage' => 'Hasil per laman:',
+'stub-threshold' => 'Ambang bateh untuak format <a href="#" class="stub">tautan rintisan</a>:',
+'stub-threshold-disabled' => 'Nonaktifkan',
+'recentchangesdays' => 'Jumlah ari nan ditampilkan di parubahan tabaru:',
+'recentchangesdays-max' => 'Maksimum $1 {{PLURAL:$1|hari}}',
+'recentchangescount' => 'Standar jumlah suntiangan nan ditampilkan:',
+'prefs-help-recentchangescount' => 'Iko untuak parubahan tabaru, riwayaik laman nan lalu, sarato log.',
+'prefs-help-watchlist-token' => 'Mangisi kotak ko jo kunci rasio (PIN) akan manghasilkan sindikasi RSS untuak dafta pantau Sanak. Sia juo nan tau jo kunci ko dapek mambaco dafta pantau Sanak, jadi hati-hatilah mamiliah nilainyo. 
+Barikuik ko nilai acak nan dapek Sanak gunoan: $1',
+'savedprefs' => 'Pangaturan lah tasimpan',
+'timezonelegend' => 'Zona wakatu:',
+'localtime' => 'Wakatu satampaik:',
+'timezoneuseserverdefault' => 'Gunokan nan dari wiki ($1)',
+'timezoneuseoffset' => 'Lainnyo (tantuan pabedoannyo)',
+'timezoneoffset' => 'Pabedoan¹:',
+'servertime' => 'Wakatu server:',
+'guesstimezone' => 'Isikan dari panjalajah web',
+'timezoneregion-africa' => 'Afrika',
+'timezoneregion-america' => 'Amerika',
+'timezoneregion-antarctica' => 'Antarktika',
+'timezoneregion-arctic' => 'Arktik',
+'timezoneregion-asia' => 'Asia',
+'timezoneregion-atlantic' => 'Samudera Atlantik',
+'timezoneregion-australia' => 'Australia',
+'timezoneregion-europe' => 'Eropa',
+'timezoneregion-indian' => 'Samudera Hindia',
+'timezoneregion-pacific' => 'Samudera Pasifik',
+'allowemail' => 'Izinkan pangguno lain mangirim surel',
+'prefs-searchoptions' => 'Cari',
+'prefs-namespaces' => 'Ruang namo',
+'defaultns' => 'Ataupun cari dalam ruang namo lain:',
+'default' => 'baku',
+'prefs-files' => 'Berkas',
+'prefs-custom-css' => 'CSS pribadi',
+'prefs-custom-js' => 'JS pribadi',
+'prefs-common-css-js' => 'CSS/JS untuak kasado kulik:',
+'prefs-reset-intro' => 'Angku dapek manggunokan laman ko untuak mangambalikan pangaturan ka setelan baku situs ko.
+Pangambalian pangaturan indak dapek dibatalan.',
+'prefs-emailconfirm-label' => 'Surel konfirmasi:',
+'prefs-textboxsize' => 'Ukuran kotak suntiang',
+'youremail' => 'Surel:',
+'username' => '{{GENDER:$1|Namo pangguno}}:',
+'uid' => 'ID {{GENDER:$1|pangguno}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Anggota}} {{PLURAL:$1|kalompok}}:',
+'prefs-registration' => 'Wakatu pandaftaran:',
 'yourrealname' => 'Namo sabananyo:',
-'prefs-help-email' => 'Alamaik surek elektronik ko hanyo tambahan se, namun paralu untuak maulang kato kunci, jiko awak ang lupo kato kunci.',
-'prefs-help-email-others' => 'Awak ang juo dapek mamiliah untuak mangizinkan urang lain manghubungi awak ang jo surek elektronik malalui laman pangguno atau laman ota.
-Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan manghubungi awak ang tu.',
+'yourlanguage' => 'Bahaso',
+'yourvariant' => 'Varian bahaso isi:',
+'prefs-help-variant' => 'Varian atau ortografi pilihan Angku untuak manampilkan isi laman wiki ko.',
+'yournick' => 'Tando tangan:',
+'prefs-help-signature' => 'Komen pado laman maota paralu ditandotangani jo "<nowiki>~~~~</nowiki>" nan kan diubah manjadi tando tangan Angku jo wakatu saat kini ko.',
+'badsig' => 'Tando tangan mantah indak sah; pariso tag HTML.',
+'badsiglength' => 'Tando tangan Angku panjang bana.
+Jan labiah dari $1 {{PLURAL:$1|karakter}}.',
+'yourgender' => 'Jenis kelamin:',
+'gender-unknown' => 'Indak ditanyo',
+'gender-male' => 'Laki-laki',
+'gender-female' => 'Padusi',
+'prefs-help-gender' => 'Lainnyo: digunoan untuak manyabuik gender jo parangkaik lunak. Informasi ko akan tabukak untuak umum.',
+'email' => 'Surel',
+'prefs-help-realname' => "Namo asli sifaiknyo opsional.
+Jiko' Angku manambahkannyo, namo asli Angku akan digunoan untuak mengenal hasil karaja Angku.",
+'prefs-help-email' => "Alamaik surel ko hanyolah tambahan, tapi paralu untuak ma-''reset'' kato sandi, bilo Sanak lupo kato sandi.",
+'prefs-help-email-others' => 'Sanak dapek mamiliah untuak mangizinkan urang lain manghubungi jo surel malalui laman pangguno atau laman diskusi.
+Alamaik surel tu indakkan tau dek urang nan manghubungi sanak tu.',
+'prefs-help-email-required' => 'Alamaik surel wajib diisi.',
+'prefs-info' => 'Informasi dasar',
+'prefs-i18n' => 'Internasionalisasi',
+'prefs-signature' => 'Tando tangan',
+'prefs-dateformat' => 'Format tangga',
+'prefs-timeoffset' => 'Format wakatu',
+'prefs-advancedediting' => 'Opsi lanjuik',
+'prefs-advancedrc' => 'Opsi lanjuik',
+'prefs-advancedrendering' => 'Opsi lanjuik',
+'prefs-advancedsearchoptions' => 'Opsi lanjuik',
+'prefs-advancedwatchlist' => 'Opsi lanjuik',
+'prefs-displayrc' => 'Pilihan tampilan',
+'prefs-displaysearchoptions' => 'Pilihan tampilan',
+'prefs-displaywatchlist' => 'Pilihan tampilan',
+'prefs-diffs' => 'Pabedoan',
+
+# User preference: e-mail validation using jQuery
+'email-address-validity-valid' => 'Alamaik surel nampaknyo sah',
+'email-address-validity-invalid' => 'Masuakkan alamaik surel nan sah',
+
+# User rights
+'userrights' => 'Manajemen hak pangguno',
+'userrights-lookup-user' => 'Mangatua kalompok pangguno',
+'userrights-user-editname' => 'Masuakkan namo pangguno:',
+'editusergroup' => 'Suntiang kalompok pangguno',
 
 # Groups
-'group-sysop' => 'Pengurus',
-
+'group' => 'Kalompok:',
+'group-user' => 'Pangguno',
+'group-autoconfirmed' => 'Pangguno takonfirmasi otomatis',
+'group-bot' => 'Bot',
+'group-sysop' => 'Panguruih',
+'group-bureaucrat' => 'Birokrat',
+'group-suppress' => 'Pangawas',
+'group-all' => '(sadonyo)',
+
+'group-user-member' => '{{GENDER:$1|pangguno}}',
+
+'grouppage-user' => '{{ns:project}}:Pangguno',
 'grouppage-sysop' => '{{ns:project}}:Pengurus',
 
+# Rights
+'right-createpage' => 'Mambuek laman baru (nan bukan laman diskusi)',
+'right-createtalk' => 'Mambuek laman diskusi',
+'right-createaccount' => 'Mambuek akun baru',
+
 # Special:Log/newusers
 'newuserlogpage' => 'Log pangguno baru',
 
@@ -929,28 +1135,33 @@ Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan mangh
 'rightslog' => 'Log parubahan hak akses',
 
 # Associated actions - in the sentence "You do not have permission to X"
+'action-read' => 'baco laman ko',
 'action-edit' => 'suntiang laman ko',
+'action-createpage' => 'buek laman',
+'action-createtalk' => 'buek laman diskusi',
+'action-createaccount' => 'buek akun pangguno ko',
+'action-minoredit' => 'tandoi sabagai suntiangan ketek',
 
 # Recent changes
-'nchanges' => '$1 {{PLURAL:$1|parubahan|parubahan}}',
+'nchanges' => '$1 {{PLURAL:$1|parubahan}}',
 'recentchanges' => 'Parubahan baru',
-'recentchanges-legend' => 'Pilihan parubahan baru',
-'recentchanges-summary' => 'Manjajak parubahan terbaru dalam wiki di laman ko.',
+'recentchanges-legend' => 'Piliahan parubahan baru',
+'recentchanges-summary' => 'Caliak parubahan tabaru pado wiki di laman ko.',
 'recentchanges-feed-description' => 'Temukan parubahan baru dalam umpan wiki ko',
-'recentchanges-label-newpage' => 'Suntiang ko mambuek laman baru',
-'recentchanges-label-minor' => 'Iko disuntiang saketek',
+'recentchanges-label-newpage' => 'Suntiangan ko mambuek laman baru',
+'recentchanges-label-minor' => 'Iko suntiangan ketek',
 'recentchanges-label-bot' => 'Suntiang ko dibuek dek bot',
-'recentchanges-label-unpatrolled' => 'Suntiangan ko alun tajago',
-'rcnote' => "Berikut ko {{PLURAL:$1|'''1'''|'''$1'''}} parubahan dalam {{PLURAL:$2|hari|'''$2''' hari}} terakhir, sampai $5, pukul $4.",
-'rcnotefrom' => "Di bawah ko ado parubahan sejak '''$2''' (sampai '''$1''' parubahan).",
-'rclistfrom' => 'Tampilkan parubahan baru sejak $1',
+'recentchanges-label-unpatrolled' => 'Suntiangan ko alun dipatroli',
+'rcnote' => "Berikuik ko {{PLURAL:$1|'''$1'''}} parubahan dalam {{PLURAL:$2|'''$2''' hari}} tarakhia, sampai $4, pukul $5.",
+'rcnotefrom' => "Di bawah ko ado parubahan mulai dari '''$2''' (sampai '''$1''' parubahan).",
+'rclistfrom' => 'Tampilkan parubahan baru mulai dari $1',
 'rcshowhideminor' => '$1 suntingan ketek',
 'rcshowhidebots' => '$1 bot',
 'rcshowhideliu' => '$1 pangguno masuak log',
 'rcshowhideanons' => '$1 pangguno anon',
 'rcshowhidepatr' => '$1 suntiangan nan tajago',
 'rcshowhidemine' => '$1 suntingan denai',
-'rclinks' => 'Tampilkan $1 parubahan baru dalam $2 hari terakhir<br />$3',
+'rclinks' => 'Tunjuakkan $1 parubahan tabaru dalam $2 hari tarakhia<br />$3',
 'diff' => 'bedo',
 'hist' => 'sijarah',
 'hide' => 'Suruakkan',
@@ -958,7 +1169,7 @@ Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan mangh
 'minoreditletter' => 'k',
 'newpageletter' => 'B',
 'boteditletter' => 'b',
-'rc-enhanced-expand' => 'Tampilkan rincian (perlu JavaScript)',
+'rc-enhanced-expand' => 'Tampilkan rincian (paralu JavaScript)',
 'rc-enhanced-hide' => 'Suruakkan rincian',
 
 # Recent changes linked
@@ -966,58 +1177,128 @@ Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan mangh
 'recentchangeslinked-toolbox' => 'Parubahan takaik',
 'recentchangeslinked-title' => 'Parubahan nan takaik jo "$1"',
 'recentchangeslinked-noresult' => 'Indak ado parubahan pado laman nan tapauik salamo periode nan ditantuan',
-'recentchangeslinked-summary' => "Iko adolah daftar parubahan tarakhir pado laman nan tahubuang dari laman tatantu (atau anggota dari suatu kategori tatantu).
-Halaman pada [[Special:Watchlist|your watchlist]] ditondai dangan '''cetak taba''",
+'recentchangeslinked-summary' => "Iko dafta parubahan tarakhir pado laman nan tahubuang dari laman tatantu (atau anggota dari kategori tatantu).
+Laman pado [[Special:Watchlist|dafta pantau Sanak]] ditandoi jo '''cetak taba'''.",
 'recentchangeslinked-page' => 'Namo laman:',
-'recentchangeslinked-to' => 'Tampilkan parubahan dari laman yang takaik jo laman yang disajikan',
+'recentchangeslinked-to' => 'Tampilkan parubahan dari laman nan takaik jo laman nan ko',
 
 # Upload
 'upload' => 'Muek berkas',
 'uploadlogpage' => 'Log unggah',
-'filedesc' => 'Ringkasan',
-'uploadedimage' => 'unggah "[[$1]]"',
+'filename' => 'Namo berkas',
+'filedesc' => 'Ikhtisar',
+'fileuploadsummary' => 'Ikhtisar:',
+'filereuploadsummary' => 'Parubahan berkas:',
+'filestatus' => 'Status hak cipta:',
+'filesource' => 'Sumber:',
+'uploadedfiles' => 'Berkas nan lah dimuek',
+'ignorewarning' => 'Acuahkan pasan dan langsuang simpan berkas.',
+'ignorewarnings' => 'Acuahkan pasan apo pun',
+'minlength1' => 'Namo berkas paliang indak ado satu hurup.',
+'illegalfilename' => 'Namo berkas "$1" ado karakter nan indak dipabuliahkan ado dalam judul. Ubah namo berkas dan cubalah muek baliak.',
+'filename-toolong' => 'Namo berkas indak buliah labiah panjang dari 240 bita.',
+'badfilename' => 'Namo berkas lah diubah manjadi "$1".',
+'filetype-mime-mismatch' => 'Ekstensi berkas ".$1" indak cocok jo MIME nan tadeteksi dari berkas ($2).',
+'filetype-badmime' => 'Berkas batipe MIME "$1" indak buliah dimuek.',
+'filetype-bad-ie-mime' => 'Indak dapek mamuek berkas dek Internet Explorer mandeteksinyo sabagai "$1", nan indak diizinkan dan marupokan tipe berkas bapotensi bahayo.',
+'fileexists-thumbnail-yes' => "Berkas ko nampaknyo marupoan gambar nan ukurannyo dipaketek ''(miniatua)''. [[$1|thumb]]
+Cubo pareso berkas <strong>[[:$1]]</strong> tasabuik.
+Koq berkas tu samemang marupoan gambar dalam ukuran aslinyo, Sanak indak paralu untuak mamuak baliak miniatur lainnyo.",
+'file-thumbnail-no' => "Namo berkas dimulai jo <strong>$1</strong>.
+Nampaknyo berkas ko marupoan gambar jo ukuran dipaketek ''(miniatua)''.
+Koq Sanak ado versi resolusi panuah dari gambar ko, cubolah muekan berkas tasabuik. Koq indak, harap ubah namo berkas ko.",
+'uploadedimage' => 'muek "[[$1]]"',
 
 'license' => 'Lisensi:',
 'license-header' => 'Lisensi',
 
+# Special:ListFiles
+'listfiles_user' => 'Pangguno',
+'listfiles_size' => 'Ukuran',
+'listfiles_description' => 'Katarangan',
+'listfiles_count' => 'Versi',
+
 # File description page
 'file-anchor-link' => 'Berkas',
 'filehist' => 'Riwayaik berkas',
 'filehist-help' => 'Klik pado tanggal/waktu untuak malihek berkas pado maso tu',
-'filehist-revert' => 'kembalikan',
+'filehist-revert' => 'baliakkan',
 'filehist-current' => 'kini ko',
 'filehist-datetime' => 'Tanggal/Waktu',
 'filehist-thumb' => 'Miniatur',
 'filehist-thumbtext' => 'Miniatur untuak versi per $1',
+'filehist-nothumb' => 'Miniatur indak ado',
 'filehist-user' => 'Pangguno',
 'filehist-dimensions' => 'Dimensi',
-'filehist-comment' => 'Ulasan',
+'filehist-filesize' => 'Ukuran berkas',
+'filehist-comment' => 'Komen',
+'filehist-missing' => 'Berkas indak ado',
 'imagelinks' => 'Panggunoan berkas',
-'linkstoimage' => 'Berikut ko ado {{PLURAL:$1|laman nan takaik|$1 laman nan takaik}} jo berkas ko:',
-'nolinkstoimage' => 'Indak ado laman nan ado batauik ka berkas ko.',
+'linkstoimage' => 'Barikuik ko {{PLURAL:$1|$1 laman nan takaik}} jo berkas:',
+'nolinkstoimage' => 'Indak ado laman nan batauik ka berkas ko.',
 'sharedupload' => 'Berkas ko barasal dari $1 dan mungkin digunoan oleh berbagai proyek lain.',
-'sharedupload-desc-here' => 'Berkas ko dari $1 dan mungkin digunoan untuak proyek-proyek lain.
-Deskripsi dari [$2 laman deskripsi berkas] ditampilkan di bawah.',
+'sharedupload-desc-here' => 'Berkas ko dari $1, mungkin juo digunoan untuak proyek-proyek lain.
+Informasi dari [$2 laman katarangannyo] ado di bawah.',
 'uploadnewversion-linktext' => 'Unggah versi baru dari berkas ko',
 
 # Random page
-'randompage' => 'Laman sambarangan',
+'randompage' => 'Laman sumbarang',
 
 # Statistics
 'statistics' => 'Statistik',
-
-'disambiguationspage' => 'Template:disambig',
+'statistics-header-pages' => 'Statistik laman',
+'statistics-header-edits' => 'Statistik suntiangan',
+'statistics-header-views' => 'Statistik tampilan',
+'statistics-header-users' => 'Statistik pangguno',
+'statistics-header-hooks' => 'Statistik lainnyo',
+'statistics-articles' => 'Laman konten',
+'statistics-pages' => 'Jumlah laman',
+'statistics-pages-desc' => 'Sado laman pado wiki, tamasuak laman maota, pangaliahan, dll.',
+'statistics-files' => 'Berkas nan lah dimuek',
+'statistics-edits' => 'Jumlah suntiangan sangkek {{SITENAME}} ko dimulai',
+'statistics-edits-average' => 'Rato-rato suntiangan per-laman',
+'statistics-views-total' => 'Jumlah tampilan laman',
+'statistics-views-total-desc' => 'Tampilan ka laman nan indak ado jo laman khusus nan indak ikuik',
+'statistics-views-peredit' => 'Tampilan per-suntiangan',
+'statistics-users' => 'Jumlah [[Special:ListUsers|pangguno tadafta]]',
+'statistics-users-active' => 'Pangguno aktip',
+'statistics-users-active-desc' => 'Pangguno nan aktip dalam {{PLURAL:$1|$1 ari}} tarakhia.',
+'statistics-mostpopular' => 'Laman nan paliang banyak ditampilkan',
+
+'disambiguations' => 'Laman nan tahubuang ka laman disambiguasi',
+'disambiguationspage' => 'Template:sanamo',
+
+'doubleredirects' => 'Pangaliahan ganda',
 
 # Miscellaneous special pages
-'nbytes' => '$1 {{PLURAL:$1|bait|bait}}',
-'nmembers' => '$1 {{PLURAL:$1|anggota|anggota}}',
-'prefixindex' => 'Semua laman jo awalan',
+'nbytes' => '$1 {{PLURAL:$1|bita}}',
+'ncategories' => '$1 {{PLURAL:$1|kategori}}',
+'ninterwikis' => '$1 {{PLURAL:$1|interwiki}}',
+'nlinks' => '$1 {{PLURAL:$1|pautan}}',
+'nmembers' => '$1 {{PLURAL:$1|anggota}}',
+'nrevisions' => '$1 {{PLURAL:$1|revisi}}',
+'nviews' => 'dilihek $1 {{PLURAL:$1|kali}}',
+'nimagelinks' => 'Digunoan pado $1 {{PLURAL:$1|laman}}',
+'ntransclusions' => 'digunoan pado $1 {{PLURAL:$1|laman}}',
+'lonelypages' => 'Laman yatim',
+'prefixindex' => 'Sado laman jo awalan',
+'prefixindex-namespace' => 'Sado laman jo awalan (ruang namo $1)',
+'shortpages' => 'Laman pendek',
+'longpages' => 'Laman panjang',
+'deadendpages' => 'Laman buntu',
+'deadendpagestext' => 'Laman-laman ko indak ad pautan ka laman lain di {{SITENAME}}.',
+'protectedpages' => 'Laman nan dilinduangi',
+'usereditcount' => '$1 {{PLURAL:$1|suntiangan}}',
 'usercreated' => '{{GENDER:$3|Dibuek}} pado $1 pukua $2',
 'newpages' => 'Laman baru',
-'move' => 'Pindahan',
+'newpages-username' => 'Namo pangguno:',
+'ancientpages' => 'Laman paliang lamo',
+'move' => 'Pindah',
 'movethispage' => 'Pindahan laman ko',
-'pager-newer-n' => '{{PLURAL:$1|labiah baru 1|labiah baru $1}}',
-'pager-older-n' => '{{PLURAL:$1|labiah lamo 1|labiah lamo $1}}',
+'unusedimagestext' => 'Berkas barikuik ado tapi indak takaik jo laman mana pun.
+Harap paratikan bahwa situs web lain mungkin ado tautan ka suatu berkas jo URL langsung, dan  masih tadafta di siko walaupun  indak digunoan aktif.',
+'pager-newer-n' => '{{PLURAL:$1|$1 labiah baru}}',
+'pager-older-n' => '{{PLURAL:$1|$1 labiah lamo}}',
 
 # Book sources
 'booksources' => 'Sumber buku',
@@ -1028,8 +1309,8 @@ Deskripsi dari [$2 laman deskripsi berkas] ditampilkan di bawah.',
 'log' => 'Log',
 
 # Special:AllPages
-'allpages' => 'Semua laman',
-'alphaindexline' => '$1 hinggo $2',
+'allpages' => 'Kasado laman',
+'alphaindexline' => '$1 sampai $2',
 'prevpage' => 'Laman sabalunnyo ($1)',
 'allpagesfrom' => 'Tampilkan laman mulai dari:',
 'allpagesto' => 'Tampilkan laman hinggo:',
@@ -1038,30 +1319,51 @@ Deskripsi dari [$2 laman deskripsi berkas] ditampilkan di bawah.',
 
 # Special:Categories
 'categories' => 'Kategori',
+'categoriespagetext' => '{{PLURAL:$1|Isi kategori}} ko ado laman atau media.
+[[Special:UnusedCategories|Kategori nan indak tapakai]] indak nampak di siko.
+Lihek pulo [[Special:WantedCategories|kategori nan diinginkan]].',
 
 # Special:LinkSearch
-'linksearch' => 'Pranala lua',
+'linksearch' => 'Pancarian pautan lua',
 'linksearch-line' => '$1 tapauik dari $2',
 
 # Special:ListGroupRights
-'listgrouprights-members' => '(senarai anggota)',
+'listgrouprights-members' => '(dafta anggota)',
 
 # E-mail user
-'emailuser' => 'E-mail pangguno',
+'emailuser' => 'Surel pangguno',
+'emailuser-title-target' => 'Kirim surel ka {{GENDER:$1|panggun}} ko',
+'emailuser-title-notarget' => 'Kirim surel',
+'emailpage' => 'Kirim surel ka pangguno ko',
+'emailpagetext' => 'Sanak dapek manggunoan formulir di bawah ko untuak mangirimkan surel ka {{GENDER:$1|pangguna}} ko.
+Alamaik surel nan Sanak masuakkan di [[Special:Preferences|pangaturan akun]] akan kalua sabagai alamaik "Dari" pado surel tasabuik, jadi panarimo dapek langsuang mambalehnyo.',
+'usermaildisabled' => 'Surel pangguno non-aktif',
+'emailtarget' => 'Masuakan namo pangguno nan ka manarimo surel',
+'emailusername' => 'Namo pangguno:',
+'emailusernamesubmit' => 'Kirim',
+'email-legend' => 'Kirim surel ka pangguno {{SITENAME}} lainnyo',
+'emailfrom' => 'Dari:',
+'emailto' => 'Untuak:',
+'emailsubject' => 'Perihal:',
+'emailmessage' => 'Pasan:',
+'emailsend' => 'Kirim',
+'emailccme' => 'Kirimkan denai salinan pasan.',
 
 # Watchlist
-'watchlist' => 'Senarai pantauan denai',
-'mywatchlist' => 'Dafta pantauan denai',
+'watchlist' => 'Dafta pantau',
+'mywatchlist' => 'Dafta pantau',
 'watchlistfor2' => 'Untuak $1 $2',
 'addedwatchtext' => "Laman \"[[:\$1]]\" lah ditambahkan ka [[Special:Watchlist|senarai pantauan awak]].
 Parubahan laman ko tamasuak laman otanyo akan ditampilkan dalam '''cetak taba''' pado [[Special:RecentChanges|senarai parubahan]] agar lebih mudah manjagonyo.",
-'removedwatchtext' => 'Laman "[[:$1]]" lah dihapuih dari [[Special:Watchlist|senarai pantauan awak]].',
+'removewatch' => 'Hapuih dari dafta pantau',
+'removedwatchtext' => 'Laman "[[:$1]]" lah dihapuih dari [[Special:Watchlist|dafta pantau Sanak]].',
 'watch' => 'Pantau',
 'watchthispage' => 'Pantau laman ko',
 'unwatch' => 'Batal pantau',
-'watchlist-details' => '{{PLURAL:$1|$1 laman|$1 laman}} dalam senarai pantauan awak, indak tamasuak laman ota.',
-'wlshowlast' => 'Tampilkan $1 jam $2 hari terakhir $3',
-'watchlist-options' => 'Pilihan senarai pantauan',
+'unwatchthispage' => 'Batal pantau laman ko',
+'watchlist-details' => '{{PLURAL:$1|$1 laman}} dalam dafta pantau awak, indak tamasuak laman rundiangnyo.',
+'wlshowlast' => 'Tampilkan $1 jam $2 hari tarakhia $3',
+'watchlist-options' => 'Piliahan dafta pantau',
 
 # Displayed when you click the "watch" button and it is in the process of watching
 'watching' => 'Mamantau...',
@@ -1069,23 +1371,29 @@ Parubahan laman ko tamasuak laman otanyo akan ditampilkan dalam '''cetak taba'''
 
 # Delete
 'deletepage' => 'Hapuih laman',
+'confirm' => 'Konfirmasi',
 'confirmdeletetext' => 'Awak akan mahapuih laman atau berkas basamo riwayatnyo.
 Pastikan awak mainginkannyo, dan awak lah tahu sagalo akibatnyo dan sasuai jo [[{{MediaWiki:Policy-url}}|kebijakan]] yang balaku.',
-'actioncomplete' => 'Proses selesai',
-'actionfailed' => 'Aksi gagal',
+'actioncomplete' => 'Proses salasai',
+'actionfailed' => 'Proses gagal',
 'deletedtext' => '"$1" lah dihapuih.
 Caliak $2 untuak rakam jajak laman nan lah dihapuih.',
-'dellogpage' => 'Log penghapusan',
+'dellogpage' => 'Log penghapuihan',
 'deletecomment' => 'Alasan:',
 'deleteotherreason' => 'Alasan lain/tambahan:',
 'deletereasonotherlist' => 'Alasan lain',
 
 # Rollback
-'rollbacklink' => 'baliakkan',
+'rollback' => 'Baliakan suntiangan',
+'rollback_short' => 'Baliakan',
+'rollbacklink' => 'baliakan',
+'rollbacklinkcount' => 'baliakan $1 {{PLURAL:$1|suntiangan}}',
+'rollbacklinkcount-morethan' => 'baliakan labiah dari $1 {{PLURAL:$1|suntiangan}}',
+'rollbackfailed' => 'Gagal mambaliakan',
 
 # Protect
-'protectlogpage' => 'Log perlindungan',
-'protectedarticle' => 'melindungi "[[$1]]"',
+'protectlogpage' => 'Log palinduangan',
+'protectedarticle' => 'malinduangkan "[[$1]]"',
 'modifiedarticleprotection' => 'maubah tingkek perlindungan "[[$1]]"',
 'protectcomment' => 'Alasan:',
 'protectexpiry' => 'Kadaluwarsa:',
@@ -1097,18 +1405,31 @@ Berikut ko pengaturan yang balaku untuak laman '''$1''':",
 'protect-cascadeon' => 'Laman ko sedang dilindungi karano tamasuak dalam {{PLURAL:$1|laman|laman}} aktif perlindungan batingkek.
 Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlindungan batingkeknyo.',
 'protect-default' => 'Semua pangguno diizinkan',
-'protect-fallback' => 'Memerlukan hak akses "$1"',
-'protect-level-autoconfirmed' => 'Blokir pangguno baru dan indak terdaftar',
-'protect-level-sysop' => 'Hanya pengurus',
+'protect-fallback' => 'Cumo untuak pangguno jo izin  "$1"',
+'protect-level-autoconfirmed' => 'Cumo untuak pangguno takonfirmasi otomatis',
+'protect-level-sysop' => 'Cumo untuak panguruih',
 'protect-summary-cascade' => 'batingkek',
-'protect-expiring' => 'kadaluwarsa $1 (UTC)',
-'protect-cascade' => 'Lindungi semua laman yang bakaik jo laman ko (perlindungan batingkek)',
-'protect-cantedit' => 'Awak indak dapek maubah tingkek perlindungan laman ko, karano awak indak berhak.',
+'protect-expiring' => 'sampai $1 (UTC)',
+'protect-expiring-local' => 'sampai $1',
+'protect-expiry-indefinite' => 'sataruihnyo',
+'protect-cascade' => 'Linduangi laman nan takaik jo laman ko (palinduangan batingkek)',
+'protect-cantedit' => 'Sanak indak dapek maubah tingkek palinduangan laman ko, karano indak ado izin untuak itu.',
+'protect-othertime' => 'Wakatu lain:',
+'protect-othertime-op' => 'wakatu lain',
+'protect-existing-expiry' => 'Alah sampai: $3, $2',
+'protect-otherreason' => 'Alasan lain/tambahan:',
+'protect-otherreason-op' => 'Alasan lain',
 'restriction-type' => 'Perlindungan:',
 'restriction-level' => 'Tingkek larangan:',
+'minimum-size' => 'Ukuran min',
+'maximum-size' => 'Ukuran max',
+'pagesize' => '(bita)',
 
 # Restrictions (nouns)
-'restriction-move' => 'Pindahan',
+'restriction-edit' => 'Suntiang',
+'restriction-move' => 'Pindah',
+'restriction-create' => 'Buek',
+'restriction-upload' => 'Muek',
 
 # Undelete
 'undeletelink' => 'caliak/cegakkan',
@@ -1116,72 +1437,117 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 
 # Namespace form on various pages
 'namespace' => 'Ruangnamo:',
-'invert' => 'Baliakkan pilihan',
+'invert' => 'Baliakkan piliahan',
+'namespace_association' => 'Ruangnamo takaik',
 'blanknamespace' => '(Utamo)',
 
 # Contributions
-'contributions' => 'Kontribusi {{GENDER:$1|pangguno}}',
+'contributions' => 'Jariah {{GENDER:$1|pangguno}}',
 'contributions-title' => 'Jariah pangguno untuak $1',
-'mycontris' => 'Jariah denai',
+'mycontris' => 'Jariah',
 'contribsub2' => 'Untuak $1 ($2)',
-'uctop' => '(atas)',
-'month' => 'Sajak bulan (dan sabalunnyo):',
-'year' => 'Sajak taun (dan sabalunnyo):',
+'uctop' => '(ateh)',
+'month' => 'Dari bulan (dan sabalunnyo):',
+'year' => 'Dari taun (dan sabalunnyo):',
 
-'sp-contributions-newbies' => 'Tampilkan jariah pangguno baru',
-'sp-contributions-blocklog' => 'log pambalokiran',
+'sp-contributions-newbies' => 'Tampilkan jariah pangguno baru sajo',
+'sp-contributions-blocklog' => 'log pamblokiran',
 'sp-contributions-deleted' => 'kontribusi pangguno nan lah batiadoan',
 'sp-contributions-uploads' => 'muek',
 'sp-contributions-logs' => 'log',
-'sp-contributions-talk' => 'kecek',
+'sp-contributions-talk' => 'maota',
 'sp-contributions-search' => 'Cari jariah',
 'sp-contributions-username' => 'Alamat IP atau namo pangguno:',
-'sp-contributions-toponly' => 'Hanyo manampilan suntiangan nan taakhia',
+'sp-contributions-toponly' => 'Hanyo manampilan suntiangan nan tarakhia',
 'sp-contributions-submit' => 'Cari',
 
 # What links here
-'whatlinkshere' => 'Pranala baliak',
+'whatlinkshere' => 'Pautan baliak',
 'whatlinkshere-title' => 'Laman yang bakaik ka "$1"',
 'whatlinkshere-page' => 'Laman:',
 'linkshere' => "Laman-laman ko bakaik ka '''[[:$1]]''':",
 'nolinkshere' => "Indak ado laman nan punyo tautan ka '''[[:$1]]'''.",
-'isredirect' => 'laman pengalihan',
+'isredirect' => 'laman pengaliahan',
 'istemplate' => 'transklusi',
-'isimage' => 'tautan berkas',
-'whatlinkshere-prev' => '{{PLURAL:$1|sabalunnyo|sabalunnyo $1}}',
-'whatlinkshere-next' => '{{PLURAL:$1|salanjuiknyo|salanjuiknyo $1}}',
-'whatlinkshere-links' => '← pranala',
-'whatlinkshere-hideredirs' => '$1 pengalihan',
+'isimage' => 'pautan berkas',
+'whatlinkshere-prev' => '{{PLURAL:$1|sabalunnyo}}',
+'whatlinkshere-next' => '{{PLURAL:$1|salanjuiknyo}}',
+'whatlinkshere-links' => '← pautan',
+'whatlinkshere-hideredirs' => '$1 pangaliahan',
 'whatlinkshere-hidetrans' => '$1 transklusi',
-'whatlinkshere-hidelinks' => '$1 pranala',
-'whatlinkshere-hideimages' => '$1 pahubuang berkas',
-'whatlinkshere-filters' => 'Penapis',
+'whatlinkshere-hidelinks' => '$1 pautan',
+'whatlinkshere-hideimages' => '$1 pautan berkas',
+'whatlinkshere-filters' => 'Panyariang',
 
 # Block/unblock
-'blockip' => 'Blokir pangguno',
-'ipboptions' => '2 jam:2 hours,1 hari:1 day,3 hari:3 days,1 minggu:1 week,2 minggu:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 tahun:1 year,salamonyo:infinite',
+'autoblockid' => 'Sakek otomatis #$1',
+'block' => 'Sakek pangguno',
+'unblock' => 'Lapeh sakek',
+'blockip' => 'Sakek pangguno',
+'blockip-title' => 'Sakek pangguno',
+'blockip-legend' => 'Sakek pangguno',
+'ipadressorusername' => 'Alamaik IP atau namo pangguno:',
+'ipbexpiry' => 'Sampai:',
+'ipbreason' => 'Alasan:',
+'ipbreasonotherlist' => 'Alasan lain',
+'ipbreason-dropdown' => '*Alasan umum
+** Marusak (vandal)
+** Mangagiah informasi palsu
+** Mangilangkan isi laman
+** Spam pautan ka situs lua
+** Mambuek ota gadang di laman
+** Babuek intimidasi/palecehan
+** Manyalahgunoan babarapo akun
+** Namo pangguno talarang',
+'ipb-hardblock' => 'Halang pangguno tadafta untuak manyuntiang dari alamaik IP ko',
+'ipbcreateaccount' => 'Halang mambuek akun',
+'ipbemailban' => 'Halang pangguno mangirim surel',
+'ipbenableautoblock' => 'Otomatis sakek alamaik IP tarakhia nan digunoan pangguno ko, jo sado alamaik IP takaik nan mancubo manyuntiang.',
+'ipbsubmit' => 'Sakek pangguno ko',
+'ipbother' => 'Salamo:',
+'ipboptions' => '2 jam:2 hours,1 hari:1 day,3 hari:3 days,1 minggu:1 week,2 minggu:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 taun:1 year,salamonyo:infinite',
+'ipbotheroption' => 'lainnyo',
+'ipbotherreason' => 'Alasan lain/tambahan:',
+'ipbhidename' => 'Suruakan namo pangguno dari dafta jo suntiangan',
+'ipbwatchuser' => 'Pantau laman pangguno ko jo laman diskusinyo',
+'ipb-disableusertalk' => 'Halang pangguno ko manyuntiang laman diskusinyo wakatu disakek',
+'ipb-change-block' => 'Sakek baliak pangguno jo setelan ko',
+'ipb-confirm' => 'Konfirmasi sakek',
+'badipaddress' => 'Alamaik IP salah',
+'blockipsuccesssub' => 'Sakek barasil',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] lah disakek.<br />
+Liek [[Special:BlockList|dafta sakek]] buek maninjaunyo.',
+'ipb-blockingself' => 'Angku ka manyakek diri surang! Lai yakin apo nan dikarajoan?',
+'ipb-edit-dropdown' => 'Suntiang alasan manyakek',
+'ipb-unblock-addr' => 'Lapeh sakek $1',
+'blocklist' => 'Pangguno tablokir',
 'ipblocklist' => 'Pangguno tablokir',
-'blocklink' => 'balokir',
-'unblocklink' => 'hilangkan balokir',
-'change-blocklink' => 'ubah balokir',
+'blocklink' => 'sakek',
+'unblocklink' => 'hilangkan sakek',
+'change-blocklink' => 'ubah sakek',
 'contribslink' => 'jariah',
-'blocklogpage' => 'Log pambalokiran',
-'blocklogentry' => 'memblokir [[$1]] dalam maso berlaku $2 $3',
-'unblocklogentry' => 'mahilangkan blokir $1',
-'block-log-flags-nocreate' => 'cipta akun dimatikan',
+'blocklogpage' => 'Log pamblokiran',
+'blocklogentry' => 'Manyakek [[$1]] dalam maso $2 $3',
+'unblocklogentry' => 'mahilangkan sakek $1',
+'block-log-flags-nocreate' => 'mambuek akun dimatikan',
+'blockme' => 'Sakek denai',
 
 # Move page
-'movepagetext' => "Formulir di bawah ko digunoan untuak maubah namo suatu laman dan mamindahkan semua data riwayat ka namo baru. Judul lamo tu akan manjadi laman peralihan manuju judul yang baru. Pranala ka judul lamo indak akan baubah. Pastikan diperiksa laman yang [[Special:DoubleRedirects|peralihan ganda]] atau [[Special:BrokenRedirects|peralihan rusak]]. Awak bertanggungjawab untuak memastikan bahwa pranala tu terus manyambuang ka laman yang seharusnyo.
+'movepagetext' => "Formulir di bawah ko digunoan untuak maubah namo suatu laman dan mamindahan sadonyo data riwayaik ka namo baru. 
+Judua lamo tu ka manjadi laman paraliahan manuju judua nan baru. 
+Awak dapek mampabarui paraliahan-paraliahan nan manuju ka judua lamo sacaro otomatis.
+Kok indak dipabarui sacaro otomatis, pastikan lah dipareso laman ko dari [[Special:DoubleRedirects|paraliahan ganda]] atau [[Special:BrokenRedirects|paralihan rusak]]. Awak batanggung-jawak untuak mamastian bahaso pautan tu taruih manyambuang ka laman nan saaruihnyo.
 
-Perhatikan bahwa laman '''indak''' akan dipindah apobilo lah ado laman yang manggunokan judul yang baru, kecuali bilo laman tu kosong atau marupokan laman peralihan dan indak punyo riwayat suntingan. Maksudnyo awak dapek maubah namo laman seperti samulo apobilo ado kesalahan, dan awak indak dapek manimpo laman yang lah ado.
+Ingeklah bahaso laman ko '''indak''' ka bapindah apobilo lah ado laman nan manggunoan judua nan baru, kacuali bilo laman tu kosong atau marupoan laman paraliahan dan indak punyo riwayaik suntiangan. Aratinyo awak dapek maubah baliak namo laman ka namo samulo apobilo ado kasalahan, dan bahaso awak indak dapek manimpo laman nan lah ado.
 
-'''Peringatan:''' Iko dapek maakibatkan parubahan yang tak diduga pado laman yang populer. Jadi pastikan awak paham akibat tindakan ko sabalun melanjutkannyo.",
-'movepagetalktext' => "Laman ota yang bakaitan akan dipindahkan sacaro otomatis '''kecuali apobilo:'''
+'''Paringatan!''' 
+Iko dapek maakibaikan parubahan nan indak dipakiroan pado laman nan populer; jadi pastikan awak paham akibaik tindakan ko sabalun malanjuikannyo.",
+'movepagetalktext' => "Laman diskusi nan bakaitan akan dipindahkan sacaro otomatis '''kacuali apobilo:'''
 
-*Sebuah laman ota yang indak kosong lah ado pado judul baru, atau
-*Awak indak memberi tando pado kotak di bawahnyo
+*Sabuah laman diskusi nan indak kosong lah ado pado judul baru, atau
+*Angku indak mangagiah tando pado kotak di bawah.
 
-Dalam kasus tu, apobilo diinginkan, awak dapek mamindahkan atau manggabuangkan laman sacaro manual.",
+Dalam kasus tu, kok amuah Angku dapek mamindahkan ataupun manggabuangkan laman sacaro manual.",
 'movearticle' => 'Pindahkan laman',
 'newtitle' => 'Ka judul baru:',
 'move-watch' => 'Pantau laman ko',
@@ -1205,62 +1571,66 @@ Dalam kasus tu, apobilo diinginkan, awak dapek mamindahkan atau manggabuangkan l
 
 # Thumbnails
 'thumbnail-more' => 'Pagadang',
-'thumbnail_error' => 'Gagal mambuek thumbnail : $1',
+'thumbnail_error' => 'Gagal mambuek miniatur: $1',
 
 # Tooltip help for the actions
-'tooltip-pt-userpage' => 'Laman pangguno sanak',
-'tooltip-pt-mytalk' => 'Laman ota sanak',
-'tooltip-pt-preferences' => 'Preferensi denai',
-'tooltip-pt-watchlist' => 'Daftar laman nan denai pantau.',
-'tooltip-pt-mycontris' => 'Daftar jariah Sanak',
-'tooltip-pt-login' => 'Sanak disarankan untuak masuak log; musiki, hal tu indak diwajibkan',
+'tooltip-pt-userpage' => 'Laman pangguno Sanak',
+'tooltip-pt-anonuserpage' => 'Laman pangguno IP Sanak',
+'tooltip-pt-mytalk' => 'Laman rundiang Sanak',
+'tooltip-pt-anontalk' => 'Parundiangan tantang suntiangan dari IP ko',
+'tooltip-pt-preferences' => 'Pangaturan denai',
+'tooltip-pt-watchlist' => 'Dafta laman nan dipantau.',
+'tooltip-pt-mycontris' => 'Dafta jariah Sanak',
+'tooltip-pt-login' => 'Sanak disaranan untuak masuak log; walaupun indak wajib',
 'tooltip-pt-logout' => 'Kalua log',
 'tooltip-ca-talk' => 'Parudiangan tantang isi laman',
-'tooltip-ca-edit' => 'Sanak dapek manyuntiang laman iko. Silakan gunokan tombol pratonton sabalun manyimpan',
+'tooltip-ca-edit' => 'Angku dapek manyuntiang laman ko. Silakan gunoan tombol pratonton sabalun manyimpan',
 'tooltip-ca-addsection' => 'Mulai bagian baru',
 'tooltip-ca-viewsource' => 'Laman ko dilinduangi.
-Sanak hanyo buliah caliak sumbernyo sajo',
-'tooltip-ca-history' => 'Pabaiakkan sabalunnyo dari laman ko',
-'tooltip-ca-protect' => 'Lindungi laman ko',
-'tooltip-ca-delete' => 'Hapuih laman iko',
+Sanak hanyo buliah mancaliak sumbernyo sajo',
+'tooltip-ca-history' => 'Revisi sabalunnyo dari laman ko',
+'tooltip-ca-protect' => 'Linduangi laman ko',
+'tooltip-ca-unprotect' => 'Tuka palinduangan laman ko',
+'tooltip-ca-delete' => 'Hapuih laman ko',
 'tooltip-ca-move' => 'Pindahan laman ko',
-'tooltip-ca-watch' => 'Tambahkan laman ko ka daftar pantauan sanak',
-'tooltip-ca-unwatch' => 'Kaluaan laman ko dari senarai pantauan awak',
+'tooltip-ca-watch' => 'Tambahkan laman ko ka dafta pantau sanak',
+'tooltip-ca-unwatch' => 'Kaluaan laman ko dari dafta pantau',
 'tooltip-search' => 'Cari {{SITENAME}}',
-'tooltip-search-go' => 'Cari suatu laman dengan namo yang samo jiko tasadio',
-'tooltip-search-fulltext' => 'Cari laman untuak teks iko',
-'tooltip-p-logo' => 'Kunjuangi laman utamo',
-'tooltip-n-mainpage' => 'Kunjuangi laman Utamo',
-'tooltip-n-mainpage-description' => 'Kunjuangi laman utamo',
-'tooltip-n-portal' => 'Tantang proyek, apa nan dapek Sanak lakukan, dima untuak manamukan sasuatu',
-'tooltip-n-currentevents' => 'Tamukan informasi manganai latar balakang kajadian kini ko',
-'tooltip-n-recentchanges' => 'Daftar panyuntiangan baru dalam wiki',
-'tooltip-n-randompage' => 'Muek sambarang laman',
+'tooltip-search-go' => 'Cari laman jo namo nan samo jikok ado',
+'tooltip-search-fulltext' => 'Cari laman untuak teks ko',
+'tooltip-p-logo' => 'Kunjuangi palanta',
+'tooltip-n-mainpage' => 'Kunjuangi palanta',
+'tooltip-n-mainpage-description' => 'Kunjuangi palanta',
+'tooltip-n-portal' => 'Tantang proyek, nan dapek Sanak buek, dima ka basobok',
+'tooltip-n-currentevents' => 'Cari informasi manganai latar balakang kajadian ko',
+'tooltip-n-recentchanges' => 'Dafta parubahan baru dalam wiki',
+'tooltip-n-randompage' => 'Muek sumbarang laman',
 'tooltip-n-help' => 'Tampek mancari bantuan',
-'tooltip-t-whatlinkshere' => 'Daftar dari kasado laman wiki nan tahubuang kasiko',
-'tooltip-t-recentchangeslinked' => 'Parubahan baru halaman nan bakaik jo laman ko',
+'tooltip-t-whatlinkshere' => 'Dafta dari sado laman wiki nan tahubuang kasiko',
+'tooltip-t-recentchangeslinked' => 'Parubahan baru laman nan bakaik jo laman ko',
 'tooltip-feed-rss' => 'Umpan RSS untuak laman ko',
 'tooltip-feed-atom' => 'Umpan Atom untuak laman ko',
 'tooltip-t-contributions' => 'Caliak dafta jariah pangguno ko',
-'tooltip-t-emailuser' => 'Kirimkan e-mail ka pangguno ko',
+'tooltip-t-emailuser' => 'Kirimkan surel pado pangguno ko',
 'tooltip-t-upload' => 'Muek berkas',
-'tooltip-t-specialpages' => 'Daftar dari kasado laman istimewa',
+'tooltip-t-specialpages' => 'Dafta dari sado laman istimewa',
 'tooltip-t-print' => 'Versi cetak dari laman ko',
-'tooltip-t-permalink' => 'Pranala parmanen untuak pabaiakkan laman ko',
+'tooltip-t-permalink' => 'Pautan parmanen untuak revisi laman ko',
 'tooltip-ca-nstab-main' => 'Caliak isi laman',
 'tooltip-ca-nstab-user' => 'Caliak laman pangguno',
-'tooltip-ca-nstab-special' => 'Iko adolah laman istimewa, awak indak buliah manyuntiangnyo',
+'tooltip-ca-nstab-media' => 'Caliak laman media',
+'tooltip-ca-nstab-special' => 'Laman istimewa, indak dapek disuntiang',
 'tooltip-ca-nstab-project' => 'Caliak laman proyek',
 'tooltip-ca-nstab-image' => 'Caliak laman berkas',
 'tooltip-ca-nstab-template' => 'Caliak templat',
 'tooltip-ca-nstab-help' => 'Caliak laman bantuan',
 'tooltip-ca-nstab-category' => 'Caliak laman kategori',
-'tooltip-minoredit' => 'Tandoi iko sabagai suntingan ketek',
-'tooltip-save' => 'Simpan yang awak ubah ko',
-'tooltip-preview' => 'Pratonton parubahan, harap gunokan iko sabalun disimpan',
+'tooltip-minoredit' => 'Tandoi iko sabagai suntiangan ketek',
+'tooltip-save' => 'Simpan nan diubah',
+'tooltip-preview' => 'Caliak dulu nan diubah, gunokan ko sabalun manyimpan',
 'tooltip-diff' => 'Caliak parubahan nan alah awak buek tu',
 'tooltip-compareselectedversions' => 'Caliak pabedoan antaro duo revisi pilihan laman ko',
-'tooltip-watch' => 'Tambahkan laman ko ka senarai pantauan awak',
+'tooltip-watch' => 'Tambahkan laman ko ka dafta pantau',
 'tooltip-recreate' => 'Buek baliak laman walaupun sabananyo pernah dihapuih',
 'tooltip-upload' => 'Mulai mamuek',
 'tooltip-rollback' => '"Baliakkan" uruangkan suntiang laman ko pado kontribusi tarakhir dalam sakali klik',
@@ -1268,33 +1638,144 @@ Sanak hanyo buliah caliak sumbernyo sajo',
 'tooltip-preferences-save' => 'Simpan preferensi',
 'tooltip-summary' => 'Masuakan sabuah ringkasan pendek',
 
+# Stylesheets
+'print.css' => '/* CSS placed here will affect the print output */',
+
 # Metadata
 'notacceptable' => 'Layanan wiki indak manyadioan data dalam format yang dapek dibaco dek pelanggan awak.',
 
+# Attribution
+'anonymous' => '{{PLURAL:$1|Pangguno}} anonim {{SITENAME}}',
+'siteuser' => 'pangguno {{SITENAME}} $1',
+'anonuser' => 'pangguno anonim {{SITENAME}} $1',
+'others' => 'lainnyo',
+'siteusers' => '{{PLURAL:$2|pangguno}} {{SITENAME}} $1',
+'anonusers' => '{{PLURAL:$2|pangguno}} anonim {{SITENAME}} $1',
+'creditspage' => 'Panghargaan laman',
+
+# Info page
+'pageinfo-title' => 'Informasi untuak "$1"',
+'pageinfo-header-basic' => 'Informasi dasar',
+'pageinfo-header-edits' => 'Riwayaik suntiangan',
+'pageinfo-header-restrictions' => 'Palinduangan laman',
+'pageinfo-header-properties' => 'Properti laman',
+'pageinfo-display-title' => 'Judua tampilan',
+'pageinfo-length' => 'Panjang laman (dalam bita)',
+'pageinfo-article-id' => 'ID Laman',
+'pageinfo-firstuser' => 'Pambuek laman',
+'pageinfo-toolboxlink' => 'Informasi laman',
+
+# Skin names
+'skinname-standard' => 'Klasik',
+'skinname-nostalgia' => 'Nostalgia',
+'skinname-cologneblue' => 'Biru Köln',
+'skinname-monobook' => 'MonoBook',
+'skinname-myskin' => 'MySkin',
+'skinname-chick' => 'Chick',
+'skinname-simple' => 'Sadarano',
+'skinname-modern' => 'Moderen',
+'skinname-vector' => 'Vektor',
+
+# Patrolling
+'markaspatrolleddiff' => 'Tandoi lah dipatroli',
+'markaspatrolledtext' => 'Tandoi laman ko lah dipatroli',
+'markedaspatrolled' => 'Tandoi lah dipatroli',
+
 # Browsing diffs
 'previousdiff' => '← Revisi sabalunnyo',
 'nextdiff' => 'Revisi salanjuiknyo →',
 
 # Media information
+'imagemaxsize' => "Bateh ukuran gambar:<br />''(untuak laman katarangan berkas)''",
+'thumbsize' => 'Ukuran miniatua:',
+'widthheight' => '$1 × $2',
+'widthheightpage' => '$1 × $2, $3 {{PLURAL:$3|laman}}',
+'file-info' => 'ukuran berkas: $1, tipe MIME: $2',
 'file-info-size' => '$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4',
-'file-nohires' => 'Indak tasadio resolusi yang labiah tinggi.',
-'svg-long-desc' => 'SVG berkas, nominal $1 × $2 piksel, ukuran berkas: $3',
-'show-big-image' => 'Resolusi penuh',
+'file-info-size-pages' => '$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4, $5 {{PLURAL:$5|laman}}',
+'file-nohires' => 'Indak tasadio resolusi nan labiah gadang.',
+'svg-long-desc' => 'Berkas SVG, $1 × $2 piksel, ukuran berkas: $3',
+'svg-long-desc-animated' => 'Berkas anmasi SVG, $1 × $2 piksel, ukuran berkas: $3',
+'svg-long-error' => 'Berkas SVG indak sah: $1',
+'show-big-image' => 'Resolusi panuah',
+'show-big-image-preview' => 'Ukuran pratonton ko: $1',
+'show-big-image-other' => '{{PLURAL:$2|Resolusi}} lainnyo: $1.',
+'show-big-image-size' => '$1 × $2 piksel',
+'file-info-gif-looped' => 'ulang',
+'file-info-gif-frames' => '$1 {{PLURAL:$1|bingkai}}',
+'file-info-png-looped' => 'ulang',
+'file-info-png-repeat' => 'dimainkan $1 {{PLURAL:$1|kali}}',
+'file-info-png-frames' => '$1 {{PLURAL:$1|bingkai}}',
+
+# Special:NewFiles
+'newimages-legend' => 'Panyariang',
+'newimages-label' => 'Namo berkas (atau sabagian darinyo):',
+'showhidebots' => '($1 bot)',
+'noimages' => 'Indak ado nan dicaliak.',
+'ilsubmit' => 'Cari',
+'bydate' => 'jo tanggal',
+'sp-newimages-showfrom' => 'Tampilkan berkas baru mulai dari $2, $1',
+
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'video-dims' => '$1, $2 × $3',
+'seconds-abbrev' => '$1 d',
+'minutes-abbrev' => '$1 min',
+'hours-abbrev' => '$1 j',
+'days-abbrev' => '$1 h',
+'seconds' => '{{PLURAL:$1|$1 detik}}',
+'minutes' => '{{PLURAL:$1|$1 minik}}',
+'hours' => '{{PLURAL:$1|$1 jam}}',
+'days' => '{{PLURAL:$1|$1 hari}}',
+'months' => '{{PLURAL:$1|$1 bulan}}',
+'years' => '{{PLURAL:$1|$1 taun}}',
+'ago' => '$1 nan lalu',
+'just-now' => 'kini ko',
 
 # Bad image list
-'bad_image_list' => 'Ukurannyo adolah sabagai barikuik:
-
-Hanyo daftar butia (barih nan dimulai jo tando *) nan dianggap.
-Pranala patamo pado barih musiti pranala ka berkas buruak.
-Satiok pranala salanjuiknyo pado barih nan samo dianggap pangacualian, yaitu laman dima berkas tasabuik bisa tajadi sajajar.',
+'bad_image_list' => 'Formatnyo adolah sabagai barikuik:
+
+Anyo dafta babutia (barih nan dimulai jo tando *) nan dianggap.
+Pautan patamo pado barih musiti pautan ka berkas buruak.
+Satiok pautan salanjuiknyo pado barih nan samo dianggap pangacualian, yaitu laman-laman dima berkas ko bisa tacaliak.',
+
+/*
+Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language
+*/
+'variantname-zh-hans' => 'hans',
+'variantname-zh-hant' => 'hant',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-mo' => 'mo',
+'variantname-zh-sg' => 'sg',
+'variantname-zh-my' => 'my',
+'variantname-zh' => 'zh',
+
+# Variants for Gan language
+'variantname-gan-hans' => 'hans',
+'variantname-gan-hant' => 'hant',
+'variantname-gan' => 'gan',
+
+# Variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr' => 'sr',
+
+# Variants for Kazakh language
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-cn' => 'kk-cn',
 
 # Metadata
 'metadata' => 'Metadata',
-'metadata-help' => 'Berkas ko mengandung informasi tambahan yang mungkin ditambahkan dek kamera digital atau pemindai yang digunokan untuak mambuek atau mendigitalisasi berkas. Jiko berkas ko lah mangalami modifikasi, rincian yang ado mungkin indak sacaro penuh merefleksikan modifikasi berkas tu.',
+'metadata-help' => 'Berkas ko ado informasi tambahan nan mungkin ditambahkan dek kamera digital atau pemindai yang digunokan untuak mambuek atau mendigitalisasi berkas. Jikok berkas ko lah mangalami modifikasi, rincian nan ado mungkin indak sacaro panuah merefleksi modifikasi dari berkas tu.',
 'metadata-expand' => 'Tampilkan rincian tambahan',
 'metadata-collapse' => 'Suruakkan rincian tambahan',
-'metadata-fields' => 'Tapak metadata gambar nan disenaraikan dalam pasan ko akan di masuakan pado tampilan laman gambar katiko tabel metadata disuruakkan. 
-Nan lainnyo akan tasuruak sacaro default.
+'metadata-fields' => 'Tapak metadata gamba nan didata dalam pasan ko akan di masuakan pado tampilan laman gambar katiko tabel metadata disuruakkan. 
+Nan lainnyo akan tasuruak sacaro baku.
 * make
 * model
 * datetimeoriginal
@@ -1309,28 +1790,85 @@ Nan lainnyo akan tasuruak sacaro default.
 * gpslongitude
 * gpsaltitude',
 
+# EXIF tags
+'exif-imagewidth' => 'Leba',
+'exif-imagelength' => 'Tinggi',
+'exif-bitspersample' => 'Bita per komponen',
+'exif-compression' => 'Skema kompresi',
+'exif-photometricinterpretation' => 'Komposisi piksel',
+'exif-orientation' => 'Orientasi',
+'exif-samplesperpixel' => 'Jumlah komponen',
+'exif-planarconfiguration' => 'Pangaturan data',
+'exif-imagedescription' => 'Judua gamba',
+'exif-make' => 'Produsen kamera',
+'exif-model' => 'Model kamera',
+'exif-software' => 'Parangkaik lunak',
+'exif-artist' => 'Pambuek',
+'exif-copyright' => 'Nan punyo hak cipta',
+'exif-exifversion' => 'Versi Exif',
+'exif-flashpixversion' => 'Dukuangan versi Flashpix',
+'exif-colorspace' => 'Ruang warna',
+'exif-componentsconfiguration' => 'Arti tiok komponen',
+'exif-compressedbitsperpixel' => 'Mode kompresi gamba',
+'exif-pixelydimension' => 'Leba gamba',
+'exif-pixelxdimension' => 'Tinggi gamba',
+'exif-usercomment' => 'Komen pangguno',
+'exif-relatedsoundfile' => 'Berkas audio nan bahubuangan',
+
 # External editor support
 'edit-externally' => 'Suntiang berkas ko dengan aplikasi lua',
 'edit-externally-help' => '(Caliak [//www.mediawiki.org/wiki/Manual:External_editors instruksi pangaturan] untuak informasi lanjuiknyo)',
 
 # 'all' in various places, this might be different for inflected languages
-'watchlistall2' => 'semua',
-'namespacesall' => 'semua',
-'monthsall' => 'sado',
+'watchlistall2' => 'kasadonyo',
+'namespacesall' => 'sadonyo',
+'monthsall' => 'sadonyo',
+'limitall' => 'sadonyo',
 
 # Watchlist editing tools
 'watchlisttools-view' => 'Tampilkan parubahan takaik',
-'watchlisttools-edit' => 'Tampilkan dan suntiang senarai pantauan',
-'watchlisttools-raw' => 'Suntiang senarai pantauan mentah',
+'watchlisttools-edit' => 'Tampilkan sarato suntiang dafta pantau',
+'watchlisttools-raw' => 'Suntiang pantauan mantah',
+
+# Signatures
+'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|maota]])',
 
 # Core parser functions
-'duplicate-defaultsort' => '\'\'\'Peringatan:\'\'\' Kunci panguruitan default "$2" sabalunnyo maabaikan kunci panguruitan default "$1".',
+'duplicate-defaultsort' => '\'\'\'Peringatan:\'\'\' Kunci panguruitan default "$2" sabalunnyo mangabaikan kunci panguruitan default "$1".',
+
+# Special:Version
+'version' => 'Versi',
+'version-extensions' => 'Ekstensi tarinstal',
+'version-specialpages' => 'Laman istimewa',
+'version-parserhooks' => 'Kaik parser',
+'version-variables' => 'Variabel',
+'version-antispam' => 'Pancagahan spam',
+'version-skins' => 'Kulik',
+'version-other' => 'Lain-lain',
+'version-version' => '(Versi $1)',
+'version-license' => 'Lisensi',
+'version-poweredby-credits' => "Wiki ko didukuang jo '''[//www.mediawiki.org/ MediaWiki]''', hak cipta © 2001-$1 $2.",
+'version-poweredby-others' => 'lainnyo',
+'version-software-version' => 'Versi',
+'version-entrypoints-header-url' => 'URL',
+'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath Artikel path]',
+'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath Skrip path]',
+
+# Special:FilePath
+'filepath' => 'Lokasi berkas',
+'filepath-page' => 'Berkas:',
+'filepath-submit' => 'Cari',
 
 # Special:FileDuplicateSearch
-'fileduplicatesearch-result-n' => 'Berkas "$1" punyo {{PLURAL:$2|1 duplikat identik|$2 duplikat identik}}.',
+'fileduplicatesearch-result-n' => 'Berkas "$1" ado {{PLURAL:$2|$2 duplikat nan samo}}.',
+'fileduplicatesearch-noresults' => 'Indak basobok berkas banamo "$1".',
 
 # Special:SpecialPages
 'specialpages' => 'Laman istimewa',
+'specialpages-group-login' => 'Masuak log / mandafta',
+
+# Special:BlankPage
+'blankpage' => 'Laman kosong',
 
 # External image whitelist
 'external_image_whitelist' => '#Bia se barih ko apo adonyo<pre>
@@ -1343,13 +1881,24 @@ Nan lainnyo akan tasuruak sacaro default.
 #Latakan sado fragmen regex di bawah barih ko. Bia se barih apo adonyo</pre>',
 
 # Special:Tags
-'tag-filter' => '[[Special:Tags|Tag]] bateh:',
+'tag-filter' => '[[Special:Tags|Tag]] sariang:',
+'tag-filter-submit' => 'Sariang',
+'tags-title' => 'Tag',
+'tags-tag' => 'Namo tag',
+'tags-edit' => 'suntiang',
+'tags-hitcount' => '$1 {{PLURAL:$1|parubahan}}',
+
+# New logging system
+'logentry-newusers-newusers' => 'Akun pangguno $1 lah dibuek',
+'logentry-newusers-create' => '$1 mambuek akun pangguno',
+'logentry-newusers-create2' => 'Akun pangguno $3 dibuek jo $1',
+'logentry-newusers-autocreate' => 'Akun $1 dibuek sacaro otomatis',
 
 # Search suggestions
 'searchsuggest-search' => 'Cari',
 'searchsuggest-containing' => 'Barisi...',
 
 # Durations
-'duration-millennia' => '$1 {{PLURAL:$1|millennium|millenia}}',
+'duration-millennia' => '$1 {{PLURAL:$1|milenium}}',
 
 );
index d82796b..5ee3452 100644 (file)
@@ -330,7 +330,7 @@ $magicWords = array(
        'numberingroup'             => array( '1', 'БРОЈВОГРУПА', 'NUMBERINGROUP', 'NUMINGROUP' ),
        'staticredirect'            => array( '1', '__СТАТИЧНОПРЕНАСОЧУВАЊЕ__', '__STATICREDIRECT__' ),
        'protectionlevel'           => array( '1', 'НИВОНАЗАШТИТА', 'PROTECTIONLEVEL' ),
-       'formatdate'                => array( '0', 'Ñ\84оÑ\80маÑ\82надаÑ\82Ñ\83м', 'formatdate', 'dateformat' ),
+       'formatdate'                => array( '0', 'форматдатум', 'formatdate', 'dateformat' ),
        'url_path'                  => array( '0', 'ПАТЕКА', 'PATH' ),
        'url_wiki'                  => array( '0', 'ВИКИ', 'WIKI' ),
        'url_query'                 => array( '0', 'БАРАЊЕ', 'QUERY' ),
@@ -791,7 +791,7 @@ $2',
 'gotaccount' => "Веќе имате корисничка сметка? '''$1'''.",
 'gotaccountlink' => 'Најавете се',
 'userlogin-resetlink' => 'Си ги заборавивте податоците за најава?',
-'createaccountmail' => 'по Ðµ-поÑ\88Ñ\82а',
+'createaccountmail' => 'Ð\94аÑ\98 Ð¿Ñ\80ивÑ\80емена Ð¿Ñ\80оизволна Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ð¸ Ð¸Ñ\81пÑ\80аÑ\82и Ñ\98а Ð½Ð° Ð´Ð¾Ð»Ñ\83наведенаÑ\82а Ð°Ð´Ñ\80еÑ\81а',
 'createaccountreason' => 'Причина:',
 'badretype' => 'Внесените лозинки не се совпаѓаат.',
 'userexists' => 'Корисничкото име што го внесовте е зафатено.
@@ -1105,7 +1105,8 @@ $2
 'longpageerror' => "'''Грешка: Текстот што го внесовте е голем {{PLURAL:$1|еден килобајт|$1 килобајти}}, што ја надминува границата од {{PLURAL:$2|еден килобајт|$2 килобајти}}.'''
 Затоа нема да може да се зачува.",
 'readonlywarning' => "'''ПРЕДУПРЕДУВАЊЕ: Базата на податоци е заклучена заради одржување, па нема да можете да ги зачувате промените сега.
-Пробајте да го зачувате текстот за подоцна, локално (со прекопирање) во некоја податотека.'''
+
+Ви препорачуваме да го прекопирате текстот на текстуална податотека за да го зачувате за подоцна.'''
 
 Администраторот кој ја заклучил базата на податоци го дал следново објаснување: $1",
 'protectedpagewarning' => "'''Предупредување:  Оваа страница е заклучена, така што само корисници со администраторски привилегии можат да ја уредуваат.'''
@@ -1409,7 +1410,7 @@ $1",
 'search-interwiki-default' => 'Најдено на $1:',
 'search-interwiki-more' => '(уште)',
 'search-relatedarticle' => 'Поврзано',
-'mwsuggest-disable' => 'Оневозможи AJAX-предлози',
+'mwsuggest-disable' => 'Оневозможи предлози во пребарувањето',
 'searcheverything-enable' => 'Барај во сите именски простори',
 'searchrelated' => 'поврзано',
 'searchall' => 'сè',
@@ -1457,7 +1458,7 @@ $1",
 'prefs-user-pages' => 'Кориснички страници',
 'prefs-personal' => 'Кориснички профил',
 'prefs-rc' => 'Скорешни промени',
-'prefs-watchlist' => 'Ð\9dабљудувања',
+'prefs-watchlist' => 'набљудувања',
 'prefs-watchlist-days' => 'Број на денови за приказ во списокот на набљудувања:',
 'prefs-watchlist-days-max' => 'Највеќе $1 {{PLURAL:$1|ден|дена}}',
 'prefs-watchlist-edits' => 'Максимален број на прикажани промени во проширениот список на набљудувања:',
@@ -2333,7 +2334,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Список на активни корисници',
 'activeusers-intro' => 'Ова е список на корисници кои биле на некој начин активни во последните $1 {{PLURAL:$1|ден|дена}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|уредување|уредувања}} {{PLURAL:$3|денес|во последните $3 дена}}',
+'activeusers-count' => '$1 {{PLURAL:$1|дејство|дејства}} {{PLURAL:$3|денес|во последните $3 дена}}',
 'activeusers-from' => 'Прикажи корисници почнувајќи од:',
 'activeusers-hidebots' => 'Скриј ботови',
 'activeusers-hidesysops' => 'Скриј администратори',
@@ -2396,7 +2397,7 @@ $1',
 'usermessage-editor' => 'Системски гласник',
 
 # Watchlist
-'watchlist' => 'набљудувања',
+'watchlist' => 'Ð\9dабљудувања',
 'mywatchlist' => 'Набљудувања',
 'watchlistfor2' => 'За $1 $2',
 'nowatchlist' => 'Немате ништо во списокот на набљудувања.',
@@ -2488,7 +2489,7 @@ $UNWATCHURL
 'exblank' => 'страницата беше празна',
 'delete-confirm' => 'Избриши „$1“',
 'delete-legend' => 'Бришење',
-'historywarning' => "'''Предупредување:''' Страницата којашто сакате да ја избришете има историја со околу $1 {{PLURAL:$1|ревизија|ревизии}}:",
+'historywarning' => "'''Предупредување:''' Страницата што сакате да ја избришете има историја со околу $1 {{PLURAL:$1|ревизија|ревизии}}:",
 'confirmdeletetext' => 'На пат сте трајно да избришете страница заедно со нејзината историја.
 Потврдете дека имате намера да го направите ова, дека ги разбирате последиците од тоа, дека го правите ова во согласност со [[{{MediaWiki:Policy-url}}|политиката]].',
 'actioncomplete' => 'Дејството е спроведено',
@@ -3232,6 +3233,7 @@ $1',
 'pageinfo-robot-noindex' => 'Не се индексира',
 'pageinfo-views' => 'Број на посети',
 'pageinfo-watchers' => 'Број на набљудувачи',
+'pageinfo-few-watchers' => 'Помалку од $1 {{PLURAL:$1|набљудувач|набљудувачи}}',
 'pageinfo-redirects-name' => 'Пренасочувања кон страницата',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Потстраници на страницата',
@@ -4166,7 +4168,7 @@ $5
 'specialpages-group-highuse' => 'Најкористени страници',
 'specialpages-group-pages' => 'Списоци на страници',
 'specialpages-group-pagetools' => 'Алатки за страници',
-'specialpages-group-wiki' => 'Ð\92ики-податоци и алатки',
+'specialpages-group-wiki' => 'Ð\9fодатоци и алатки',
 'specialpages-group-redirects' => 'Пренасочување на специјални страници',
 'specialpages-group-spam' => 'Алатки против спам',
 
@@ -4251,7 +4253,7 @@ $5
 'revdelete-content-unhid' => 'содржината е откриена',
 'revdelete-summary-unhid' => 'описот на уредувањето е откриен',
 'revdelete-uname-unhid' => 'корисничкото име е скриено',
-'revdelete-restricted' => 'применети ограничувања на систем оператори',
+'revdelete-restricted' => 'применети ограничувања на администратори',
 'revdelete-unrestricted' => 'отстранети ограничувања за систем оператори',
 'logentry-move-move' => '$1 ја премести страницата $3 на $4',
 'logentry-move-move-noredirect' => '$1 ја премести страницата $3 на $4 без да остави пренасочување',
@@ -4262,8 +4264,8 @@ $5
 'logentry-newusers-newusers' => 'Направена е корисничката сметка $1',
 'logentry-newusers-create' => 'Направена е корисничката сметка $1',
 'logentry-newusers-create2' => 'Направена е корисничката сметка $3; создавач: $1',
+'logentry-newusers-byemail' => '$1 ја создаде корисничката сметка $3. Лозинката ви ја испративме по е-пошта',
 'logentry-newusers-autocreate' => 'Сметката $1 е создадена автоматски',
-'newuserlog-byemail' => 'испратена лозинка по е-пошта',
 'logentry-rights-rights' => '$1 го смени групното членство за $3 од $4 во $5',
 'logentry-rights-rights-legacy' => '$1 го смени групното членство за $3',
 'logentry-rights-autopromote' => '$1 е автоматски унапреден од $4 во $5',
@@ -4320,7 +4322,8 @@ $5
 'api-error-nomodule' => 'Внатрешна грешка: нема зададено модул за подигање.',
 'api-error-ok-but-empty' => 'Внатрешна грешка: опслужувачот не одговара.',
 'api-error-overwrite' => 'Презапишувањето врз постоечки податотеки не е дозволено.',
-'api-error-stashfailed' => 'Внатрешна грешка: опслужувачот не успеа да ја складира привремената податотека.',
+'api-error-stashfailed' => 'Внатрешна грешка: Опслужувачот не успеа да ја складира привремената податотека.',
+'api-error-publishfailed' => 'Внатрешна грешка: Опслужувачот не успеа да ја објави привремената податотека.',
 'api-error-timeout' => 'Опслужувачот не одговори во очекуваното време.',
 'api-error-unclassified' => 'Се појави непозната грешка.',
 'api-error-unknown-code' => 'Непозната грешка: „$1“',
index 42bee52..e16c6ac 100644 (file)
@@ -262,6 +262,7 @@ $magicWords = array(
        'img_text_bottom'           => array( '1', 'എഴുത്ത്-താഴെ', 'text-bottom' ),
        'img_link'                  => array( '1', 'കണ്ണി=$1', 'link=$1' ),
        'img_alt'                   => array( '1', 'പകരം=$1', 'alt=$1' ),
+       'img_class'                 => array( '1', 'ശ്രേണി=$1', 'class=$1' ),
        'sitename'                  => array( '1', 'സൈറ്റിന്റെപേര്', 'SITENAME' ),
        'ns'                        => array( '0', 'നാമേ:', 'NS:' ),
        'localurl'                  => array( '0', 'ലോക്കൽയുആർഎൽ:', 'LOCALURL:' ),
@@ -307,6 +308,7 @@ $magicWords = array(
        'padleft'                   => array( '0', 'ഇടത്ത്നിറക്കുക', 'PADLEFT' ),
        'padright'                  => array( '0', 'വലത്ത്നിറക്കുക', 'PADRIGHT' ),
        'special'                   => array( '0', 'പ്രത്യേകം', 'special' ),
+       'speciale'                  => array( '0', 'സവിശേഷം', 'speciale' ),
        'defaultsort'               => array( '1', 'സ്വതവേയുള്ളക്രമപ്പെടുത്തൽ:', 'സ്വതവേയുള്ളക്രമപ്പെടുത്തൽചാവി:', 'സ്വതവേയുള്ളവർഗ്ഗക്രമപ്പെടുത്തൽ:', 'DEFAULTSORT:', 'DEFAULTSORTKEY:', 'DEFAULTCATEGORYSORT:' ),
        'filepath'                  => array( '0', 'പ്രമാണപഥം:', 'FILEPATH:' ),
        'tag'                       => array( '0', 'റ്റാഗ്', 'ടാഗ്', 'tag' ),
@@ -339,7 +341,7 @@ $messages = array(
 'tog-hidepatrolled' => 'റോന്തുചുറ്റിയ തിരുത്തുകൾ പുതിയമാറ്റങ്ങളിൽ പ്രദർശിപ്പിക്കാതിരിക്കുക',
 'tog-newpageshidepatrolled' => 'റോന്തുചുറ്റിയ താളുകൾ പുതിയതാളുകളുടെ പട്ടികയിൽ പ്രദർശിപ്പിക്കാതിരിക്കുക',
 'tog-extendwatchlist' => 'ഏറ്റവും പുതിയവ മാത്രമല്ല, എല്ലാ മാറ്റങ്ങളും ദൃശ്യമാകുന്ന വിധത്തിൽ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക വികസിപ്പിക്കുക.',
-'tog-usenewrc' => 'സമീപകാല മാറ്റങ്ങൾ താളിലും ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിലും മാറ്റങ്ങൾ താളിനനുസരിച്ച് ഗണമായി പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ് ആവശ്യമാണ്)',
+'tog-usenewrc' => 'സമീപകാല മാറ്റങ്ങൾ, ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക എന്നീ താളുകളിലെ വിവരങ്ങൾ താളുകൾക്കനുസരിച്ചുള്ള കൂട്ടങ്ങളായി ഒതുക്കി പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ് ആവശ്യമാണ്)',
 'tog-numberheadings' => 'ഉപവിഭാഗങ്ങൾക്ക് ക്രമസംഖ്യ കൊടുക്കുക',
 'tog-showtoolbar' => 'തിരുത്തൽ റ്റൂൾബാർ  പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ്)',
 'tog-editondblclick' => 'താളുകളിൽ ഇരട്ട ക്ലിക്ക് ചെയ്യുമ്പോൾ തിരുത്താനനുവദിക്കുക (ജാവാസ്ക്രിപ്റ്റ്)',
@@ -449,7 +451,7 @@ $messages = array(
 'category-empty' => "''ഈ വർഗ്ഗത്തിൽ താളുകളോ പ്രമാണങ്ങളോ ഇല്ല.''",
 'hidden-categories' => '{{PLURAL:$1|മറഞ്ഞിരിക്കുന്ന വർഗ്ഗം|മറഞ്ഞിരിക്കുന്ന വർഗ്ഗങ്ങൾ}}',
 'hidden-category-category' => 'മറഞ്ഞിരിക്കുന്ന വർഗ്ഗങ്ങൾ',
-'category-subcat-count' => '{{PLURAL:$2|à´\88 à´µàµ¼à´\97àµ\8dà´\97à´¤àµ\8dതിനàµ\8d, à´¤à´¾à´´àµ\86 à´¨àµ½à´\95ിയിരിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨ à´\92à´°àµ\81 à´\89പവർà´\97àµ\8dà´\97à´\82 à´®à´¾à´¤àµ\8dരമാണàµ\81à´³àµ\8dളതàµ\8d.|à´\88 à´µàµ¼à´\97àµ\8dà´\97à´¤àµ\8dതിനàµ\8d $2 à´\89പവർà´\97àµ\8dà´\97à´\99àµ\8dà´\99à´³àµ\81à´³àµ\8dളതിൽ {{PLURAL:$1|à´\92à´°àµ\86à´£àµ\8dà´£à´\82|$1 à´\8eà´£àµ\8dà´£à´\82}} à´¤à´¾à´´àµ\86 à´¨àµ½à´\95à´¿à´¯ിരിക്കുന്നു.}}',
+'category-subcat-count' => '{{PLURAL:$2|à´\88 à´µàµ¼à´\97àµ\8dà´\97à´¤àµ\8dതിനàµ\81 à´¤à´¾à´´àµ\86 à´¨àµ½à´\95ിയിരിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨ à´\92à´°àµ\81 à´\89പവർà´\97àµ\8dà´\97à´\82 à´®à´¾à´¤àµ\8dരമാണàµ\81à´³àµ\8dളതàµ\8d.|à´\88 à´µàµ¼à´\97àµ\8dà´\97à´¤àµ\8dതിനàµ\8d à´\86à´\95àµ\86 $2 à´\89പവർà´\97àµ\8dà´\97à´\99àµ\8dà´\99ൾ à´\89à´³àµ\8dളതിൽ {{PLURAL:$1|à´\92à´°àµ\81 à´\89പവർà´\97àµ\8dà´\97à´\82|$1 à´\89പവർà´\97àµ\8dà´\97à´\99àµ\8dà´\99ൾ}}, à´¤à´¾à´´àµ\86à´\95àµ\8dà´\95àµ\8aà´\9fàµ\81à´¤àµ\8dà´¤ിരിക്കുന്നു.}}',
 'category-subcat-count-limited' => 'ഈ വർഗ്ഗത്തിനു താഴെ നൽകിയിരിക്കുന്ന {{PLURAL:$1|ഉപവർഗ്ഗമുണ്ട്|$1 ഉപവർഗ്ഗങ്ങളുണ്ട്}}.',
 'category-article-count' => '{{PLURAL:$2|ഈ വർഗ്ഗത്തിൽ താഴെ നൽകിയിരിക്കുന്ന ഒരു താൾ മാത്രമാണുള്ളത്.|ഈ വർഗ്ഗത്തിൽ $2 താളുകളുള്ളതിൽ {{PLURAL:$1|ഒരു താൾ|$1 എണ്ണം}} താഴെ നൽകിയിരിക്കുന്നു.}}',
 'category-article-count-limited' => 'ഈ വർഗ്ഗത്തിൽ താഴെ നൽകിയിരിക്കുന്ന {{PLURAL:$1|ഒരു താൾ ഉണ്ട്|$1 താളുകൾ ഉണ്ട്}}.',
@@ -768,7 +770,7 @@ $2',
 'gotaccount' => "താങ്കൾക്ക് അംഗത്വമുണ്ടോ? '''$1'''.",
 'gotaccountlink' => 'പ്രവേശിക്കുക',
 'userlogin-resetlink' => 'താങ്കളുടെ ലോഗിൻ വിവരങ്ങൾ മറന്നു പോയോ?',
-'createaccountmail' => 'à´\87à´®àµ\86യിൽ à´µà´´à´¿',
+'createaccountmail' => 'താതàµ\8dà´\95ാലിà´\95മായ à´\95àµ\8dരമരഹിത à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´\89പയàµ\8bà´\97à´¿à´\95àµ\8dà´\95ാനനàµ\81വാദà´\82 à´¨àµ½à´\95àµ\81à´\95à´¯àµ\81à´\82 à´\85à´¤àµ\8d à´¤à´¾à´´àµ\86 à´µàµ\8dà´¯à´\95àµ\8dതമാà´\95àµ\8dà´\95ിയിരിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨ à´\87à´®àµ\86യിൽ à´µà´¿à´²à´¾à´¸à´¤àµ\8dതിലàµ\87à´¯àµ\8dà´\95àµ\8dà´\95àµ\8d à´\85à´¯à´\95àµ\8dà´\95àµ\81à´\95à´¯àµ\81à´\82 à´\9aàµ\86à´¯àµ\8dà´¯àµ\81à´\95',
 'createaccountreason' => 'കാരണം:',
 'badretype' => 'താങ്കൾ നൽകിയ രഹസ്യവാക്കുകൾ സമമല്ല.',
 'userexists' => 'നൽകിയ ഉപയോക്തൃനാമം മുമ്പേ നിലവിലുണ്ട്.
@@ -1047,7 +1049,7 @@ $1 ആണ് ഈ തടയൽ നടത്തിയത്. ''$2'' എന്ന
 ഇതു താങ്കൾത്തന്നെ എഴുതിയതാണെന്നും, അതല്ലെങ്കിൽ പകർപ്പവകാശ നിയമങ്ങളുടെ പരിധിയിലില്ലാത്ത ഉറവിടങ്ങളിൽനിന്നും പകർത്തിയതാണെന്നും ഉറപ്പാക്കുക (കുടുതൽ വിവരത്തിനു $1 കാണുക).
 '''പകർപ്പവകാശ സംരക്ഷണമുള്ള സൃഷ്ടികൾ ഒരു കാരണവശാലും ഇവിടെ പ്രസിദ്ധീകരിക്കരുത്!'''",
 'longpageerror' => "'''പിഴവ്: താങ്കൾ സമർപ്പിച്ച എഴുത്തുകൾക്ക് {{PLURAL:$1|ഒരു കിലോബൈറ്റ്|$1 കിലോബൈറ്റ്സ്}} വലിപ്പമുണ്ട്. പരമാവധി അനുവദനീയമായ വലിപ്പം {{PLURAL:$2|ഒരു കിലോബൈറ്റ്|$2 കിലോബൈറ്റ്സ്}} ആണ്‌. അതിനാലിതു സേവ് ചെയ്യാൻ സാദ്ധ്യമല്ല.'''",
-'readonlywarning' => "'''à´®àµ\81à´¨àµ\8dനറിയിപàµ\8dà´ªàµ\8d: à´¡àµ\87à´±àµ\8dറാബàµ\87à´¸àµ\8d à´ªà´°à´¿à´ªà´¾à´²à´¨à´¤àµ\8dതിനàµ\81 à´µàµ\87à´£àµ\8dà´\9fà´¿ à´¬à´¨àµ\8dധിà´\9aàµ\8dà´\9aà´¿à´°à´¿à´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81, à´\85à´¤àµ\81à´\95àµ\8aà´£àµ\8dà´\9fàµ\8d à´¤à´¾à´\99àµ\8dà´\95ളിപàµ\8dà´ªàµ\8bൾ à´µà´°àµ\81à´¤àµ\8dതിയ à´®à´¾à´±àµ\8dà´±à´\99àµ\8dà´\99ൾ à´¸àµ\87à´µàµ\8d à´\9aàµ\86à´¯àµ\8dയാൻ à´¸à´¾à´¦àµ\8dà´§àµ\8dയമലàµ\8dà´².''' à´¤à´¾à´\99àµ\8dà´\95ൾ à´µà´°àµ\81à´¤àµ\8dതിയ à´®à´¾à´±àµ\8dà´±à´\99àµ\8dà´\99ൾ à´\92à´°àµ\81 à´\9fàµ\86à´\95àµ\8dà´¸àµ\8dà´±àµ\8dà´±àµ\8d à´ªàµ\8dരമാണതàµ\8dതിലàµ\87à´\95àµ\8dà´\95àµ\8d à´ªà´\95ർതàµ\8dതി (à´\95à´\9fàµ\8dà´\9fàµ\8d & പേസ്റ്റ്) പിന്നീടുള്ള ഉപയോഗത്തിനായി സേവ് ചെയ്യുവാൻ താല്പര്യപ്പെടുന്നു. ഡേറ്റാബേസ് ബന്ധിച്ച അഡ്മിനിസ്ട്രേറ്റർ നൽകിയ വിശദീകരണം: $1",
+'readonlywarning' => "'''à´®àµ\81à´¨àµ\8dനറിയിപàµ\8dà´ªàµ\8d: à´¡àµ\87à´±àµ\8dറാബàµ\87à´¸àµ\8d à´ªà´°à´¿à´ªà´¾à´²à´¨à´¤àµ\8dതിനàµ\81 à´µàµ\87à´£àµ\8dà´\9fà´¿ à´¬à´¨àµ\8dധിà´\9aàµ\8dà´\9aà´¿à´°à´¿à´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81, à´\85à´¤àµ\81à´\95àµ\8aà´£àµ\8dà´\9fàµ\8d à´¤à´¾à´\99àµ\8dà´\95ളിപàµ\8dà´ªàµ\8bൾ à´µà´°àµ\81à´¤àµ\8dതിയ à´®à´¾à´±àµ\8dà´±à´\99àµ\8dà´\99ൾ à´¸àµ\87à´µàµ\8d à´\9aàµ\86à´¯àµ\8dയാൻ à´¸à´¾à´¦àµ\8dà´§àµ\8dയമലàµ\8dà´².''' à´¤à´¾à´\99àµ\8dà´\95ൾ à´µà´°àµ\81à´¤àµ\8dതിയ à´®à´¾à´±àµ\8dà´±à´\99àµ\8dà´\99ൾ à´\92à´°àµ\81 à´\9fàµ\86à´\95àµ\8dà´¸àµ\8dà´±àµ\8dà´±àµ\8d à´ªàµ\8dരമാണതàµ\8dതിലàµ\87à´\95àµ\8dà´\95àµ\8d à´ªà´\95ർതàµ\8dതി (à´\95àµ\8bà´ªàµ\8dപി & പേസ്റ്റ്) പിന്നീടുള്ള ഉപയോഗത്തിനായി സേവ് ചെയ്യുവാൻ താല്പര്യപ്പെടുന്നു. ഡേറ്റാബേസ് ബന്ധിച്ച അഡ്മിനിസ്ട്രേറ്റർ നൽകിയ വിശദീകരണം: $1",
 'protectedpagewarning' => "'''മുന്നറിയിപ്പ്:  ഈ താൾ കാര്യനിർവാഹക പദവിയുള്ളവർക്കു മാത്രം തിരുത്താൻ സാധിക്കാവുന്ന തരത്തിൽ സം‌രക്ഷിക്കപ്പെട്ടിരിക്കുന്നു.''' അവലംബമായി രേഖകളിൽ ലഭ്യമായ ഏറ്റവും പുതിയ വിവരം താഴെ നൽകിയിരിക്കുന്നു:",
 'semiprotectedpagewarning' => "'''ശ്രദ്ധിക്കുക:'''അംഗത്വമെടുത്തിട്ടുള്ളവർക്കുമാത്രം തിരുത്താൻ സാധിക്കുന്ന വിധത്തിൽ ഈ താൾ സംരക്ഷിക്കപ്പെട്ടിരിക്കുന്നു. അവലംബമായി രേഖകളിലെ ഏറ്റവും പുതിയ വിവരം താഴെ കൊടുത്തിരിക്കുന്നു:",
 'cascadeprotectedwarning' => "'''മുന്നറിയിപ്പ്:''' ഈ താൾ കാര്യനിർവാഹക അവകാശമുള്ളവർക്കു മാത്രം തിരുത്തുവാൻ സാധിക്കുന്ന വിധത്തിൽ സം‌രക്ഷിക്കപ്പെട്ടിട്ടുള്ളതാണ്‌. {{PLURAL:$1|താൾ|താളുകൾ}} കാസ്കേഡ് സം‌രക്ഷണം ചെയ്തപ്പോൾ അതിന്റെ ഭാഗമായി സംരക്ഷിക്കപ്പെട്ടിട്ടുള്ളതാണ്‌ ഈ താൾ.",
@@ -1348,7 +1350,7 @@ $1",
 'search-interwiki-default' => '$1 ഫലങ്ങൾ:',
 'search-interwiki-more' => '(കൂടുതൽ)',
 'search-relatedarticle' => 'ബന്ധപ്പെട്ടവ',
-'mwsuggest-disable' => 'à´\85à´\9cà´¾à´\95àµ\8dà´¸àµ\8d à´¨à´¿àµ¼à´¦àµ\8dà´¦àµ\87à´¶à´\99àµ\8dà´\99ൾ à´µàµ\87à´£àµ\8dà´\9f',
+'mwsuggest-disable' => 'തിരà´\9aàµ\8dà´\9aിലിനàµ\81 à´¨à´¿àµ¼à´¦àµ\8dà´¦àµ\87à´¶à´\99àµ\8dà´\99ൾ à´¨àµ½à´\95àµ\81à´¨àµ\8dനതàµ\8d à´ªàµ\8dരവർതàµ\8dതനരഹിതമാà´\95àµ\8dà´\95àµ\81à´\95',
 'searcheverything-enable' => 'എല്ലാ നാമമേഖലകളും തിരയുക',
 'searchrelated' => 'ബന്ധപ്പെട്ടവ',
 'searchall' => 'എല്ലാം',
@@ -2244,7 +2246,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization കാണുക.',
 # Special:ActiveUsers
 'activeusers' => 'സജീവ ഉപയോക്താക്കളുടെ പട്ടിക',
 'activeusers-intro' => 'ഇത് കഴിഞ്ഞ {{PLURAL:$1|ദിവസം|$1 ദിവസങ്ങളിൽ}} ഏതെങ്കിലും വിധത്തിലുള്ള പ്രവർത്തനങ്ങൾ ചെയ്ത ഉപയോക്താക്കളുടെ പട്ടികയാണ്.',
-'activeusers-count' => 'à´\95à´´à´¿à´\9eàµ\8dà´\9e {{PLURAL:$3|à´\92à´°àµ\81 à´¦à´¿à´µà´¸à´\82|$3 à´¦à´¿à´µà´¸à´\99àµ\8dà´\99ളിൽ}} {{PLURAL:$1|à´\92à´°àµ\81 à´¤à´¿à´°àµ\81à´¤àµ\8dà´¤àµ\8d|$1 à´¤à´¿à´°àµ\81à´¤àµ\8dà´¤àµ\81കൾ}}',
+'activeusers-count' => 'à´\95à´´à´¿à´\9eàµ\8dà´\9e {{PLURAL:$3|à´\92à´°àµ\81 à´¦à´¿à´µà´¸à´\82|$3 à´¦à´¿à´µà´¸à´\99àµ\8dà´\99ളിൽ}} {{PLURAL:$1|à´\92à´°àµ\81 à´ªàµ\8dà´°à´µàµ\83à´¤àµ\8dതി|$1 à´ªàµ\8dà´°à´µàµ\83à´¤àµ\8dതികൾ}}',
 'activeusers-from' => 'ഇങ്ങനെ തുടങ്ങുന്ന ഉപയോക്താക്കളെ കാട്ടുക:',
 'activeusers-hidebots' => 'യന്ത്രങ്ങളെ മറയ്ക്കുക',
 'activeusers-hidesysops' => 'കാര്യനിർവാഹകരെ മറയ്ക്കുക',
@@ -2307,7 +2309,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization കാണുക.',
 'usermessage-editor' => 'വ്യവസ്ഥാസന്ദേശകൻ',
 
 # Watchlist
-'watchlist' => 'ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക',
+'watchlist' => 'ശ്രദ്ധിക്കുന്ന',
 'mywatchlist' => 'ശ്രദ്ധിക്കുന്നവ',
 'watchlistfor2' => 'ഉപയോക്താവ്:$1 $2',
 'nowatchlist' => 'താങ്കൾ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽ ഇനങ്ങളൊന്നുമില്ല.',
@@ -2765,8 +2767,7 @@ $1',
 # Move page
 'move-page' => '$1 മാറ്റുക',
 'move-page-legend' => 'താൾ മാറ്റുക',
-'movepagetext' => "താഴെയുള്ള ഫോം ഒരു താളിനെ പുനർനാമകരണം ചെയ്യാനുള്ളതാണ്.
-താളിന്റെ പഴയരൂപങ്ങളും ഈ മാറ്റത്തിന് വിധേയമാക്കപ്പെടും.
+'movepagetext' => "താഴെയുള്ള ഫോം ഒരു താളിനെ പുനർനാമകരണം ചെയ്യാനുള്ളതാണ്, താളിന്റെ നാൾവഴിയും അക്കൂടെ പുതിയ പേരിലേയ്ക്ക് മാറുന്നതാണ്.
 പഴയ തലക്കെട്ട്, പുതിയ തലക്കെട്ടുള്ള താളിലേക്കുള്ള ഒരു തിരിച്ചുവിടൽ താളായി മാറും.
 പഴയ തലക്കെട്ടിലേക്കുള്ള തിരിച്ചുവിടലുകൾ യന്ത്രങ്ങൾ ഉപയോഗിച്ച് താങ്കൾക്ക് ശരിയാക്കാവുന്നതാണ്.
 അങ്ങനെ വേണ്ട എന്നാണ് താങ്കളാഗ്രഹിക്കുന്നതെങ്കിൽ [[Special:DoubleRedirects|ഇരട്ട തിരിച്ചുവിടലുകളോ]], [[Special:BrokenRedirects|ഫലപ്രദമല്ലാത്ത തിരിച്ചുവിടലുകളോ]] ഉണ്ടാകുന്നുണ്ടോയെന്ന് ദയവായി പരിശോധിക്കുക.
@@ -3117,6 +3118,7 @@ $1',
 'pageinfo-robot-noindex' => 'സൂചികാവത്കരിക്കാനാവാത്തത്',
 'pageinfo-views' => 'എടുത്തുനോക്കലുകളുടെ എണ്ണം',
 'pageinfo-watchers' => 'താൾ ശ്രദ്ധിക്കുന്നവരുടെ എണ്ണം',
+'pageinfo-few-watchers' => '{{PLURAL:$1|ശ്രദ്ധിക്കുന്നയാളുടെ|ശ്രദ്ധിക്കുന്നവരുടെ}} എണ്ണം $1 എണ്ണത്തിലും കുറവാണ്',
 'pageinfo-redirects-name' => 'ഈ താളിലേക്കുള്ള തിരിച്ചുവിടലുകൾ',
 'pageinfo-subpages-name' => 'ഈ താളിന്റെ ഉപതാളുകൾ',
 'pageinfo-subpages-value' => '$1 ({{PLURAL:$2|ഒരു തിരിച്ചുവിടൽ|$2 തിരിച്ചുവിടലുകൾ}}; {{PLURAL:$3|തിരിച്ചുവിടലല്ലാത്ത ഒരെണ്ണം|തിരിച്ചുവിടലല്ലാത്ത $3}})',
@@ -3131,6 +3133,7 @@ $1',
 'pageinfo-magic-words' => 'മാന്ത്രിക{{PLURAL:$1|വാക്ക്|വാക്കുകൾ}} ($1)',
 'pageinfo-hidden-categories' => 'മറഞ്ഞിരിക്കുന്ന {{PLURAL:$1|വർഗ്ഗം|വർഗ്ഗങ്ങൾ}} ($1)',
 'pageinfo-templates' => 'ഉൾപ്പെടുത്തിയിട്ടുള്ള {{PLURAL:$1|ഫലകം|ഫലകങ്ങൾ}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|താൾ|താളുകൾ}} ഉൾപ്പെടുത്തിയിട്ടുണ്ട് ($1 എണ്ണം)',
 'pageinfo-toolboxlink' => 'താളിന്റെ വിവരങ്ങൾ',
 'pageinfo-redirectsto' => 'തിരിച്ചുവിടുന്നു',
 'pageinfo-redirectsto-info' => 'വിവരം',
@@ -3890,7 +3893,7 @@ $5
 'specialpages-group-highuse' => 'കൂടുതൽ ഉപയോഗിക്കപ്പെട്ട താളുകൾ',
 'specialpages-group-pages' => 'താളുകളുടെ പട്ടിക',
 'specialpages-group-pagetools' => 'താളുകൾക്കുള്ള ഉപകരണങ്ങൾ',
-'specialpages-group-wiki' => 'വിà´\95àµ\8dà´\95à´¿ à´µà´¿à´µà´°à´\99àµ\8dà´\99à´³àµ\81à´\82 à´\89à´ªà´\95à´°à´£à´\99àµ\8dà´\99à´³àµ\81à´\82',
+'specialpages-group-wiki' => 'വിവരങ്ങളും ഉപകരണങ്ങളും',
 'specialpages-group-redirects' => 'തിരിച്ചുവിടൽ സംബന്ധിച്ച പ്രത്യേക താളുകൾ',
 'specialpages-group-spam' => 'പാഴെഴുത്ത് ഉപകരണങ്ങൾ',
 
@@ -3988,8 +3991,8 @@ $5
 'logentry-newusers-newusers' => '$1 എന്ന ഉപയോക്തൃ അംഗത്വം സൃഷ്ടിക്കപ്പെട്ടിരിക്കുന്നു',
 'logentry-newusers-create' => '$1 എന്ന ഉപയോക്തൃ അംഗത്വം സൃഷ്ടിക്കപ്പെട്ടിരിക്കുന്നു',
 'logentry-newusers-create2' => '$3 എന്ന ഉപയോക്തൃ അംഗത്വം $1 സൃഷ്ടിച്ചിരിക്കുന്നു',
+'logentry-newusers-byemail' => '$3 എന്ന ഉപയോക്തൃ അംഗത്വം $1 സൃഷ്ടിച്ചിരിക്കുന്നു, രഹസ്യവാക്ക് ഇമെയിൽ വഴി അയച്ചു',
 'logentry-newusers-autocreate' => '$1 എന്ന അംഗത്വം സ്വയം സൃഷ്ടിക്കപ്പെട്ടിരിക്കുന്നു',
-'newuserlog-byemail' => 'രഹസ്യവാക്ക് ഇ-മെയിൽ വഴി അയച്ചിരിക്കുന്നു',
 'logentry-rights-rights' => '$3 എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം $1, $4 എന്നതിൽ നിന്നു $5 എന്നതിലേക്കു മാറ്റിയിരിക്കുന്നു',
 'logentry-rights-rights-legacy' => '$3 എന്ന ഉപയോക്താവിന്റെ സംഘ അംഗത്വം $1 മാറ്റിയിരിക്കുന്നു',
 'logentry-rights-autopromote' => '$1 എന്ന ഉപയോക്താവ് $4 എന്നതിൽ നിന്നും $5 എന്നതിലേയ്ക്ക് സ്വയം ഉയർത്തിയിരിക്കുന്നു',
@@ -4047,6 +4050,7 @@ $5
 'api-error-ok-but-empty' => 'ആന്തരിക പിഴവ്: സെർവറിൽ നിന്ന് പ്രതികരണമൊന്നും ലഭിക്കുന്നില്ല.',
 'api-error-overwrite' => 'നിലവിലുള്ള പ്രമാണത്തിന്റെ മുകളിൽ സ്ഥാപിക്കൽ അനുവദിച്ചിട്ടില്ല.',
 'api-error-stashfailed' => 'ആന്തരിക പിഴവ്: പ്രമാണം താത്കാലികമായി സംഭരിക്കുന്നതിൽ സെർവർ പരാജയപ്പെട്ടു.',
+'api-error-publishfailed' => 'ആന്തരിക പിഴവ്: താത്കാലിക പ്രമാണം പ്രസിദ്ധീകരിക്കുന്നതിൽ സെർവർ പരാജയപ്പെട്ടു.',
 'api-error-timeout' => 'പ്രതീക്ഷിക്കപ്പെട്ട കാലാവധിക്കുള്ളിൽ സെർവർ പ്രതികരിച്ചില്ല.',
 'api-error-unclassified' => 'അപരിചിതമായ പിഴവ് സംഭവിച്ചിരിക്കുന്നു',
 'api-error-unknown-code' => 'അപരിചിതമായ പിഴവ്: "$1"',
index 79cfce4..f863d34 100644 (file)
@@ -2027,7 +2027,7 @@ URL нь зөв болон сайт ажиллагаатай байгаа эсэ
 'usermessage-template' => 'МедиаВики:ХэрэглэгчийнМэдээ',
 
 # Watchlist
-'watchlist' => 'Ð\9cиний Ñ\85Ñ\8fнаж Ð±Ñ\83й Ñ\85Ñ\83Ñ\83дÑ\81Ñ\83Ñ\83д',
+'watchlist' => 'Ð¥Ñ\8fнаÑ\85 Ð¶Ð°Ð³Ñ\81аалÑ\82',
 'mywatchlist' => 'Хяналтын хуудсын жагсаалт',
 'watchlistfor2' => 'Хэрэглэгч: $1 $2',
 'nowatchlist' => 'Танд хянаж буй зүйл байхгүй.',
@@ -3484,7 +3484,6 @@ $5
 'logentry-delete-restore' => '$3 хуудсыг $1 сэтгээсэн',
 'revdelete-restricted' => 'системийн операторуудад тавигдсан хязгаарлалтууд',
 'revdelete-unrestricted' => 'системийн операторуудаас авч хаясан хязгаарлалтууд',
-'newuserlog-byemail' => 'мэйлээр явуулсан нууц үг',
 'logentry-rights-rights' => '$1 $3 дахь грүпийн гишүүнчлэлээ $4 ээс $5 руу шилжүүллээ',
 'logentry-rights-rights-legacy' => '$1 $3 дэхь грүпийн гишүүнчлэлээ сольсон',
 'logentry-rights-autopromote' => '$1 $4 аас $5 руу автоматаар дэвшигдлээ',
index a42c163..16f11e5 100644 (file)
@@ -10,6 +10,7 @@
  * @author Aan
  * @author Angela
  * @author Ankitgadgil
+ * @author Ashupawar
  * @author Balaji
  * @author Chandu
  * @author Dnyanesh325
@@ -25,6 +26,7 @@
  * @author Mohanpurkar
  * @author Mvkulkarni23
  * @author Prabodh1987
+ * @author Pranav jagtap
  * @author Rahuldeshmukh101
  * @author Rdeshmuk
  * @author Sankalpdravid
@@ -35,6 +37,7 @@
  * @author Sudhanwa
  * @author Tusharpawar1982
  * @author V.narsikar
+ * @author Vibhavari
  * @author Vpnagarkar
  * @author Ydyashad
  * @author Ynwala
@@ -456,7 +459,7 @@ $messages = array(
 'moredotdotdot' => 'अजून...',
 'morenotlisted' => 'आणखी यादीत नाही...',
 'mypage' => 'माझे पान',
-'mytalk' => 'माà¤\9dà¥\8dया à¤\9aरà¥\8dà¤\9aा',
+'mytalk' => 'चर्चा',
 'anontalk' => 'या अंकपत्त्याचे चर्चा पान उघडा',
 'navigation' => 'सुचालन',
 'and' => '&#32;आणि',
@@ -488,6 +491,7 @@ $messages = array(
 'namespaces' => 'नामविश्वे',
 'variants' => 'अस्थिर',
 
+'navigation-heading' => 'दिक्चालन यादी',
 'errorpagetitle' => 'चूक',
 'returnto' => '$1 कडे परत चला.',
 'tagline' => '{{SITENAME}} कडून',
@@ -675,6 +679,8 @@ MySQL returned error "$3: $4".',
 'badarticleerror' => 'या पानावर ही कृती करता येत नाही.',
 'cannotdelete' => '$1 हे पान किंवा संचिका वगळता आलेली नाही. (आधीच इतर कुणी वगळले असण्याची शक्यता आहे.)',
 'cannotdelete-title' => '$1 ला वगळू शकत नाहि',
+'delete-hook-aborted' => 'खोडण्याची  क्रिया मधेच थांबवीण्यात येत आहे.
+कोणतेही कारण देण्यात आले नाही',
 'badtitle' => 'चुकीचे शीर्षक',
 'badtitletext' => 'आपण मागितलेले शीर्षक पान अयोग्य, रिकामे अथवा चूकीने जोडलेले आंतर-भाषिय किंवा आंतर-विकि शीर्षक आहे. त्यात एक किंवा अधिक शीर्षकअयोग्य चिन्हे आहेत.',
 'perfcached' => 'खालील माहिती सयीमध्ये(कॅशे) ठेवली आहे त्यामुळे ती नवीनतम {{PLURAL:$1|one result is|$1 results }} नसावी.',
@@ -1031,6 +1037,8 @@ $2',
 'edit-no-change' => 'तुमचे संपादन दुर्लक्षित करण्यात आले आहे, कारण माहितीमध्ये काहीही बदल झालेला नाही.',
 'edit-already-exists' => 'नवीन पान तयार करता येऊ शकले नाही.
 या नावाचे पान आधीच अस्तित्वात आहे.',
+'defaultmessagetext' => 'कसूर पाठ्य मजकूर',
+'invalid-content-data' => 'अवैध माहिती',
 
 # Content models
 'content-model-wikitext' => 'विकिमजकूर',
@@ -1505,6 +1513,7 @@ $1",
 'right-writeapi' => 'लेखन एपीआय चा उपयोग',
 'right-delete' => 'पृष्ठे वगळा',
 'right-bigdelete' => 'जास्त इतिहास असणारी पाने वगळा',
+'right-deletelogentry' => 'थरविक् लोग् प्रवेश् बन्द आनि चालु करने',
 'right-deleterevision' => 'एखाद्या पानाच्या विशिष्ट आवृत्त्या लपवा',
 'right-deletedhistory' => 'वगळलेल्या इतिहास नोंदी, त्यांच्या संलग्न मजकूराशिवाय पहा',
 'right-deletedtext' => 'वगळलेला मजकूर व वगळलेल्या आवर्तनांमधील बदल पहा',
@@ -2091,6 +2100,7 @@ Input:contenttype/subtype, e.g. <code>image/jpeg</code>.',
 'alllogstext' => '{{SITENAME}}च्या सर्व नोंदीचे एकत्र दर्शन.नोंद प्रकार, सदस्यनाव किंवा बाधीत पान निवडून तुम्ही तुमचे दृश्यपान मर्यादीत करू शकता.',
 'logempty' => 'नोंदीत अशी बाब नाही.',
 'log-title-wildcard' => 'या मजकुरापासून सुरू होणारी शिर्षके शोधा.',
+'showhideselectedlogentries' => 'निवडलेले लॉग पहाणे /लपवणे',
 
 # Special:AllPages
 'allpages' => 'सर्व पृष्ठे',
@@ -2111,6 +2121,7 @@ Input:contenttype/subtype, e.g. <code>image/jpeg</code>.',
 'allpages-hide-redirects' => 'पुनर्निर्देशने लपवा',
 
 # SpecialCachedPage
+'cachedspecial-viewing-cached-ttl' => 'तुम्ही पाहत आहात या पाठया ची छोटी  आवृत्ती,जी की १ तास ३० मिनिट जुनी असू शकते',
 'cachedspecial-refresh-now' => 'आखेरचे दृश्य',
 
 # Special:Categories
@@ -2839,6 +2850,7 @@ $1',
 'import-error-interwiki' => 'इंटर विकी लिंक साठी $1 पान आरक्षित केल्यामुळे ते इम्पोर्ट करू शकत नाही',
 'import-error-special' => 'विशेष नामविश्वासाठी $1 पान आरक्षित केल्यामुळे ते इम्पोर्ट करू शकत नाही. या नामविश्वात पाने असत नाहीत.',
 'import-error-invalid' => 'नाव अयोग्य असल्याने $1 पान इम्पोर्ट करू शकत नाही.',
+'import-rootpage-invalid' => 'दिलेले मूळ पान अवैध नाव आहे',
 
 # Import log
 'importlogpage' => 'ईम्पोर्ट सूची',
@@ -2963,9 +2975,12 @@ $1',
 'pageinfo-display-title' => 'दृश्य शीर्षक',
 'pageinfo-length' => 'पानाचा आकार (बाइट्समध्ये)',
 'pageinfo-language' => 'पानाच्या मजकूराची भाषा',
+'pageinfo-robot-index' => 'आनुक्रमानीत',
+'pageinfo-robot-noindex' => 'आनुक्रमानीत करू शकत नाही',
 'pageinfo-views' => 'अभिप्रायांची संख्या',
 'pageinfo-watchers' => 'पाहणाऱ्यांची संख्या',
 'pageinfo-redirects-name' => 'या पानाकडील पुनर्निर्देशने',
+'pageinfo-firstuser' => 'पृष्ठ निर्मानक',
 'pageinfo-firsttime' => 'पान निर्मितीचा दिनांक',
 'pageinfo-lastuser' => 'अलीकडील संपादक',
 'pageinfo-lasttime' => 'अलीकडिल संपादनाचा दिनांक',
@@ -3806,7 +3821,6 @@ $5
 'logentry-newusers-create' => 'एक सदस्यखाते $1 तयार केले',
 'logentry-newusers-create2' => '$1  ने  सदस्य खाते $3  निर्मित केले  आहे.',
 'logentry-newusers-autocreate' => '$1  खाते स्वयमेव निर्मित झाले आहे.',
-'newuserlog-byemail' => 'परवलीचा शब्द ई-मेल मार्फत पाठविलेला आहे',
 'logentry-rights-rights-legacy' => '$1 ने $3 चे ग्रुप सदस्यत्व बदलले',
 'rightsnone' => '(काहीही नाही)',
 
index 243b3b2..3761e40 100644 (file)
@@ -629,7 +629,7 @@ Jangan lupa untuk mengubah [[Special:Preferences|keutamaan anda di {{SITENAME}}]
 'gotaccount' => "Sudah mempunyai akaun? '''$1'''.",
 'gotaccountlink' => 'Log masuk',
 'userlogin-resetlink' => 'Lupa nama pengguna/kata laluan anda?',
-'createaccountmail' => 'melalui e-mel',
+'createaccountmail' => 'Gunakan kata laluan rawak yang sementara dan hantarnya ke alamat e-mel yang dinyatakan di bawah',
 'createaccountreason' => 'Sebab:',
 'badretype' => 'Sila ulangi kata laluan dengan betul.',
 'userexists' => 'Nama pengguna yang diisikan telah pun digunakan.
@@ -914,10 +914,10 @@ disalin daripada domain awam atau mana-mana sumber bebas lain (lihat $1 untuk bu
 '''JANGAN KIRIM KARYA HAK CIPTA ORANG LAIN TANPA KEBENARAN!'''",
 'longpageerror' => "'''Ralat: Teks yang anda serahkan itu panjangnya {{PLURAL:$1|1|$1}} kilobait, iaitu lebih panjang daripada had maksimum {{PLURAL:$2|1|$2}} kilobait.'''
 Oleh itu, ia tidak boleh disimpan.",
-'readonlywarning' => "'''AMARAN: Pangkalan data telah dikunci untuk penyenggaraan. Justeru, anda tidak boleh menyimpan suntingan anda pada masa sekarang.
-Anda boleh menyalin teks anda ke dalam komputer anda terlebih dahulu dan simpan teks tersebut di sini pada masa akan datang.'''
+'readonlywarning' => "'''Amaran: Pangkalan data ini dikunci untuk tujuan penyelenggaraan , maka anda tidak akan dapat menyimpan suntingan anda buat sekarang.'''
+Anda boleh menyalin tampal teks anda pada fail teks dan menyimpannya untuk lain kali.
 
-Yang berikut ialah penjelasan yang diberikan: $1",
+Penyelia yang menguncinya memberikan penjelasan ini: $1",
 'protectedpagewarning' => "'''Amaran: Laman ini telah dikunci supaya hanya mereka yang mempunyai keistimewaan penyelia boleh menyuntingnya.'''
 Masukan log terakhir ditunjukkan di bawah untuk rujukan:",
 'semiprotectedpagewarning' => "'''Nota:''' Laman ini telah dikunci agar hanya pengguna berdaftar sahaja boleh menyuntingnya.
@@ -1221,7 +1221,7 @@ Butirannya boleh didapati di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGEN
 'search-interwiki-default' => 'Keputusan daripada $1:',
 'search-interwiki-more' => '(lagi)',
 'search-relatedarticle' => 'Berkaitan',
-'mwsuggest-disable' => 'Matikan ciri cadangan AJAX',
+'mwsuggest-disable' => 'Matikan ciri cadangan carian',
 'searcheverything-enable' => 'Cari dalam semua ruang nama',
 'searchrelated' => 'berkaitan',
 'searchall' => 'semua',
@@ -2121,7 +2121,7 @@ Memerlukan sekurang-kurangnya satu domain peringkat tinggi, cth. "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Senarai pengguna aktif',
 'activeusers-intro' => 'Yang berikut ialah senarai pengguna yang bergiat sejak {{PLURAL:$1|semalam|$1 hari lalu}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|suntingan|suntingan}} sejak {{PLURAL:$3|semalam|$3 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 pentadbir',
@@ -2351,9 +2351,9 @@ Ini adalah tetapan semasa bagi laman '''$1''':",
 Ini adalah tetapan semasa bagi laman '''$1''':",
 'protect-cascadeon' => 'Laman ini dilindungi kerana ia terkandung dalam {{PLURAL:$1|laman|laman-laman}} berikut, yang dilindungi secara melata. Anda boleh menukar peringkat perlindunan laman ini, akan tetapi ia tidak akan menjejaskan perlindungan melata tersebut.',
 'protect-default' => 'Benarkan semua pengguna',
-'protect-fallback' => 'Perlukan keizinan "$1"',
-'protect-level-autoconfirmed' => 'Sekat pengguna baru dan pengguna tidak berdaftar',
-'protect-level-sysop' => 'Pentadbir sahaja',
+'protect-fallback' => 'Benarkan pengguna yang berizin "$1" sahaja',
+'protect-level-autoconfirmed' => 'Benarkan pengguna yang diautosahkan sahaja',
+'protect-level-sysop' => 'Benarkan pentadbir sahaja',
 'protect-summary-cascade' => 'melata',
 'protect-expiring' => 'sehingga $1 (UTC)',
 'protect-expiring-local' => 'luput $1',
@@ -2652,13 +2652,18 @@ sahkan bahawa anda betul-betul mahu melakukan tindakan ini.',
 # Move page
 'move-page' => 'Pindahkan $1',
 'move-page-legend' => 'Pindahkan laman',
-'movepagetext' => "Gunakan borang di bawah untuk menukar nama laman dan memindahkan semua maklumat sejarahnya ke nama baru. Tajuk yang lama akan dijadikan lencongan ke tajuk yang baru. Anda juga boleh mengemaskinikan semua lencongan yang menuju ke tajuk asal supaya menuju ke tajuk baru. Sebaliknya, anda boleh menyemak sekiranya terdapat [[Special:DoubleRedirects|lencongan berganda]] atau [[Special:BrokenRedirects|lencongan rosak]]. Anda bertanggungjawab memastikan semua pautan bersambung ke laman yang sepatutnya.
+'movepagetext' => "Menggunakan borang di bawah akan menukar nama halaman dan memindahkan segala sejarahnya kepada nama baru itu.
 
-Sila ambil perhatian bahawa laman tersebut '''tidak''' akan dipindahkan sekiranya laman dengan tajuk yang baru tadi telah wujud, melainkan apabila
-laman tersebut kosong atau merupakan laman lencongan dan tidak mempunyai sejarah penyuntingan. Ini bermakna anda boleh menukar semula nama sesebuah
-laman kepada nama yang asal jika anda telah melakukan kesilapan, dan anda tidak boleh menulis ganti laman yang telah wujud.
+Tajuk yang lama akan menjadi halaman lencongan kepada tajuk baru.
+Anda boleh mengemaskinikan lencongan yang menghala ke tajuk asal secara automatik.
+Jika anda memilih untuk tidak berbuat demikian, tolong semak untuk mencari lencongan [[Special:DoubleRedirects|berganda]] atau [[Special:BrokenRedirects|terputus]].
+Anda dipertanggungjawabkan untuk memastikan agar semua pautan tetap menghala ke tempat yang sepatutnya.
 
-'''AMARAN!''' Tindakan ini boleh menjadi perubahan yang tidak dijangka dan drastik bagi laman popular. Oleh itu, sila pastikan anda faham akibat yang mungkin timbul sebelum meneruskannya.",
+Sila ingat bahasa halaman '''tidak''' akan dipindahkan jika tajuk barunya sudah diambil oleh halaman yang sedia ada, melainkan halaman yang sedia ada tersebut merupakan lencongan tanpa sebarang sejarah suntingan.
+Ertinya, anda boleh menukar kembali nama halaman ke nama yang sebelumnya jika anda terbuat silap, tetapi anda tidak boleh menulis ganti halaman yang sedia ada.
+
+'''Amaran!'''
+Tindakan ini boleh mendatangkan perubahan yang drastik dan tidak dijangka untuk halaman yang popular; sila pasti bahawa anda memahami akibatnya sebelum meneruskan.",
 'movepagetext-noredirectfixer' => "Borang di bawah akan menamakan semula sesebuah laman, memindahkan kesemua sejarahnya ke nama baru.
 Nama lamanya akan menjadi sebuah laman lencongan ke laman baru tadi.
 Pastikan [[Special:DoubleRedirects|lencongan berganda]] atau [[Special:BrokenRedirects|rosak]] sudah diperiksa.
@@ -2979,6 +2984,7 @@ Simpan dalam komputer anda dan muat naiknya di sini.',
 'pageinfo-robot-noindex' => 'Tidak boleh diindekskan',
 'pageinfo-views' => 'Bilangan kunjungan',
 'pageinfo-watchers' => 'Bilangan pemantau halaman',
+'pageinfo-few-watchers' => 'Kurang daripada $1 orang pemantau',
 'pageinfo-redirects-name' => 'Lencongan ke halaman ini',
 'pageinfo-subpages-name' => 'Subhalaman untuk halaman ini',
 'pageinfo-subpages-value' => '$1 ($2 lencongan; $3 bukan lencongan)',
@@ -3762,7 +3768,7 @@ Imej ditunjuk dalam leraian penuh, jenis fail yang lain dibuka dengan atur cara
 'specialpages-group-highuse' => 'Laman popular',
 'specialpages-group-pages' => 'Senarai laman',
 'specialpages-group-pagetools' => 'Alatan laman',
-'specialpages-group-wiki' => 'Data dan alatan wiki',
+'specialpages-group-wiki' => 'Data dan peralatan',
 'specialpages-group-redirects' => 'Laman khas yang melencong',
 'specialpages-group-spam' => 'Alatan spam',
 
@@ -3859,8 +3865,8 @@ Imej ditunjuk dalam leraian penuh, jenis fail yang lain dibuka dengan atur cara
 'logentry-newusers-newusers' => 'Akaun pengguna $1 dibuka',
 'logentry-newusers-create' => 'Akaun pengguna $1 dibuka',
 'logentry-newusers-create2' => 'Akaun pengguna $3 dibuka oleh $1',
+'logentry-newusers-byemail' => 'Akaun pengguna $3 dibuka oleh $1 dan kata laluannya dihantar melalui e-mel',
 'logentry-newusers-autocreate' => 'Akaun $1 dibuka secara automatik',
-'newuserlog-byemail' => 'kata laluan dihantar melalui e-mel',
 'logentry-rights-rights' => '$1 menukar keahlian kumpulan untuk $3 dari $4 ke $5',
 'logentry-rights-rights-legacy' => '$1 menukar keahlian kumpulan untuk $3',
 'logentry-rights-autopromote' => '$1 dinaik pangkat secara automatik dari $4 ke $5',
@@ -3918,6 +3924,7 @@ Ataupun, anda boleh menggunakan borang yang mudah di bawah. Ulasan anda akan dic
 'api-error-ok-but-empty' => 'Ralat dalaman: tiada gerak balas dari pelayan.',
 'api-error-overwrite' => 'Menulis ganti fail yang telah wujud adalah tidak dibenarkan.',
 'api-error-stashfailed' => 'Ralat dalaman: pelayan tidak dapat menyimpan fail sementara.',
+'api-error-publishfailed' => 'Ralat dalaman: Pelayan tidak dapat menerbitkan fail sementara.',
 'api-error-timeout' => 'Pelayan tidak bergerak balas dalam tempoh yang diharapkan.',
 'api-error-unclassified' => 'Berlakunya ralat yang tidak diketahui',
 'api-error-unknown-code' => 'Ralat tidak diketahui: "$1"',
index 1845e5d..448f4d3 100644 (file)
@@ -3708,7 +3708,7 @@ Stampi huwa mogħrija b'risoluzzjoni sħiħa, tipi tal-fajl oħrajn jibdew bil-p
 * Paġni speċjali normali.
 * <span class="mw-specialpagerestricted">Paġni speċjali riservati.</span>
 * <span class="mw-specialpagecached">Paġni speċjali disponibbli f\'verżjoni cache (jistgħu jkunu skaduti).</span>',
-'specialpages-group-maintenance' => 'Rapporti tal-manteniment',
+'specialpages-group-maintenance' => "Rapporti ta' manutenzjoni",
 'specialpages-group-other' => 'Paġni speċjali oħrajn',
 'specialpages-group-login' => 'Idħol / oħloq kont',
 'specialpages-group-changes' => 'L-Aħħar modifiki u reġistri',
@@ -3805,7 +3805,6 @@ Stampi huwa mogħrija b'risoluzzjoni sħiħa, tipi tal-fajl oħrajn jibdew bil-p
 'logentry-newusers-create' => 'Il-kont $1 ġie maħluq',
 'logentry-newusers-create2' => 'Il-kont $3 ġie maħluq minn $1',
 'logentry-newusers-autocreate' => 'Il-kont $1 ġie maħluq awtomatikament',
-'newuserlog-byemail' => "il-password intbagħtet permezz ta' posta elettronika",
 'logentry-rights-rights' => "$1 biddel is-sħubija ta' $3 minn $4 għal $5",
 'logentry-rights-rights-legacy' => "$1 biddel is-sħubija fil-gruppi ta' $3",
 'logentry-rights-autopromote' => '$1 ġie awtomatikament promoss minn $4 għal $5',
index 421949f..e6f79b9 100644 (file)
@@ -1908,7 +1908,6 @@ Your e-mail address is not revealed when other users contact you.
 # New logging system
 'revdelete-restricted' => 'အက်ဒမင်များသို့ ကန့်သတ်ချက်များ သက်ရောက်ရန်',
 'revdelete-unrestricted' => 'အက်ဒမင်များအတွက် ကန့်သတ်ချက်များကို ဖယ်ရှားရန်',
-'newuserlog-byemail' => 'စကားဝှက်ကို အီးမေးဖြင့် ပို့လိုက်ပါပြီ။',
 'rightsnone' => '(ဘာမှမရှိ)',
 
 # API errors
index a368246..05f5854 100644 (file)
@@ -2225,7 +2225,6 @@ IP-тешкстэть — $3, саймас совавтоманть ID-сь —
 'htmlform-selectorother-other' => 'Лия',
 
 # New logging system
-'newuserlog-byemail' => 'салава валот кучозь е-сёрмасо',
 'rightsnone' => '(арасть)',
 
 # Feedback
index 48d2e38..34beed5 100644 (file)
@@ -198,25 +198,25 @@ $messages = array(
 'thu' => 'پنجشنبه',
 'fri' => 'جـومه',
 'sat' => 'شمبه',
-'january' => 'جـانـویـه',
+'january' => 'ژانویه',
 'february' => 'فوریه',
-'march' => 'مـارچ',
+'march' => 'مارس',
 'april' => 'آوریل',
 'may_long' => 'مه',
 'june' => 'ژوئن',
-'july' => 'جـولای',
+'july' => 'ژوئیه',
 'august' => 'ئـوگـه‌سـت',
 'september' => 'سـه‌پـتـه‌مـبـر',
 'october' => 'اکتبر',
 'november' => 'نـووه‌مـبـر',
 'december' => 'دسامبر',
-'january-gen' => 'جـانـویـه',
+'january-gen' => 'ژانویه',
 'february-gen' => 'فوریه',
 'march-gen' => 'مـارس',
 'april-gen' => 'آوریـل',
 'may-gen' => 'مه',
 'june-gen' => 'جـون',
-'july-gen' => 'جـولای',
+'july-gen' => 'ژوئیه',
 'august-gen' => 'ئوگـه‌سـت',
 'september-gen' => 'سـه‌پـتـه‌مـبـر',
 'october-gen' => 'اکتبر',
index 89ca035..28834b3 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-/** Norwegian Bokmål (norsk (bokmål)‎)
+/** Norwegian Bokmål (norsk bokmål)
  *
  * See MessagesQqq.php for message documentation incl. usage of parameters
  * To improve a translation please visit http://translatewiki.net
@@ -751,7 +751,7 @@ Ikke glem å endre [[Special:Preferences|innstillingene dine]] på {{SITENAME}}.
 'gotaccount' => 'Har du allerede en konto? $1.',
 'gotaccountlink' => 'Logg inn',
 'userlogin-resetlink' => 'Har du glemt påloggingsdetaljene dine?',
-'createaccountmail' => 'per e-post',
+'createaccountmail' => 'Bruk et midlertidig tilfeldig passord, og send det til e-postadressen nedenfor',
 'createaccountreason' => 'Årsak:',
 'badretype' => 'Passordene samsvarte ikke.',
 'userexists' => 'Brukernavnet er allerede i bruk.
@@ -3907,7 +3907,7 @@ Bilder vises med full oppløsning, mens andre filtyper startes direkte gjennom s
 'specialpages-group-highuse' => 'Ofte brukte sider',
 'specialpages-group-pages' => 'Sidelister',
 'specialpages-group-pagetools' => 'Sideverktøy',
-'specialpages-group-wiki' => 'Informasjon og verktøy for wikien',
+'specialpages-group-wiki' => 'Data og verktøy',
 'specialpages-group-redirects' => 'Omdirigerende spesialsider',
 'specialpages-group-spam' => 'Spamverktøy',
 
@@ -4004,8 +4004,8 @@ Bilder vises med full oppløsning, mens andre filtyper startes direkte gjennom s
 'logentry-newusers-newusers' => 'Kontoen $1 ble opprettet',
 'logentry-newusers-create' => 'Kontoen $1 ble opprettet',
 'logentry-newusers-create2' => 'Kontoen $3 ble opprettet av $1',
+'logentry-newusers-byemail' => 'Kontoen $3 ble opprettet av $1 og passordet sendt med e-post',
 'logentry-newusers-autocreate' => 'Konto $1 ble opprettet automatisk',
-'newuserlog-byemail' => 'passord sendt på e-post',
 'logentry-rights-rights' => '$1 endret gruppemedlemskap for $3 fra $4 til $5',
 'logentry-rights-rights-legacy' => '$1 endret gruppemedlemskap for $3',
 'logentry-rights-autopromote' => '$1 ble automatisk forfremmet fra $4 til $5',
@@ -4063,6 +4063,7 @@ Om det ikke er tilfellet, kan du bruke det enkle skjemaet som du finner under. K
 'api-error-ok-but-empty' => 'Intern feil: ingen svar fra server.',
 'api-error-overwrite' => 'Det er ikke tillatt å overskrive eksisterende filer.',
 'api-error-stashfailed' => 'Internal error: tjeneren greide ikke å lagre midlertidig fil.',
+'api-error-publishfailed' => 'Intern feil: Tjeneren greide ikke å publisere midlertidig fil.',
 'api-error-timeout' => 'Serveren svarte ikke innenfor forventet tid.',
 'api-error-unclassified' => 'En ukjent feil har oppstått',
 'api-error-unknown-code' => 'Ukjent feil: "$1"',
index be27a74..e2833ce 100644 (file)
@@ -63,8 +63,8 @@ $magicWords = array(
        'noeditsection'             => array( '0', '__KEENÄNNERNLINK__', '__ABSCHNITTE_NICHT_BEARBEITEN__', '__NOEDITSECTION__' ),
        'currentmonth'              => array( '1', 'AKTMAAND', 'JETZIGER_MONAT', 'JETZIGER_MONAT_2', 'CURRENTMONTH', 'CURRENTMONTH2' ),
        'currentmonthname'          => array( '1', 'AKTMAANDNAAM', 'JETZIGER_MONATSNAME', 'CURRENTMONTHNAME' ),
-       'currentmonthnamegen'       => array( '1', 'AKTMAANDNAAMGEN', 'JETZIGER_MONATSNAME_GENITIV', 'CURRENTMONTHNAMEGEN' ),
-       'currentday'                => array( '1', 'AKTDAG', 'JETZIGER_KALENDERTAG', 'CURRENTDAY' ),
+       'currentmonthnamegen'       => array( '1', 'AKTMAANDNAAMGEN', 'JETZIGER_MONATSNAME_GENITIV', 'JETZIGER_MONATSNAME_GEN', 'CURRENTMONTHNAMEGEN' ),
+       'currentday'                => array( '1', 'AKTDAG', 'JETZIGER_KALENDERTAG', 'JETZIGER_TAG', 'CURRENTDAY' ),
        'currentdayname'            => array( '1', 'AKTDAGNAAM', 'JETZIGER_WOCHENTAG', 'CURRENTDAYNAME' ),
        'currentyear'               => array( '1', 'AKTJOHR', 'JETZIGES_JAHR', 'CURRENTYEAR' ),
        'currenttime'               => array( '1', 'AKTTIED', 'JETZIGE_UHRZEIT', 'CURRENTTIME' ),
@@ -3088,7 +3088,6 @@ Geev den Dateinaam ahn den Tosatz „{{ns:file}}:“ an.',
 # New logging system
 'revdelete-restricted' => 'Inschränkungen för Administraters instellt',
 'revdelete-unrestricted' => 'Inschränkungen för Administraters rutnahmen',
-'newuserlog-byemail' => 'Passwoord per E-Mail toschickt',
 'rightsnone' => '(kene)',
 
 );
index fe35dac..06841f0 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-/** Nedersaksies (Nedersaksies)
+/** Low Saxon (Netherlands) (Nedersaksies)
  *
  * See MessagesQqq.php for message documentation incl. usage of parameters
  * To improve a translation please visit http://translatewiki.net
@@ -3883,7 +3883,6 @@ Aandere bestaandstypen wörden gelieke in t mit t MIME-type verbunnen programma
 'logentry-newusers-create' => '$1 hef n gebruker an-emaakt',
 'logentry-newusers-create2' => '$1 hef n gebruker $3 an-emaakt',
 'logentry-newusers-autocreate' => 'De gebruker $1 is automaties an-emaakt',
-'newuserlog-byemail' => 'wachtwoord is verstuurd via de netpost',
 'rightsnone' => '(gien)',
 
 # Feedback
index 05f60a9..9e40c5a 100644 (file)
@@ -189,6 +189,7 @@ $messages = array(
 'newwindow' => '(नयाँ विन्डोमा खुल्छ)',
 'cancel' => 'रद्द',
 'moredotdotdot' => 'थप...',
+'morenotlisted' => 'थप जानकारी दिइएको  छैन',
 'mypage' => 'पृष्ठ',
 'mytalk' => 'वार्ता',
 'anontalk' => 'यस IP को वारेमा वार्तालाप गर्नुहोस्',
@@ -3432,7 +3433,6 @@ $5
 'revdelete-restricted' => 'प्रबन्धकहरुमाथि सीमितता लागू गरियो',
 'revdelete-unrestricted' => 'प्रवन्धककोलागि निषेधहरु हटाइयो ।',
 'logentry-move-move' => '$1 द्वारा $3 पृष्ठलाई $4 मा सारियो',
-'newuserlog-byemail' => 'इ मेलबाट पठाइएको प्रवेशशव्द',
 'rightsnone' => '(कुनैपनि होइन)',
 
 # Feedback
index cbb1938..0417459 100644 (file)
@@ -172,7 +172,7 @@ $magicWords = array(
        'img_middle'                => array( '1', 'midden', 'middle' ),
        'img_bottom'                => array( '1', 'beneden', 'bottom' ),
        'img_text_bottom'           => array( '1', 'tekst-beneden', 'text-bottom' ),
-       'img_link'                  => array( '1', 'verwijzing=$1', 'link=$1' ),
+       'img_link'                  => array( '1', 'koppeling=$1', 'verwijzing=$1', 'link=$1' ),
        'sitename'                  => array( '1', 'SITENAAM', 'SITENAME' ),
        'ns'                        => array( '0', 'NR:', 'NS:' ),
        'nse'                       => array( '0', 'NRE:', 'NSE:' ),
@@ -212,7 +212,7 @@ $magicWords = array(
        'displaytitle'              => array( '1', 'WEERGEGEVENTITEL', 'TOONTITEL', 'DISPLAYTITLE' ),
        'rawsuffix'                 => array( '1', 'V', 'R' ),
        'newsectionlink'            => array( '1', '__NIEUWESECTIELINK__', '__NIEUWESECTIEKOPPELING__', '__NEWSECTIONLINK__' ),
-       'nonewsectionlink'          => array( '1', '__GEENNIEUWESECTIELINK__', '__GEENNIEUWKOPJEVERWIJZING__', '__NONEWSECTIONLINK__' ),
+       'nonewsectionlink'          => array( '1', '__GEENNIEUWKOPJEKOPPELING__', '__GEENNIEUWESECTIELINK__', '__GEENNIEUWKOPJEVERWIJZING__', '__NONEWSECTIONLINK__' ),
        'currentversion'            => array( '1', 'HUIDIGEVERSIE', 'CURRENTVERSION' ),
        'urlencode'                 => array( '0', 'URLCODEREN', 'CODEERURL', 'URLENCODE:' ),
        'anchorencode'              => array( '0', 'ANKERCODEREN', 'CODEERANKER', 'ANCHORENCODE' ),
@@ -794,7 +794,7 @@ Vergeet niet uw [[Special:Preferences|voorkeuren voor {{SITENAME}}]] aan te pass
 'gotaccount' => 'Hebt u al een gebruikersnaam? $1.',
 'gotaccountlink' => 'Aanmelden',
 'userlogin-resetlink' => 'Bent u uw aanmeldgegevens vergeten?',
-'createaccountmail' => 'Per e-mail',
+'createaccountmail' => 'Gebruik een tijdelijk willekeurig wachtwoord en stuur het naar het e-mailadres dat hieronder is vermeld',
 'createaccountreason' => 'Reden:',
 'badretype' => 'De ingevoerde wachtwoorden verschillen van elkaar.',
 'userexists' => 'De gekozen gebruikersnaam is al in gebruik.
@@ -1427,7 +1427,7 @@ Probeer een andere zoekopdracht.',
 'search-interwiki-default' => '$1 resultaten:',
 'search-interwiki-more' => '(meer)',
 'search-relatedarticle' => 'Gerelateerd',
-'mwsuggest-disable' => 'Suggesties via AJAX uitschakelen',
+'mwsuggest-disable' => 'Zoekuggesties uitschakelen',
 'searcheverything-enable' => 'In alle naamruimten zoeken',
 'searchrelated' => 'gerelateerd',
 'searchall' => 'alle',
@@ -2361,7 +2361,7 @@ Heeft tenminste een topleveldomein nodig, zoals bijvoorbeeld "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Aanwezige gebruikers',
 '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|bewerking|bewerkingen}} in de {{PLURAL:$3|afgelopen dag|laatste $3 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',
@@ -3260,6 +3260,7 @@ Meestal wordt dit door een externe koppeling op een zwarte lijst veroorzaakt.',
 'pageinfo-robot-noindex' => 'Niet indexeerbaar',
 'pageinfo-views' => 'Aantal weergaven',
 'pageinfo-watchers' => 'Aantal paginavolgers',
+'pageinfo-few-watchers' => 'Minder dan  {{PLURAL:$1|één volger|$1 volgers}}',
 'pageinfo-redirects-name' => 'Doorverwijzingen naar deze pagina',
 'pageinfo-subpages-name' => "Subpagina's van deze pagina",
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|doorverwijzing|doorverwijzingen}}; $3 {{PLURAL:$3|niet-doorverwijzing|niet-doorverwijzingen}})',
@@ -4055,7 +4056,7 @@ Andere bestandstypen worden direct in het met het MIME-type verbonden programma
 'specialpages-group-highuse' => "Veelgebruikte pagina's",
 'specialpages-group-pages' => 'Paginalijsten',
 'specialpages-group-pagetools' => 'Paginahulpmiddelen',
-'specialpages-group-wiki' => 'Wikigegevens en -hulpmiddelen',
+'specialpages-group-wiki' => 'Gegevens en -hulpmiddelen',
 'specialpages-group-redirects' => "Doorverwijzende speciale pagina's",
 'specialpages-group-spam' => 'Spamhulpmiddelen',
 
@@ -4152,8 +4153,8 @@ Andere bestandstypen worden direct in het met het MIME-type verbonden programma
 'logentry-newusers-newusers' => 'Gebruiker $1 is aangemaakt',
 'logentry-newusers-create' => 'Gebruiker $1 is aangemaakt',
 'logentry-newusers-create2' => 'Gebruiker $3 is aangemaakt door $1',
+'logentry-newusers-byemail' => 'Gebruiker $3 is aangemaakt door $1 en het wachtwoord is per e-mail verzonden',
 'logentry-newusers-autocreate' => 'De gebruiker $1 is automatisch aangemaakt',
-'newuserlog-byemail' => 'wachtwoord is verzonden per e-mail',
 'logentry-rights-rights' => '$1 heeft groepslidmaatschap voor $3 gewijzigd van $4 naar $5',
 'logentry-rights-rights-legacy' => '$1 heeft groepslidmaatschap voor $3 gewijzigd',
 'logentry-rights-autopromote' => '$1 is automatisch gepromoveerd van $4 naar $5',
@@ -4211,6 +4212,7 @@ Anders kunt u ook het eenvoudige formulier hieronder gebruiken. Uw reactie wordt
 '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-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-timeout' => 'De server heeft niet binnen de verwachte tijd geantwoord.',
 'api-error-unclassified' => 'Er is een onbekende fout opgetreden',
 'api-error-unknown-code' => 'Interne fout: "$1"',
index 588a70c..048ccde 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-/** Norwegian Nynorsk (norsk (nynorsk)‎)
+/** Norwegian Nynorsk (norsk nynorsk)
  *
  * See MessagesQqq.php for message documentation incl. usage of parameters
  * To improve a translation please visit http://translatewiki.net
@@ -431,12 +431,12 @@ $messages = array(
 'category-empty' => "''Kategorien inneheld for tida ingen sider eller mediefiler.''",
 'hidden-categories' => '{{PLURAL:$1|Gøymd kategori|Gøymde kategoriar}}',
 'hidden-category-category' => 'Gøymde kategoriar',
-'category-subcat-count' => 'Kategorien har {{PLURAL:$2|berre den følgjande underkategorien|{{PLURAL:$1|den følgjande underkategorien|dei følgjande $1 underkategoriane}}, av totalt $2}}.',
-'category-subcat-count-limited' => 'Denne kategorien har {{PLURAL:$1|den følgjande underkategorien|dei følgjande $1 underkategoriane}}.',
-'category-article-count' => 'Kategorien inneheld {{PLURAL:$2|berre den følgjande sida|dei følgjande {{PLURAL:$1|side|$1 sidene}}, av totalt $2}}.',
-'category-article-count-limited' => 'Følgjande {{PLURAL:$1|side|$1 sider}} er i denne kategorien.',
+'category-subcat-count' => 'Kategorien har {{PLURAL:$2|berre denne underkategorien|{{PLURAL:$1|denne underkategorien|desse $1 underkategoriane}}, av totalt $2}}.',
+'category-subcat-count-limited' => 'Kategorien har {{PLURAL:$1|denne underkategorien|desse $1 underkategoriane}}.',
+'category-article-count' => 'Kategorien inneheld {{PLURAL:$2|berre denne sida|{{PLURAL:$1|denne sida|desse $1 sidene}}, av totalt $2}}.',
+'category-article-count-limited' => '{{PLURAL:$1|Denne sida|Desse $1 sidene}} er i kategorien.',
 'category-file-count' => 'Kategorien inneheld {{PLURAL:$2|berre den følgjande fila|dei følgjande {{PLURAL:$1|fil|$1 filene}}, av totalt $2}}.',
-'category-file-count-limited' => 'Følgjande {{PLURAL:$1|fil|$1 filer}} er i denne kategorien.',
+'category-file-count-limited' => '{{PLURAL:$1|Denne fila|Desse $1 filene}} er i kategorien.',
 'listingcontinuesabbrev' => 'vidare',
 'index-category' => 'Indekserte sider',
 'noindex-category' => 'Ikkje-indekserte sider',
@@ -740,7 +740,7 @@ Gløym ikkje å endra [[Special:Preferences|innstillingane dine for {{SITENAME}}
 'gotaccount' => "Har du ein brukarkonto? '''$1'''.",
 'gotaccountlink' => 'Logg inn',
 'userlogin-resetlink' => 'Har du gløymd påloggingsopplysingane dine?',
-'createaccountmail' => 'over e-post',
+'createaccountmail' => 'Bruk eit mellombels tilfeldig passord og send det til e-postadressa som er oppgjeven under',
 'createaccountreason' => 'Årsak:',
 'badretype' => 'Passorda du skreiv inn er ikkje like.',
 'userexists' => 'Brukarnamnet er alt i bruk. Vel eit anna brukarnamn.',
@@ -1014,9 +1014,9 @@ Teksten må du ha skrive sjølv eller ha kopiert frå ein ressurs som er kompati
 
 '''LEGG ALDRI INN MATERIALE SOM ANDRE HAR OPPHAVSRETT TIL UTAN LØYVE FRÅ DEI!'''",
 'longpageerror' => "'''Feil: Teksten du sende inn er {{PLURAL:$1|éin kilobyte|$1 kilobyte}} stor, noko som er større enn øvstegrensa på {{PLURAL:$2|éin kilobyte|$2 kilobyte}}.''' Han kan difor ikkje lagrast.",
-'readonlywarning' => "'''ÅTVARING: Databasen er skriveverna på grunn av vedlikehald, så du kan ikkje lagre endringane dine akkurat no. Det kan vera lurt å  kopiere teksten din til ei tekstfil, så du kan lagre han her seinare.'''
+'readonlywarning' => "'''ÅTVARING: Databasen er skriveverna på grunn av vedlikehald, så du kan ikkje lagre endringane dine akkurat no. Det kan vera lurt å kopiere teksten din til ei tekstfil, så du kan lagre han her seinare.'''
 
-Systemadministratoren som låste databasen gav følgjande årsak: $1",
+Systemadministratoren som låste databasen gav denne årsaka: $1",
 'protectedpagewarning' => "'''ÅTVARING: Denne sida er verna, slik at berre administratorar kan endra henne.'''
 Det siste loggelementet er oppgjeve under som referanse:",
 'semiprotectedpagewarning' => "'''Merk:''' Denne sida er verna slik at berre registrerte brukarar kan endre henne.
@@ -1313,7 +1313,7 @@ Detaljar kan ein finna i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE
 'search-interwiki-default' => '$1-resultat:',
 'search-interwiki-more' => '(meir)',
 'search-relatedarticle' => 'Relatert',
-'mwsuggest-disable' => 'Slå av AJAX-forslag',
+'mwsuggest-disable' => 'Slå av søkjeframlegg',
 'searcheverything-enable' => 'Søk i alle namneroma',
 'searchrelated' => 'relatert',
 'searchall' => 'alle',
@@ -2051,7 +2051,7 @@ Ei side vert handsama som ei fleirtydingsside om ho nyttar ein mal som er lenkja
 'double-redirect-fixer' => 'Omdirigeringsfiksar',
 
 'brokenredirects' => 'Blindvegsomdirigeringar',
-'brokenredirectstext' => 'Dei følgjande omdirigeringane viser til ei side som ikkje finst:',
+'brokenredirectstext' => 'Desse omdirigeringane viser til sider som ikkje finst:',
 'brokenredirects-edit' => 'endre',
 'brokenredirects-delete' => 'slett',
 
@@ -2074,7 +2074,7 @@ Ei side vert handsama som ei fleirtydingsside om ho nyttar ein mal som er lenkja
 'ntransclusions' => 'brukt på $1 {{PLURAL:$1|side|sider}}',
 'specialpage-empty' => 'Det er ingen resultat for denne rapporten.',
 'lonelypages' => 'Foreldrelause sider',
-'lonelypagestext' => 'Følgjande sider er ikkje lenkja til på andre sider på {{SITENAME}}.',
+'lonelypagestext' => 'Desse sidene er ikkje lenkja til eller inkluderte på andre sider på {{SITENAME}}.',
 'uncategorizedpages' => 'Ukategoriserte sider',
 'uncategorizedcategories' => 'Ukategoriserte kategoriar',
 'uncategorizedimages' => 'Ukategoriserte filer',
@@ -2206,7 +2206,7 @@ Det er påkravt med eit toppnivådomene, til dømes «*.org».<br />
 # Special:ActiveUsers
 'activeusers' => 'Liste over aktive brukarar',
 '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 endring|$1 endringar}} {{PLURAL:$3|det siste døgeret|dei siste $3 døgra}}',
+'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' => 'Skjul botar',
 'activeusers-hidesysops' => 'Skjul administratorar',
@@ -2214,7 +2214,7 @@ Det er påkravt med eit toppnivådomene, til dømes «*.org».<br />
 
 # Special:ListGroupRights
 'listgrouprights' => 'Rettar for brukargrupper',
-'listgrouprights-summary' => 'Følgjande liste viser brukargruppene som er definert på denne wikien, og kvar rettar dei har. Meir informasjon om dei ulike rettane ein kan ha finn ein [[{{MediaWiki:Listgrouprights-helppage}}|her]].',
+'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.',
 'listgrouprights-key' => '* <span class="listgrouprights-granted">Innvilga rettar</span>
 * <span class="listgrouprights-granted">Tilbaketrukne rettar</span>',
 'listgrouprights-group' => 'Gruppe',
@@ -2465,7 +2465,7 @@ Her er dei noverande innstillingane for sida '''$1''':",
 # Undelete
 'undelete' => 'Sletta sider',
 'undeletepage' => 'Sletta sider',
-'undeletepagetitle' => "'''Følgjande innhald er sletta versjonar av [[:$1]]'''.",
+'undeletepagetitle' => "'''Dette innhaldet er sletta versjonar av [[:$1]]'''.",
 'viewdeletedpage' => 'Sjå sletta sider',
 'undeletepagetext' => '{{PLURAL:$1|Den følgjande sida er sletta, men ho|Dei følgjande $1 sidene er sletta, men dei}} finst enno i arkivet og kan attopprettast. Arkivet blir periodevis sletta.',
 'undelete-fieldset-title' => 'Attenderull endringar',
@@ -2622,7 +2622,7 @@ Sjå [[Special:BlockList|blokkeringslista]] for alle blokkeringane.',
 'blocklist-tempblocks' => 'Gøym mellombelse blokkeringar',
 'blocklist-addressblocks' => 'Gøym einskilde IP-blokkeringar',
 'blocklist-rangeblocks' => 'Gøym intervallblokkeringar',
-'blocklist-timestamp' => 'Tidsmerkje',
+'blocklist-timestamp' => 'Tidsmerke',
 'blocklist-target' => 'Mål',
 'blocklist-expiry' => 'Endar',
 'blocklist-by' => 'Blokkerande admin',
@@ -2713,7 +2713,7 @@ Den gamle tittelen vil verta ei omdirigeringsside til den nye.
 Du kan oppdatera omdirigeringar som peikar til den opphavlege tittelen automatisk.
 Vel du å ikkje gjera dette, pass på å sjå etter [[Special:DoubleRedirects|doble]] eller [[Special:BrokenRedirects|øydelagde omdirigeringar]].
 
-Merk at sida '''ikkje''' vert flytt dersom det alt finst ei side med den nye tittelen, minder ho er ei omdirigering og ikkje har nokon endringshistorikk. Detter tyder at du kan omdøypa ei side attende til der ho vart omdøypt frå om du gjorde eit mistak, og du kan ikkje skriva over sider som finst.
+Merk at sida '''ikkje''' vert flytt dersom det alt finst ei side med den nye tittelen, minder målsida er ei omdirigering og ikkje har nokon endringshistorikk. Detter tyder at du kan omdøypa ei side attende til der ho vart omdøypt frå om du gjorde eit mistak, og du kan ikkje skriva over sider som finst.
 
 '''ÅTVARING!'''
 Dette kan vera ei drastisk og uventa endring for ei populær side; ver viss på at du skjøner konsekvensane av dette før du held fram.",
@@ -2820,7 +2820,7 @@ Dersom du berre vil ha noverande versjon, kan du også bruke ei lenkje, til døm
 'allmessages' => 'Systemmeldingar',
 'allmessagesname' => 'Namn',
 'allmessagesdefault' => 'Standardtekst',
-'allmessagescurrent' => 'Noverande tekst',
+'allmessagescurrent' => 'Gjeldande meldingstekst',
 'allmessagestext' => 'Dette er ei liste over systemmeldingar i MediaWiki-namnerommet.
 Vitja [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] og [//translatewiki.net translatewiki.net] om du ynskjer å bidra til den generelle omsetjinga av MediaWiki.',
 'allmessagesnotsupportedDB' => "Denne sida kan ein ikkje bruka fordi «'''\$wgUseDatabaseMessages'''» er slått av.",
@@ -3045,6 +3045,7 @@ Vitja [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] og [//trans
 'pageinfo-robot-noindex' => 'Kan ikkje indekserast',
 'pageinfo-views' => 'Tal på visningar',
 'pageinfo-watchers' => 'Tal på overvakarar av sida',
+'pageinfo-few-watchers' => 'Færre enn $1 {{PLURAL:$1|som overvakar}}',
 'pageinfo-redirects-name' => 'Omdirigeringar til sida',
 'pageinfo-subpages-name' => 'Undersider av sida',
 'pageinfo-subpages-value' => '$1 ({{PLURAL:$2|éi omdirigering|$2 omdirigeringar}}; {{PLURAL:$3|éi ikkje-omdirigering|$3 ikkje-omdirigeringar}})',
@@ -3810,7 +3811,7 @@ Bilete vert viste i full oppløysing, andre filtypar vert starta direkte i dei t
 'specialpages-group-highuse' => 'Mykje brukte sider',
 'specialpages-group-pages' => 'Sidelister',
 'specialpages-group-pagetools' => 'Sideverktøy',
-'specialpages-group-wiki' => 'Informasjon og verktøy for wikien',
+'specialpages-group-wiki' => 'Data og verktøy',
 'specialpages-group-redirects' => 'Omdirigerande spesialsider',
 'specialpages-group-spam' => 'Spamverktøy',
 
@@ -3907,8 +3908,8 @@ Bilete vert viste i full oppløysing, andre filtypar vert starta direkte i dei t
 'logentry-newusers-newusers' => 'Brukarkontoen $1 vart oppretta',
 'logentry-newusers-create' => 'Brukarkontoen $1 vart oppretta',
 'logentry-newusers-create2' => 'Brukarkontoen $3 vart oppretta av $1',
+'logentry-newusers-byemail' => 'Brukarkontoen $3 vart oppretta av $1 og passord vart sendt med e-post',
 'logentry-newusers-autocreate' => 'Kontoen $1 vart oppretta av seg sjølv',
-'newuserlog-byemail' => 'passordet er sendt på e-post',
 'logentry-rights-rights' => '$1 endra gruppemedlemskap for $3 frå $4 til $5',
 'logentry-rights-rights-legacy' => '$1 endra gruppemedlemskap for $3',
 'logentry-rights-autopromote' => '$1 vart automatisk forfremja frå $4 til $5',
@@ -3966,6 +3967,7 @@ Om ikkje kan du nytta det enkle skjemaet under. Merknaden din vert lagd til på
 'api-error-ok-but-empty' => 'Intern feil: ikkje noko svar frå tenaren.',
 'api-error-overwrite' => 'Det er ikkje tillate å skriva over filer som alt finst.',
 'api-error-stashfailed' => 'Intern feil: tenaren greidde ikkje å lagra ei mellombels fil.',
+'api-error-publishfailed' => 'Intern feil: tenaren greidde ikkje å publisera mellombels fil.',
 'api-error-timeout' => 'Tenaren svara ikkje innan tida svar var venta.',
 'api-error-unclassified' => 'Det oppstod ein ukjend feil.',
 'api-error-unknown-code' => 'Ukjend feil: «$1»',
index dd85d0f..2e34445 100644 (file)
@@ -300,7 +300,7 @@ $messages = array(
 'tog-extendwatchlist' => 'Espandir la lista de seguiment per afichar totas las modificacions e non pas solament las mai recentas',
 'tog-usenewrc' => 'Agropar los cambiaments dins los darrièrs cambiaments e la lista de seguiment (necessita JavaScript)',
 'tog-numberheadings' => 'Numerotar automaticament los títols',
-'tog-showtoolbar' => 'Far veire la barra de menut de modificacion (JavaScript)',
+'tog-showtoolbar' => 'Far veire la barra de menú de modificacion (JavaScript)',
 'tog-editondblclick' => 'Modificar una pagina amb un clic doble (JavaScript)',
 'tog-editsection' => 'Modificar una seccion via los ligams [modificar]',
 'tog-editsectiononrightclick' => 'Modificar una seccion en fasent un clic drech sus son títol (JavaScript)',
@@ -658,7 +658,7 @@ Cap d'explicacion es pas estada provesida.",
 'badtitle' => 'Títol marrit',
 'badtitletext' => 'Lo títol de la pagina demandada es invalid, void o s’agís d’un títol interlenga o interprojècte mal ligat. Benlèu conten un o maites caractèrs que pòdon pas èsser utilizats dins los títols.',
 'perfcached' => "Las donadas seguendas son en escondedor e benlèu, son pas a jorn. Un maximum de {{PLURAL:$1|un resultat|$1 resultats}} es disponible dins l'escondedor.",
-'perfcachedts' => "Las donadas que segon son dins l'amagatal, son doncas pas forçadament a jorn. La darrièra actualizacion data del $1. A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
+'perfcachedts' => "Las donadas seguendas son en escondedor e benlèu, son pas a jorn. Un maximum de {{PLURAL:$1|un resultat|$1 resultats}} es disponible dins l'escondedor.",
 'querypage-no-updates' => 'Las mesas a jorn per aquesta pagina son actualamnt desactivadas. Las donadas çaijós son pas mesas a jorn.',
 'wrong_wfQuery_params' => 'Paramètres incorrèctes sus wfQuery()<br />
 Foncion : $1<br />
@@ -667,9 +667,11 @@ Requèsta : $2',
 'viewsource-title' => 'Veire la font de $1',
 'actionthrottled' => 'Accion limitada',
 'actionthrottledtext' => "Per luchar contra lo spam, l’utilizacion d'aquesta accion es limitada a un cèrt nombre de còps dins una sosta pro corta. S'avèra qu'avètz depassat aqueste limit. Ensajatz tornamai dins qualques minutas.",
-'protectedpagetext' => 'Aquesta pagina es estada protegida per empachar sa modificacion.',
+'protectedpagetext' => "Aquesta pagina es estada protegida per empachar sa modificacion o d'autras accions.",
 'viewsourcetext' => 'Podètz veire e copiar lo contengut de l’article per poder trabalhar dessús :',
-'protectedinterface' => 'Aquesta pagina provesís de tèxte d’interfàcia pel logicial e es protegida per evitar los abuses.',
+'viewyourtext' => "Podètz veire e copiar lo contengut de '''vòstras modificacions''' a aquesta pagina :",
+'protectedinterface' => 'Aquesta pagina provesís de tèxte d’interfàcia pel logicial susaqueste wiki, e es protegida per evitar los abuses.
+Per apondre o modificar de traduccions sus totes los wikis, utilizatz [//translatewiki.net/ translatewiki.net], lo projècte de localizacion de MediaWiki.',
 'editinginterface' => "'''Atencion :''' sètz a editar una pagina utilizada per crear lo tèxte de l’interfàcia del logicial. Los cambiaments se repercutaràn, segon lo contèxte, sus totas o d'unas paginas visiblas pels autres utilizaires. Per las traduccions, vos convidam a utilizar lo projècte MediaWiki d'internacionalizacion dels messatges [//translatewiki.net/wiki/Main_Page?setlang=oc translatewiki.net].",
 'sqlhidden' => '(Requèsta SQL amagada)',
 'cascadeprotected' => "Aquesta pagina es actualament protegida perque es inclusa dins {{PLURAL:$1|la pagina seguenta|las paginas seguentas}}, {{PLURAL:$1|qu'es estada protegida|que son estadas protegidas}} amb l’opcion « proteccion en cascada » activada :
@@ -717,7 +719,7 @@ Doblidetz pas de modificar [[Special:Preferences|vòstras preferéncias per {{SI
 'gotaccount' => "Ja avètz un compte ? '''$1'''.",
 'gotaccountlink' => 'Identificatz-vos',
 'userlogin-resetlink' => 'Avètz doblidat vòstres detalhs de connexion ?',
-'createaccountmail' => 'per corrièr electronic',
+'createaccountmail' => 'Utilizar un senhal aleatòri temporari e lo mandar a l’adreça de corrièl especificada çaijós',
 'createaccountreason' => 'Motiu :',
 'badretype' => "Los senhals qu'avètz picats son pas identics.",
 'userexists' => "Lo nom d'utilizaire qu'avètz picat ja es utilizat.
@@ -768,6 +770,7 @@ Atal los visitors qu'utilizan aquesta adreça IP pòdon pas crear mai de compte
 'emailconfirmlink' => 'Confirmatz vòstra adreça de corrièr electronic',
 'invalidemailaddress' => "Aquesta adreça de corrièr electronic pòt pas èsser acceptada perque sembla qu'a un format incorrècte.
 Picatz una adreça plan formatada o daissatz aqueste camp void.",
+'emaildisabled' => 'Aqueste site pòt pas mandar de corrièls.',
 'accountcreated' => 'Compte creat.',
 'accountcreatedtext' => "Lo compte d'utilizaire de $1 es estat creat.",
 'createaccount-title' => "Creacion d'un compte per {{SITENAME}}",
@@ -777,9 +780,13 @@ Ignoratz aqueste messatge se aqueste compte es estat creat per error.",
 'usernamehasherror' => "Lo nom d'utilizaire pòt pas conténer de caractèrs de hachage",
 'login-throttled' => 'Avètz ensajat tròp de temptativas de connexion darrièrament.
 Esperatz abans d’ensajar tornamai.',
+'login-abort-generic' => 'Vòstra temptativa de connexion a fracassat',
 'loginlanguagelabel' => 'Lenga: $1',
 'suspicious-userlogout' => 'Vòstra demanda de desconnexion es estada refusada perque sembla qu’es estada mandada per un navigador copat o la mesa en escondedor d’un proxy.',
 
+# E-mail sending
+'php-mail-error-unknown' => 'Error desconeguda dins la foncion mail() de PHP.',
+
 # Change password dialog
 'resetpass' => 'Cambiar lo senhal del compte',
 'resetpass_announce' => 'Vos sètz enregistrat amb un senhal temporari mandat per corrièr electronic. Per acabar l’enregistrament, vos cal picar un senhal novèl aicí :',
@@ -803,6 +810,7 @@ Benlèu ja avètz modificat vòstre senhal o demandat un senhal temporari novèl
 'passwordreset-legend' => 'Reïnicializar lo senhal',
 'passwordreset-username' => "Nom d'utilizaire :",
 'passwordreset-domain' => 'Domeni:',
+'passwordreset-capture' => 'Veire lo corrièl resultant ?',
 'passwordreset-email' => 'Adreça de corrièr electronic :',
 'passwordreset-emailtitle' => "Detailhs d'un compte per {{SITENAME}}",
 'passwordreset-emailelement' => 'Utilizaire: $1
@@ -1746,6 +1754,9 @@ Se lo problèma persistís, contactatz un [[Special:ListUsers/sysop|administrato
 'lockmanager-fail-openlock' => 'Impossible de dobrir lo fichièr de varrolh per « $1 ».',
 'lockmanager-fail-releaselock' => 'Impossible de daissar anar lo fichièr de varrolh per « $1 ».',
 
+# Special:UploadStash
+'uploadstash' => "Escondedor d'impòrt",
+
 # img_auth script messages
 'img-auth-accessdenied' => 'Accès refusat',
 'img-auth-nopathinfo' => 'PATH_INFO mancant.
@@ -1912,7 +1923,7 @@ Doblidetz pas de verificar se i a pas d’autre ligam cap als modèls abans de l
 'statistics-users-active-desc' => "Utilizaires qu'an fach al mens una accion durant {{PLURAL:$1|lo darrièr jorn|los $1 darrièrs jorns}}",
 'statistics-mostpopular' => 'Paginas mai consultadas',
 
-'disambiguations' => "Paginas d'omonimia",
+'disambiguations' => "Paginas qu'an de ligams cap a de paginas d'omonimia",
 'disambiguationspage' => 'Template:Omonimia',
 'disambiguations-text' => "Las paginas seguentas puntan cap a una '''pagina d’omonimia'''.
 Deurián puslèu puntar cap a una pagina apropriada.<br />
@@ -2132,7 +2143,7 @@ L'adreça electronica qu'avètz indicada dins [[Special:Preferences|vòstras pre
 'usermessage-editor' => 'Messatgièr del sistèma',
 
 # Watchlist
-'watchlist' => 'Ma lista de seguiment',
+'watchlist' => 'Lista de seguiment',
 'mywatchlist' => 'Lista de seguiment',
 'watchlistfor2' => 'Per $1 ($2)',
 'nowatchlist' => "Vòstra lista de seguiment conten pas cap d'article.",
@@ -2618,7 +2629,7 @@ jol nom novèl. Se vos plai, fusionatz-las manualament.",
 L’article de destinacion « [[:$1]] » existís ja.
 Lo volètz suprimir per permetre lo cambiament de nom ?',
 'delete_and_move_confirm' => 'Òc, accèpti de suprimir la pagina de destinacion per permetre lo cambiament de nom.',
-'delete_and_move_reason' => 'Pagina suprimida per permetre un cambiament de nom',
+'delete_and_move_reason' => 'Pagina suprimida per permetre lo cambiament de nom dempuèi « [[$1]] »',
 'selfmove' => 'Los títols d’origina e de destinacion son los meteisses : impossible de tornar nomenar una pagina sus ela-meteissa.',
 'immobile-source-namespace' => "Podètz pas tornar nomenar de paginas dins l'espaci de noms « $1 »",
 'immobile-target-namespace' => "Podètz pas desplaçar de paginas cap a l'espaci de noms « $1 »",
@@ -2644,6 +2655,7 @@ Causissètz un autre nom.',
 Per exportar de paginas, entratz lors títols dins la bóstia de tèxte çaijós, un títol per linha, e seleccionatz s'o desiratz o pas la version actuala amb totas las versions ancianas, amb la pagina d’istoric, o simplament la pagina actuala amb d'informacions sus la darrièra modificacion.
 
 Dins aqueste darrièr cas, podètz tanben utilizar un ligam, coma [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] per la pagina [[{{MediaWiki:Mainpage}}]].",
+'exportall' => 'Exportar totas las paginas',
 'exportcuronly' => 'Exportar unicament la version correnta sens l’istoric complet',
 'exportnohistory' => "----
 '''Nòta :''' l’exportacion completa de l’istoric de las paginas amb l’ajuda d'aqueste formulari es estada desactivada per de rasons de performàncias.",
@@ -2733,6 +2745,10 @@ Salvatz-lo sus vòstre disc dur puèi importatz-lo aicí.",
 'import-logentry-interwiki' => 'a importat (transwiki) $1',
 'import-logentry-interwiki-detail' => '$1 {{PLURAL:$1|version|versions}} dempuèi $2',
 
+# JavaScriptTest
+'javascripttest' => 'Tèst de JavaScript',
+'javascripttest-title' => 'Execucion dels tèsts $1',
+
 # Tooltip help for the actions
 'tooltip-pt-userpage' => "Vòstra pagina d'utilizaire",
 'tooltip-pt-anonuserpage' => "La pagina d'utilizare de l’IP amb la quala contribuissètz",
@@ -2750,7 +2766,7 @@ Salvatz-lo sus vòstre disc dur puèi importatz-lo aicí.",
 'tooltip-ca-viewsource' => 'Aquesta pagina es protegida. Çaquelà, ne podètz veire lo contengut.',
 'tooltip-ca-history' => "Los autors e versions precedentas d'aquesta pagina.",
 'tooltip-ca-protect' => 'Protegir aquesta pagina',
-'tooltip-ca-unprotect' => 'Desprotegir aquesta pagina',
+'tooltip-ca-unprotect' => "Cambiar la proteccion d'aquesta pagina",
 'tooltip-ca-delete' => 'Suprimir aquesta pagina',
 'tooltip-ca-undelete' => 'Restablir aquesta pagina',
 'tooltip-ca-move' => 'Tornar nomenar aquesta pagina',
@@ -2793,6 +2809,8 @@ Salvatz-lo sus vòstre disc dur puèi importatz-lo aicí.",
 'tooltip-diff' => "Permet de visualizar los cambiaments qu'avètz efectuats",
 'tooltip-compareselectedversions' => "Afichar las diferéncias entre doas versions d'aquesta pagina",
 'tooltip-watch' => 'Apondre aquesta pagina a vòstra lista de seguiment',
+'tooltip-watchlistedit-normal-submit' => 'Levar los títols',
+'tooltip-watchlistedit-raw-submit' => 'Mesa a jorn de la lista de seguiment',
 'tooltip-recreate' => 'Tornar crear la pagina, quitament se es estada escafada',
 'tooltip-upload' => 'Amodar lo mandadís',
 'tooltip-rollback' => '"Revocar" anulla en un clic la o las edicion(s) sus aquesta pagina del darrièr contributor.',
@@ -2878,9 +2896,15 @@ Aquò es probablament causat per un ligam sus lista negra que punta cap a un sit
 'pageinfo-magic-words' => '{{PLURAL:$1|Mot magic|Mots magics}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoria amagada|Categorias amagadas}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Modèl inclús|Modèls incluses}} ($1)',
+'pageinfo-toolboxlink' => 'Informacion sus la pagina',
+'pageinfo-redirectsto' => 'Redirigir cap a',
 'pageinfo-redirectsto-info' => 'info',
 'pageinfo-contentpage-yes' => 'Òc',
 'pageinfo-protect-cascading-yes' => 'Òc',
+'pageinfo-category-info' => 'Informacions sus la categoria',
+'pageinfo-category-pages' => 'Nombre de paginas',
+'pageinfo-category-subcats' => 'Nombre de soscategorias',
+'pageinfo-category-files' => 'Nombre de fichièrs',
 
 # Skin names
 'skinname-standard' => 'Estandard',
@@ -2963,6 +2987,7 @@ Se l'executatz, vòstre sistèma pòt èsser compromés.",
 'hours' => '{{PLURAL:$1|$1 ora|$1 oras}}',
 'days' => '{{PLURAL:$1|$1 jorn|$1 jorns}}',
 'ago' => 'I a $1',
+'just-now' => 'sulpic',
 
 # Bad image list
 'bad_image_list' => "Lo format es lo seguent :
@@ -3555,9 +3580,8 @@ Ensajatz la previsualizacion normala.',
 'filepath' => "Camin d'accès d'un fichièr",
 'filepath-page' => 'Fichièr :',
 'filepath-submit' => 'Validar',
-'filepath-summary' => "Aquesta pagina especiala balha lo camin d'accès complet d’un fichièr ; los imatges son mostrats en nauta resolucion, los fichièrs audiò e vidèo s’executan amb lor programa associat.
-
-Picatz lo nom del fichièr sens lo prefix « {{ns:file}}: »",
+'filepath-summary' => "Aquesta pagina especiala retorna lo camin d'accès complet d’un fichièr.
+Los imatges son afichats en nauta resolucion, los fichièrs àudio e vidèo son cargats e aviats dirèctament amb lor programa associat.",
 
 # Special:FileDuplicateSearch
 'fileduplicatesearch' => 'Recèrca dels fichièrs en doble',
@@ -3568,12 +3592,14 @@ Picatz lo nom del fichièr sens lo prefix « {{ns:file}}: »",
 'fileduplicatesearch-info' => '$1 × $2 pixèls<br />Talha del fichièr : $3<br />MIME type : $4',
 'fileduplicatesearch-result-1' => 'Lo fichièr « $1 » a pas de doble identic.',
 'fileduplicatesearch-result-n' => 'Lo fichièr « $1 » a {{PLURAL:$2|1 doble identic|$2 dobles identics}}.',
+'fileduplicatesearch-noresults' => 'Cap de fichièr nomenat « $1 » es pas estat trobat.',
 
 # Special:SpecialPages
 'specialpages' => 'Paginas especialas',
 'specialpages-note' => '----
-* Las paginas especialas
-* <strong class="mw-specialpagerestricted">en gras</strong> son restrenhudas.',
+* Paginas especialas normalas.
+* <span class="mw-specialpagerestricted">Paginas especialas restrenchas.</span>
+* <span class="mw-specialpagecached">Paginas especialas solament en escondedor (poirián èsser obsolètas).</span>',
 'specialpages-group-maintenance' => 'Rapòrts de mantenença',
 'specialpages-group-other' => 'Autras paginas especialas',
 'specialpages-group-login' => "S'identificar / s'inscriure",
@@ -3583,7 +3609,7 @@ Picatz lo nom del fichièr sens lo prefix « {{ns:file}}: »",
 'specialpages-group-highuse' => 'Utilizacion intensa de las paginas',
 'specialpages-group-pages' => 'Listas de paginas',
 'specialpages-group-pagetools' => 'Aisinas per las paginas',
-'specialpages-group-wiki' => 'Donadas del wiki e aisinas',
+'specialpages-group-wiki' => 'Donadas e aisinas',
 'specialpages-group-redirects' => 'Redireccions',
 'specialpages-group-spam' => 'Aisinas antispam',
 
@@ -3647,6 +3673,8 @@ Picatz lo nom del fichièr sens lo prefix « {{ns:file}}: »",
 'htmlform-selectorother-other' => 'Autre',
 
 # New logging system
+'logentry-delete-delete' => '$1 a suprimit la pagina $3',
+'logentry-delete-restore' => '$1 a restablit la pagina $3',
 'revdelete-content-hid' => 'contengut amagat',
 'revdelete-summary-hid' => 'resumit de modificacion amagat',
 'revdelete-uname-hid' => 'nom d’utilizaire amagat',
@@ -3663,7 +3691,6 @@ Picatz lo nom del fichièr sens lo prefix « {{ns:file}}: »",
 'logentry-newusers-create' => "Lo compte d'utilizaire $1 es estat creat",
 'logentry-newusers-create2' => "Lo compte d'utilizaire $3 es estat creat per $1",
 'logentry-newusers-autocreate' => 'Lo compte $1 es estat creat automaticament',
-'newuserlog-byemail' => 'senhal mandat per corrièr electronic',
 'rightsnone' => '(cap)',
 
 # Feedback
index 6e9b9cb..fbfbb57 100644 (file)
@@ -329,7 +329,7 @@ $messages = array(
 'fri' => 'ଶୁକ୍ର',
 'sat' => 'ଶନି',
 'january' => 'ଜାନୁଆରୀ',
-'february' => 'ଫà­\87ବà­\8dରà­\81ଆରୀ',
+'february' => 'ଫà­\87ବà­\83ଆରୀ',
 'march' => 'ମାର୍ଚ୍ଚ',
 'april' => 'ଅପ୍ରେଲ',
 'may_long' => 'ମଇ',
@@ -341,7 +341,7 @@ $messages = array(
 'november' => 'ନଭେମ୍ବର',
 'december' => 'ଡିସେମ୍ବର',
 'january-gen' => 'ଜାନୁଆରୀ',
-'february-gen' => 'ଫà­\87ବà­\8dରà­\81ଆରୀ',
+'february-gen' => 'ଫà­\87ବà­\83ଆରୀ',
 'march-gen' => 'ମାର୍ଚ୍ଚ',
 'april-gen' => 'ଅପ୍ରେଲ',
 'may-gen' => 'ମଇ',
@@ -423,7 +423,7 @@ $messages = array(
 'namespaces' => 'ନେମସ୍ପେସ',
 'variants' => 'ନିଆରା',
 
-'navigation-heading' => 'ଦିà¬\97ବାରà­\87ଣà­\80 à¬®à¬¿ନୁ',
+'navigation-heading' => 'ଦିà¬\97ବାରà­\87ଣି à¬®à­\87ନୁ',
 'errorpagetitle' => 'ଭୁଲ',
 'returnto' => '$1କୁ ଫେରିଯାନ୍ତୁ ।',
 'tagline' => '{{SITENAME}} ରୁ',
@@ -467,7 +467,7 @@ $messages = array(
 'imagepage' => 'ଫାଇଲ ପୃଷ୍ଠାଗୁଡ଼ିକ ଦେଖନ୍ତୁ',
 'mediawikipage' => 'ମେସେଜ ପୃଷ୍ଠାଟି ଦେଖାଇବେ',
 'templatepage' => 'ଛାଞ୍ଚ ପୃଷ୍ଠାଗୁଡ଼ିକ ଦେଖନ୍ତୁ',
-'viewhelppage' => 'ସହାଯà­\8bà¬\97 à¬ªà­\83ଷà­\8dଠାà¬\97à­\81ଡ଼ିà¬\95 à¬¦à­\87à¬\96ନà­\8dତà­\81',
+'viewhelppage' => 'ସହଯୋଗ ପୃଷ୍ଠାଗୁଡ଼ିକ ଦେଖନ୍ତୁ',
 'categorypage' => 'ଶ୍ରେଣୀ ପୃଷ୍ଠାଟିକୁ ଦେଖାଇବେ',
 'viewtalkpage' => 'ଆଲୋଚନାଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ',
 'otherlanguages' => 'ଅଲଗା ଭାଷା',
@@ -502,13 +502,13 @@ $1',
 'mainpage' => 'ପ୍ରଧାନ ପୃଷ୍ଠା',
 'mainpage-description' => 'ପ୍ରଧାନ ପୃଷ୍ଠା',
 'policy-url' => 'Project:ନୀତି',
-'portal' => 'ସà¬\99à­\8dଘ ସୂଚନା ଫଳକ',
-'portal-url' => 'Project:ସà¬\99à­\8dଘ ସୂଚନା ଫଳକ',
+'portal' => 'ସà¬\82ଘ ସୂଚନା ଫଳକ',
+'portal-url' => 'Project:ସà¬\82ଘ ସୂଚନା ଫଳକ',
 'privacy' => 'ଗୁମର ନୀତି',
 'privacypage' => 'Project:ଗୁମର ନୀତି',
 
 'badaccess' => 'ଅନୁମତି ମିଳିବାରେ ଅସୁବିଧା',
-'badaccess-group0' => 'à¬\86ପଣ à¬\85ନà­\81ରà­\8bଷ କରିଥିବା ପୃଷ୍ଠାଟିରେ କିଛି କାମ କରିବା ନିମନ୍ତେ ଆପଣଙ୍କୁ ଅନୁମତି ମିଳିନାହିଁ',
+'badaccess-group0' => 'à¬\86ପଣ à¬\85ନà­\81ରà­\8bଧ କରିଥିବା ପୃଷ୍ଠାଟିରେ କିଛି କାମ କରିବା ନିମନ୍ତେ ଆପଣଙ୍କୁ ଅନୁମତି ମିଳିନାହିଁ',
 'badaccess-groups' => 'ଆପଣ ଅନୁରୋଧ କରିଥିବା କାମଟି କେବଳ {{PLURAL:$2|ଗୋଠ|ଗୋଠମାନଙ୍କ ଭିତରୁ ଗୋଟିଏ ଗୋଠ}}: $1 ର ସଭ୍ୟମାନଙ୍କ ଭିତରେ ସୀମିତ ।',
 
 'versionrequired' => 'ମିଡ଼ିଆଉଇକି ର $1 ତମ ସଙ୍କଳନଟି ଲୋଡ଼ା',
@@ -517,12 +517,12 @@ $1',
 
 'ok' => 'ଠିକ ଅଛି',
 'retrievedfrom' => '"$1" ରୁ ଅଣାଯାଇଅଛି',
-'youhavenewmessages' => 'ଆପଣଙ୍କର $1 ($2).',
-'newmessageslink' => 'ନà­\82à¬\86 à¬®à­\87ସà­\87à¬\9c',
+'youhavenewmessages' => 'ଆପଣଙ୍କ ପାଇଁ $1 ($2)।',
+'newmessageslink' => 'ନà­\82à¬\86 à¬¸à¬¨à­\8dଦà­\87ଶ',
 'newmessagesdifflink' => 'ଶେଷ ବଦଳ',
 'youhavenewmessagesfromusers' => 'ଆପଣଙ୍କର {{PLURAL:$3|another user|$3 users}} ($2)ରୁ $1 ଅଛି ।',
 'youhavenewmessagesmanyusers' => 'ଆପଣଙ୍କର ବହୁତ ବ୍ୟବହାରକାରୀ($2)ମାନଙ୍କଠାରୁ $1 ଅଛି ।',
-'newmessageslinkplural' => '{{PLURAL:$1|a new message|ନୂଆ ମେସେଜ}}',
+'newmessageslinkplural' => '{{PLURAL:$1|ଏକ ନୂଆ ସନ୍ଦେଶ|ନୂଆ ସନ୍ଦେଶ}}',
 'newmessagesdifflinkplural' => 'ଶେଷ{{PLURAL:$1|change|changes}}',
 'youhavenewmessagesmulti' => '$1 ତାରିଖରେ ନୂଆ ଚିଠିଟିଏ ଆସିଛି',
 'editsection' => 'ସମ୍ପାଦନା',
@@ -575,7 +575,7 @@ $1',
 # General errors
 'error' => 'ଭୁଲ',
 'databaseerror' => 'ଡାଟାବେସରେ ଭୁଲ',
-'dberrortext' => 'à¬\8fହା à¬\8fହି à¬¸à¬«à­\8dà¬\9fବେରରେ ଭୁଲଟିଏକୁ ମଧ୍ୟ ସୂଚାଇପାରେ ।
+'dberrortext' => 'à¬\8fହା à¬\8fହି à¬¸à¬«à­\8dà¬\9fà­±େରରେ ଭୁଲଟିଏକୁ ମଧ୍ୟ ସୂଚାଇପାରେ ।
 ଶେଷଥର ଖୋଜାଯାଇଥିବା ଡାଟାବେସ ପ୍ରଶ୍ନଟି ଥିଲା:
 <blockquote><code>$1</code></blockquote>
  ଯାହାକି "<code>$2</code>"ରୁ ଥିଲା
@@ -635,8 +635,8 @@ $1',
 'protectedpagetext' => 'ଏହି ପୃଷ୍ଠାଟି ସମ୍ପାଦନା କିମ୍ବା ଅନ୍ୟକୌଣସି କାର୍ଯ୍ୟ କରିବାରୁ କିଳାଯାଇଛି ।',
 'viewsourcetext' => 'ଆପଣ ଏହି ପୃଷ୍ଠାର ଲେଖା ଦେଖିପାରିବେ ଓ ନକଲ କରିପାରିବେ:',
 'viewyourtext' => "ଆପଣ '''ଆପଣଙ୍କ ସମ୍ପାଦିତ ''' ଅଧରଟିକୁ ଦେଖିପାରିବେ ଓ ଏହି ପୃଷ୍ଠାକୁ ନକଲ କରି ପାରିବେ",
-'protectedinterface' => 'à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fି à¬\8fହି à¬\89à¬\87à¬\95ିରà­\87 à¬¥à¬¿à¬¬à¬¾ à¬¸à¬«à­\8dà¬\9fà­±à­\87ର à¬¨à¬¿à¬®à¬¨à­\8dତà­\87 à¬\87ଣà­\8dà¬\9fରଫà­\87ସ à¬²à­\87à¬\96ା à¬¯à­\8bà¬\97ାà¬\87ଥାà¬\8f à¬\93 à¬\8fହା à¬\85ବà­\8dପà­\9fବହାରà¬\95à­\81 à¬°à­\8bà¬\95ିବା à¬¨à¬¿à¬®à¬¨à­\8dତà­\87 à¬\95ିଳାଯାà¬\87à¬\85à¬\9bି à¥¤ à¬¸à¬®à¬¸à­\8dତ à¬\89à¬\87à¬\95ିର à¬\85ନà­\81ବାଦà¬\95à­\81 à¬¯à­\8bଡିବା à¬\8fବà¬\82 à¬¬à¬¦à¬³à¬¾à¬\87ବା à¬ªà¬¾à¬\87à¬\81 à¬®à­\87ଡିଆଉଇକିର ସ୍ଥାନୀୟ ପ୍ରକଳ୍ପରେ ଥିବା [//translatewiki.net/ translatewiki.net]କୁ ବ୍ୟବହାର କରନ୍ତୁ ।',
-'editinginterface' => "'''à¬\9aà­\87ତାବନà­\80:''' à¬\86ପଣ à¬¸à¬«à­\8dà¬\9fବେରର ଇଣ୍ଟରଫେସ ଲେଖା ଯୋଗାଇବା ନିମନ୍ତେ ବ୍ୟବହାର କରାଯାଉଥିବା ଏକ ପୃଷ୍ଠାର ସମ୍ପାଦନା କରୁଅଛନ୍ତି ।
+'protectedinterface' => 'à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fି à¬\8fହି à¬\89à¬\87à¬\95ିରà­\87 à¬¥à¬¿à¬¬à¬¾ à¬¸à¬«à­\8dà¬\9fà­±à­\87ର à¬¨à¬¿à¬®à¬¨à­\8dତà­\87 à¬\87ଣà­\8dà¬\9fରଫà­\87ସ à¬²à­\87à¬\96ା à¬¯à­\8bà¬\97ାà¬\87ଥାà¬\8f à¬\93 à¬\8fହା à¬\85ପବà­\8dà­\9fବହାରà¬\95à­\81 à¬°à­\8bà¬\95ିବା à¬¨à¬¿à¬®à¬¨à­\8dତà­\87 à¬\95ିଳାଯାà¬\87à¬\85à¬\9bି à¥¤ à¬¸à¬®à¬¸à­\8dତ à¬\89à¬\87à¬\95ିର à¬\85ନà­\81ବାଦà¬\95à­\81 à¬¯à­\8bଡ଼ିବା à¬\8fବà¬\82 à¬¬à¬¦à¬³à¬¾à¬\87ବା à¬ªà¬¾à¬\87à¬\81 à¬®à­\87ଡ଼ିଆଉଇକିର ସ୍ଥାନୀୟ ପ୍ରକଳ୍ପରେ ଥିବା [//translatewiki.net/ translatewiki.net]କୁ ବ୍ୟବହାର କରନ୍ତୁ ।',
+'editinginterface' => "'''à¬\9aà­\87ତାବନà­\80:''' à¬\86ପଣ à¬¸à¬«à­\8dà¬\9fà­±େରର ଇଣ୍ଟରଫେସ ଲେଖା ଯୋଗାଇବା ନିମନ୍ତେ ବ୍ୟବହାର କରାଯାଉଥିବା ଏକ ପୃଷ୍ଠାର ସମ୍ପାଦନା କରୁଅଛନ୍ତି ।
 ଏହି ଉଇକିପୃଷ୍ଠାର କିଛି ବି ବଦଳ ବାକି ସଭ୍ୟମାନଙ୍କ ଇଣ୍ଟରଫେସର ଦେଖଣାକୁ ପ୍ରଭାବିତ କରିବ ।
 ସମସ୍ତ ଉଇକିର ଅନୁବାଦ ନିମନ୍ତେ, ଦୟାକରି ମିଡ଼ିଆଉଇକିର ସ୍ଥାନୀୟକରଣ ପ୍ରକଳ୍ପ [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net] ବ୍ୟବହାର କରନ୍ତୁ ।",
 'sqlhidden' => '(SQL ପ୍ରଶ୍ନ ଲୁଚାଯାଇଅଛି)',
@@ -691,7 +691,7 @@ $2',
 'gotaccount' => 'ଆଗରୁ ଖାତାଟିଏ ଅଛି କି? $1.',
 'gotaccountlink' => 'ଲଗ ଇନ',
 'userlogin-resetlink' => 'ଲଗଇନ ତଥ୍ୟ ସବୁ ଭୁଲିଗେଲେକି?',
-'createaccountmail' => 'à¬\87-ମà­\87ଲ à¬°ୁ',
+'createaccountmail' => 'à¬\97à­\8bà¬\9fିà¬\8f à¬¸à¬¾à¬®à­\9fିà¬\95 à¬\9cାହିତାହି à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ à¬¬à­\8dà­\9fବହାର à¬\95ରନà­\8dତà­\81 à¬\8fବà¬\82 à¬\8fହାà¬\95à­\81 à¬¤à¬³à­\87 à¬¦à¬¿à¬\86ଯାà¬\87ଥିବା à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣାà¬\95à­\81 à¬ªà¬ à­\87à¬\87 à¬¦à¬¿à¬\85ନà­\8dତୁ',
 'createaccountreason' => 'କାରଣ:',
 'badretype' => 'ଆପଣ ଦେଇଥିବା ପାସବାର୍ଡ଼ଟି ମେଳଖାଉନାହିଁ ।',
 'userexists' => 'ଆପଣ ଦେଇଥିବା ଇଉଜର ନାମ ଆଗରୁ ଅଛି ।
@@ -716,14 +716,14 @@ $2',
 ଆପଣ ବନାନ ପରଖି ନିଅନ୍ତୁ ।',
 'nouserspecified' => 'ଆପଣଙ୍କୁ ଇଉଜର ନାମଟିଏ ଦେବାକୁ ପଡ଼ିବ ।',
 'login-userblocked' => 'ଏହି ସଭ୍ୟଙ୍କୁ ଅଟକାଯାଇଛି । ଲଗ ଇନ କରିବାକୁ ଅନୁମତି ନାହିଁ ।',
-'wrongpassword' => 'ଦିà¬\86ଯାà¬\87ଥିବା à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟି ଭୁଲ ଅଟେ  ।
+'wrongpassword' => 'ଦିà¬\86ଯାà¬\87ଥିବା à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟି ଭୁଲ ଅଟେ  ।
 ଦୟାକରି ଆଉଥରେ ଚେଷ୍ଟା କରନ୍ତୁ ।',
 'wrongpasswordempty' => 'ଦିଆଯାଇଥିବା ପାସବାର୍ଡ଼ଟି ଖାଲି ଛଡ଼ାଯାଇଛି ।
 ଦୟାକରି ଆଉଥରେ ଚେଷ୍ଟା କରନ୍ତୁ ।',
-'passwordtooshort' => 'ପାସବାର୍ଡ଼ଟି ଅତି କମରେ {{PLURAL:$1|ଗୋଟିଏ ଅକ୍ଷର|$1ଟି ଅକ୍ଷର}}ର ହୋଇଥିବା ଲୋଡ଼ା ।',
-'password-name-match' => 'à¬\86ପଣà¬\99à­\8dà¬\95 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟି ଆପଣଙ୍କ ଇଉଜର ନାମ ଠାରୁ ଅଲଗା ହେବା ଉଚିତ ।',
-'password-login-forbidden' => 'à¬\8fହି à¬\87à¬\89à¬\9cର à¬¨à¬¾à¬® à¬\93 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ର ବ୍ୟବହାରକୁ ବାରଣ କରାଯାଇଅଛି ।',
-'mailmypassword' => 'ପାସବାର୍ଡ଼ଟିକୁ ଇମେଲ କରି ପଠାଇବେ',
+'passwordtooshort' => 'ପାସୱାର୍ଡ଼ଟି ଅତି କମରେ {{PLURAL:$1|ଗୋଟିଏ ଅକ୍ଷର|$1ଟି ଅକ୍ଷର}}ର ହୋଇଥିବା ଲୋଡ଼ା ।',
+'password-name-match' => 'à¬\86ପଣà¬\99à­\8dà¬\95 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟି ଆପଣଙ୍କ ଇଉଜର ନାମ ଠାରୁ ଅଲଗା ହେବା ଉଚିତ ।',
+'password-login-forbidden' => 'à¬\8fହି à¬\87à¬\89à¬\9cର à¬¨à¬¾à¬® à¬\93 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ର ବ୍ୟବହାରକୁ ବାରଣ କରାଯାଇଅଛି ।',
+'mailmypassword' => 'ପାସୱାର୍ଡ଼ଟିକୁ ଇମେଲ କରି ପଠାଇବେ',
 'passwordremindertitle' => '{{SITENAME}} ପାଇଁ ନୂଆ ଅଳ୍ପ କାଳର ପାସୱାର୍ଡ଼',
 'passwordremindertext' => 'କେହିଜଣେ (ବୋଧେ ଆପଣ, $1 IP ଠିକଣାରୁ) 
 ନୂଆ ପାସବାର୍ଡ଼ଟିଏ ପାଇଁ {{SITENAME}} ($4) ରେ ଆବେଦନ କରିଅଛନ୍ତି । "$2"ଙ୍କ ପାଇଁ ଏକ ଅସ୍ଥାୟୀ ପାସବାର୍ଡ଼
@@ -736,18 +736,18 @@ and you no longer wish to change it, you may ignore this message and
 continue using your old password.',
 'noemail' => 'ସଭ୍ୟ "$1"ଙ୍କ ପାଇଁ କିଛି ବି ଇ-ମେଲ ଆଇ.ଡି. ସାଇତାଯାଇନାହିଁ  ।',
 'noemailcreate' => 'ଆପଣଙ୍କୁ ଏକ ସଚଳ ଇ-ମେଲ ଠିକଣା ଦେବାକୁ ପଡ଼ିବ',
-'passwordsent' => '"$1" à¬ªà¬¾à¬\87à¬\81 à¬¥à­\9f à¬\95ରାଯାà¬\87ଥିବା à¬\87-ମà­\87ଲà¬\95à­\81 à¬¨à­\82à¬\86 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟିଏ ପଠାଇଦିଆଗଲା ।
+'passwordsent' => '"$1" à¬ªà¬¾à¬\87à¬\81 à¬¥à­\9f à¬\95ରାଯାà¬\87ଥିବା à¬\87-ମà­\87ଲà¬\95à­\81 à¬¨à­\82à¬\86 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟିଏ ପଠାଇଦିଆଗଲା ।
 ତାହା ମିଳିଲା ପରେ ଆଉଥରେ ଲଗ ଇନ କରନ୍ତୁ ।',
-'blocked-mailpassword' => 'à¬\86ପଣà¬\99à­\8dà¬\95 IP à¬ à¬¿à¬\95ଣାà¬\9fି à¬¸à¬®à­\8dପାଦନାରà­\87 à¬­à¬¾à¬\97 à¬¨à­\87ବାରà­\81 à¬\85à¬\9fà¬\95ାଯାà¬\87à¬\9bି, à¬¤à­\87ଣà­\81 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ ଫେରନ୍ତା କାମ ବ୍ୟବହାର କରି ଅବ୍ୟବହାରକୁ ରୋକିବା ଅନୁମୋଦିତ ନୁହେଁ ।',
+'blocked-mailpassword' => 'à¬\86ପଣà¬\99à­\8dà¬\95 IP à¬ à¬¿à¬\95ଣାà¬\9fି à¬¸à¬®à­\8dପାଦନାରà­\87 à¬­à¬¾à¬\97 à¬¨à­\87ବାରà­\81 à¬\85à¬\9fà¬\95ାଯାà¬\87à¬\9bି, à¬¤à­\87ଣà­\81 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ ଫେରନ୍ତା କାମ ବ୍ୟବହାର କରି ଅବ୍ୟବହାରକୁ ରୋକିବା ଅନୁମୋଦିତ ନୁହେଁ ।',
 'eauthentsent' => 'ଆପଣଙ୍କ ବଛା ଇ-ମେଲ ଠିକଣାକୁ ଏକ ଥୟ କରିବା ଇ-ମେଲଟିଏ ପଠାଇଦିଆଗଲା ।
 ଖାତାଟି ଆପଣଙ୍କର ବୋଲି ଥୟ କରିବା ନିମନ୍ତେ ଆଉ କେଉଁ ଇ-ମେଲ ଆପଣଙ୍କ ଖାତାକୁ ପଠାହେବା ଆଗରୁ ଆପଣଙ୍କୁ ସେହି ଇ-ମେଲରେ ଥିବା ସୂଚନା ଅନୁସରଣ କରିବାକୁ ପଡ଼ିବ ।',
-'throttled-mailpassword' => 'à¬\97ତ {{PLURAL:$1|à¬\8fà¬\95 à¬\98ଣà­\8dà¬\9fାରà­\87|$1 à¬\98ଣà­\8dà¬\9fାରà­\87}} à¬\86ପଣà¬\99à­\8dà¬\95à­\81 à¬\8fà¬\95 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ ମନେକରିବା ସୂଚନାଟିଏ ପଠାଯାଇଛି ।
-à¬\85ବà­\8dà­\9fବହାରà¬\95à­\81 à¬°à­\8bà¬\95ିବା à¬¨à¬¿à¬®à¬¨à­\8dତà­\87, {{PLURAL:$1|à¬\8fà¬\95 à¬\98ଣà­\8dà¬\9fାରà­\87|$1 à¬\98ଣà­\8dà¬\9fାରà­\87}} à¬\95à­\87ବଳ à¬\97à­\8bà¬\9fିà¬\8f à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ ହିଁ ପଠାହେବ ।',
+'throttled-mailpassword' => 'à¬\97ତ {{PLURAL:$1|à¬\8fà¬\95 à¬\98ଣà­\8dà¬\9fାରà­\87|$1 à¬\98ଣà­\8dà¬\9fାରà­\87}} à¬\86ପଣà¬\99à­\8dà¬\95à­\81 à¬\8fà¬\95 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ ମନେକରିବା ସୂଚନାଟିଏ ପଠାଯାଇଛି ।
+à¬\85ବà­\8dà­\9fବହାରà¬\95à­\81 à¬°à­\8bà¬\95ିବା à¬¨à¬¿à¬®à¬¨à­\8dତà­\87, {{PLURAL:$1|à¬\8fà¬\95 à¬\98ଣà­\8dà¬\9fାରà­\87|$1 à¬\98ଣà­\8dà¬\9fାରà­\87}} à¬\95à­\87ବଳ à¬\97à­\8bà¬\9fିà¬\8f à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ ହିଁ ପଠାହେବ ।',
 'mailerror' => 'ମେଲ ପଠାଇବାରେ ଭୁଲ : $1',
 'acct_creation_throttle_hit' => 'ଏହି ଉଇକିର ଦେଖଣାହାରୀ ମାନେ ଆପଣଙ୍କ IP ଠିକଣା ବ୍ୟବହାର କରି ବିଗତ ଦିନରେ {{PLURAL:$1|ଖାତାଟିଏ|$1 ଗୋଟି ଖାତା}} ତିଆରି କରିଛନ୍ତି ଯାହା ସେହି ସମୟସୀମା ଭିତରେ ସବୁଠାରୁ ଅଧିକ ଥିଲା ।
 ତେଣୁ, ଏହି IP ଠିକଣାର ଦେଖଣାହାରୀ ଗଣ ଏବେ ଆଉ ଅଧିକ ଖାତା ଖୋଲିପାରିବେ ନାହିଁ ।',
 'emailauthenticated' => '$2 ତାରିଖ $3 ଘଟିକା ବେଳେ ଆପଣଙ୍କ ଇ-ମେଲ ଠିକଣାଟି ଅନୁମୋଦିତ ହେଲା ।',
-'emailnotauthenticated' => 'à¬\86ପନà¬\99à­\8dà¬\95 à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣାà¬\9fି à¬\85ନà­\81ମà­\8bଦିତà­\8d ହୋଇନାହିଁ ।
+'emailnotauthenticated' => 'à¬\86ପଣà¬\99à­\8dà¬\95 à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣାà¬\9fି à¬\85ନà­\81ମà­\8bଦିତ ହୋଇନାହିଁ ।
 ଏହି ସବୁ ସୁବିଧାକୁ ନେଇ କିଛି ବି ଇ-ମେଲ ଆପଣଙ୍କୁ ପଠାଯିବ ନାହିଁ ।',
 'noemailprefs' => 'ଆପଣଙ୍କ ପସନ୍ଦ ଭିତରେ ଏକ ଇ-ମେଲ ଠିକଣା ଦିଅନ୍ତୁ ଯାହା ଏହି ସବୁ ସୁବିଧାକୁ ସଚଳ କରାଇବ ।',
 'emailconfirmlink' => 'ଆପଣଙ୍କ ଇମେଲ ଆଇ.ଡି.ଟି ଠିକ ବୋଲି ଥୟ କରନ୍ତୁ',
@@ -758,10 +758,10 @@ continue using your old password.',
 'accountcreated' => 'ଖାତାଟି ଖୋଲାହୋଇଗଲା',
 'accountcreatedtext' => '$1 ପାଇଁ ନୂଆ ଖାତାଟିଏ ତିଆରି ହୋଇଗଲା ।',
 'createaccount-title' => '{{SITENAME}} ପାଇଁ ଖାତା ଖୋଲା',
-'createaccount-text' => 'à¬\95à­\87ହି à¬\9cଣà­\87 à¬\86ପଣà¬\99à­\8dà¬\95 à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣାରà­\87 {{SITENAME}} ($4) à¬°à­\87 "$2" à¬¨à¬¾à¬®à¬°à­\87, "$3" à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ରେ ଖାତାଟିଏ ତିଆରି କରିଅଛି ।
+'createaccount-text' => 'à¬\95à­\87ହି à¬\9cଣà­\87 à¬\86ପଣà¬\99à­\8dà¬\95 à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣାରà­\87 {{SITENAME}} ($4) à¬°à­\87 "$2" à¬¨à¬¾à¬®à¬°à­\87, "$3" à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ରେ ଖାତାଟିଏ ତିଆରି କରିଅଛି ।
 ଆପଣ ଏବେ ଲଗ ଇନ କରି ନିଜର ପାସବାର୍ଡ଼ଟିକୁ ବଦଳାଇଦିଅନ୍ତୁ ।
 
-ଯଦି ଭୁଲରେ ଏହି ଖାତାଟି ତିଆରି କରାଯାଇଥାଏ ତେବେ ଏହି ସୂଚନାଟିକୁ ଅଣଦେଖା କରିବେ ।',
+ଯଦି ଭୁଲରେ ଏହି ଖାତାଟି ତିଆରି କରାଯାଇଥାଏ, ତେବେ ଏହି ସୂଚନାଟିକୁ ଅଣଦେଖା କରିବେ ।',
 'usernamehasherror' => 'ଇଉଜର ନାମରେ ହାସ ଅକ୍ଷର (hash characters) ରହି ପାରିବନାହିଁ',
 'login-throttled' => 'ଆପଣ ବହୁ ଥର ଲଗ ଇନ କରିବାର ଉଦ୍ୟମ କରିଅଛନ୍ତି ।
 ଦୟାକରି ଆଉଥରେ ଚେଷ୍ଟା କରିବା ଆଗରୁ କିଛି କାଳ ଅପେକ୍ଷ କରନ୍ତୁ ।',
@@ -778,19 +778,19 @@ continue using your old password.',
 'resetpass' => 'ପାସୱାର୍ଡ଼ ବଦଳାନ୍ତୁ',
 'resetpass_announce' => 'ଆପଣ ଏକ ଅସ୍ଥାୟୀ ଇ-ମେଲରେ ଯାଇଥିବା କୋଡ଼ ସହାୟତାରେ ଲଗ ଇନ କରିଅଛନ୍ତି ।
 ଲଗ ଇନ ଶେଷ କରିବା ନିମନ୍ତେ ଆପଣଙ୍କୁ ଏହିଠାରେ ନୂଆ ପାସବାର୍ଡ଼ଟିଏ ଦେବାକୁ ପଡ଼ିବ:',
-'resetpass_header' => 'à¬\96ାତାର à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟିକୁ ବଦଳାଇ ଦିଅନ୍ତୁ',
+'resetpass_header' => 'à¬\96ାତାର à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟିକୁ ବଦଳାଇ ଦିଅନ୍ତୁ',
 'oldpassword' => 'ପୁରୁଣା ପାସୱାର୍ଡ଼:',
 'newpassword' => 'ନୂଆ ପାସୱାର୍ଡ଼:',
 'retypenew' => 'ପାସୱାର୍ଡ଼ ଆଉଥରେ ଦିଅନ୍ତୁ:',
-'resetpass_submit' => 'ପାସବାରà­\8dଡ଼à¬\9fି ଦେଇ ଲଗ ଇନ କରନ୍ତୁ',
+'resetpass_submit' => 'ପାସୱାରà­\8dଡ଼à¬\9fିà¬\8f ଦେଇ ଲଗ ଇନ କରନ୍ତୁ',
 'resetpass_success' => 'ଆପଣଙ୍କ ପାସବାର୍ଡ଼ଟି ବଦଳାଇ ଦିଆଗଲା !
 ଏବେ ଲଗ ଇନ କରୁଅଛୁଁ...',
 'resetpass_forbidden' => 'ପାସବାର୍ଡ଼ମାନ ବଦଳା ଯାଇପାରିବ ନାହିଁ',
 'resetpass-no-info' => 'ଏହି ପୃଷ୍ଠାଟିକୁ ସିଧା ଖୋଲିବା ନିମନ୍ତେ ଆପଣଙ୍କୁ ଲଗ ଇନ କରିବାକୁ ପଡ଼ିବ ।',
 'resetpass-submit-loggedin' => 'ପାସୱାର୍ଡ଼ ବଦଳାନ୍ତୁ',
 'resetpass-submit-cancel' => 'ନାକଚ',
-'resetpass-wrong-oldpass' => 'à¬\85ସà­\8dଥାà­\9fà­\80 à¬¬à¬¾ à¬\8fବà­\87à¬\95ାର à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟି ଭୁଲ ଅଟେ ।
-à¬\86ପଣ à¬¬à­\8bଧ à¬¹à­\81à¬\8f à¬\86à¬\97ରà­\81 à¬¸à¬«à¬³ à¬­à¬¾à¬¬à¬°à­\87 à¬¨à¬¿à¬\9cର à¬ªà¬¾à¬¸à¬¬à¬¾à¬°à­\8dଡ଼à¬\9fି à¬¬à¬¦à¬³à¬¾à¬\87ଦà­\87à¬\87à¬\9bନà­\8dତି à¬¬à¬¾ à¬¨à­\82à¬\86 à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟିଏ ପାଇଁ ଆବେଦନ କରିଅଛନ୍ତି ।',
+'resetpass-wrong-oldpass' => 'à¬\85ସà­\8dଥାà­\9fà­\80 à¬¬à¬¾ à¬\8fବà­\87à¬\95ାର à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟି ଭୁଲ ଅଟେ ।
+à¬\86ପଣ à¬¬à­\8bଧ à¬¹à­\81à¬\8f à¬\86à¬\97ରà­\81 à¬¸à¬«à¬³ à¬­à¬¾à¬¬à¬°à­\87 à¬¨à¬¿à¬\9cର à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ଼à¬\9fି à¬¬à¬¦à¬³à¬¾à¬\87ଦà­\87à¬\87à¬\9bନà­\8dତି à¬¬à¬¾ à¬¨à­\82à¬\86 à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟିଏ ପାଇଁ ଆବେଦନ କରିଅଛନ୍ତି ।',
 'resetpass-temp-password' => 'ଅସ୍ଥାୟୀ ପାସୱାର୍ଡ଼:',
 
 # Special:PasswordReset
@@ -810,28 +810,28 @@ continue using your old password.',
 
 $2
 
-{{PLURAL:$3|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à¬¬à¬¾à¬°à­\8dଡ଼à¬\9fି|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ସବୁ}} {{PLURAL:$5|ଦିନକରେ|$5 ଦିନରେ ଅଚଳ}} ହୋଇଯିବ ।
-à¬\86ପଣ à¬\8fବà­\87 à¬²à¬\97 à¬\87ନ à¬\95ରି à¬¨à­\82à¬\86 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟିଏ ବାଛନ୍ତୁ । ଯହି ଆଉ କେହି ଜଣେ ଏହି ଅନୁରୋଧ କରିଥାନ୍ତି
-à¬\95ିମà­\8dବା à¬\86ପଣ à¬\8fବà­\87 à¬¨à¬¿à¬\9cର à¬®à­\82ଳ à¬ªà¬¾à¬¸à¬¬à¬¾à¬°à­\8dଡ଼ à¬®à¬¨à­\87 à¬ªà¬\95ାà¬\87 à¬ªà¬¾à¬°à¬¿à¬¥à¬¾à¬¨à­\8dତି à¬¤à­\87ବà­\87 à¬\8fହି à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟିକୁ ଆଉ ବଦଳାଇବା ଲୋଡ଼ା ନାହିଁ ।
-à¬\86ପଣ à¬¨à¬¿à¬\9c à¬ªà­\81ରà­\81ଣା à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟି ଆଗପରି ବ୍ୟବହାର କରିପାରନ୍ତି ।',
-'passwordreset-emailtext-user' => '{{SITENAME}}ରà­\87 à¬¥à¬¿à¬¬à¬¾ à¬¬à­\8dà­\9fà­\9fବହାରà¬\95ାରà­\80 $1 {{SITENAME}} ($4) à¬¸à¬¾à¬\87à¬\9fରà­\87 à¬¥à¬¿à¬¬à¬¾ à¬\86ପଣà¬\99à­\8dà¬\95 à¬\96ାତାର à¬¸à¬¬à¬¿à¬¶à­\87ଷ à¬\9cାଣିବାà¬\95à­\81 à¬\85ନà­\81ରà­\8bଧ à¬\95ରିà¬\9bନà­\8dତି à¥¤ à¬\8fହି à¬\87ମà­\87ଲ à¬ à¬¿à¬\95ଣା à¬¸à¬¹à¬¿à¬¤ à¬¤à¬³à¬²à¬¿à¬\96ିତ à¬¬à­\8dà­\9fବହାରà¬\95ାରà­\80à¬\99à­\8dà¬\95 {{PLURAL:$3|à¬\96ାତା|à¬\96ାତାସମà­\82ହ}} à¬¯à­\8bଡ଼ା:
+{{PLURAL:$3|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ଼à¬\9fି|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ସବୁ}} {{PLURAL:$5|ଦିନକରେ|$5 ଦିନରେ ଅଚଳ}} ହୋଇଯିବ ।
+à¬\86ପଣ à¬\8fବà­\87 à¬²à¬\97 à¬\87ନ à¬\95ରି à¬¨à­\82à¬\86 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟିଏ ବାଛନ୍ତୁ । ଯହି ଆଉ କେହି ଜଣେ ଏହି ଅନୁରୋଧ କରିଥାନ୍ତି
+à¬\95ିମà­\8dବା à¬\86ପଣ à¬\8fବà­\87 à¬¨à¬¿à¬\9cର à¬®à­\82ଳ à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ଼ à¬®à¬¨à­\87 à¬ªà¬\95ାà¬\87 à¬ªà¬¾à¬°à¬¿à¬¥à¬¾à¬¨à­\8dତି à¬¤à­\87ବà­\87 à¬\8fହି à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟିକୁ ଆଉ ବଦଳାଇବା ଲୋଡ଼ା ନାହିଁ ।
+à¬\86ପଣ à¬¨à¬¿à¬\9c à¬ªà­\81ରà­\81ଣା à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟି ଆଗପରି ବ୍ୟବହାର କରିପାରନ୍ତି ।',
+'passwordreset-emailtext-user' => '{{SITENAME}}ରେ ଥିବା ବ୍ୟବହାରକାରୀ $1 {{SITENAME}} ($4) ସାଇଟରେ ଥିବା ଆପଣଙ୍କ ଖାତାର ସବିଶେଷ ଜାଣିବାକୁ ଅନୁରୋଧ କରିଛନ୍ତି । ଏହି ଇମେଲ ଠିକଣା ସହିତ ତଳଲିଖିତ ବ୍ୟବହାରକାରୀଙ୍କ {{PLURAL:$3|ଖାତା|ଖାତାସମୂହ}} ଯୋଡ଼ା:
 
 $2
 
-{{PLURAL:$3|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à¬¬à¬¾à¬°à­\8dଡ଼à¬\9fି|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ସବୁ}} {{PLURAL:$5|ଦିନକରେ|$5 ଦିନରେ ଅଚଳ}} ହୋଇଯିବ ।
-à¬\86ପଣ à¬\8fବà­\87 à¬²à¬\97 à¬\87ନ à¬\95ରି à¬¨à­\82à¬\86 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟିଏ ବାଛନ୍ତୁ । ଯହି ଆଉ କେହି ଜଣେ ଏହି ଅନୁରୋଧ କରିଥାନ୍ତି
-à¬\95ିମà­\8dବା à¬\86ପଣ à¬\8fବà­\87 à¬¨à¬¿à¬\9cର à¬®à­\82ଳ à¬ªà¬¾à¬¸à¬¬à¬¾à¬°à­\8dଡ଼ à¬®à¬¨à­\87 à¬ªà¬\95ାà¬\87 à¬ªà¬¾à¬°à¬¿à¬¥à¬¾à¬¨à­\8dତି à¬¤à­\87ବà­\87 à¬\8fହି à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟିକୁ ଆଉ ବଦଳାଇବା ଲୋଡ଼ା ନାହିଁ ।
-à¬\86ପଣ à¬¨à¬¿à¬\9c à¬ªà­\81ରà­\81ଣା à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ଟି ଆଗପରି ବ୍ୟବହାର କରିପାରନ୍ତି ।',
+{{PLURAL:$3|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ଼à¬\9fି|à¬\8fହି à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ସବୁ}} {{PLURAL:$5|ଦିନକରେ|$5 ଦିନରେ ଅଚଳ}} ହୋଇଯିବ ।
+à¬\86ପଣ à¬\8fବà­\87 à¬²à¬\97 à¬\87ନ à¬\95ରି à¬¨à­\82à¬\86 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟିଏ ବାଛନ୍ତୁ । ଯହି ଆଉ କେହି ଜଣେ ଏହି ଅନୁରୋଧ କରିଥାନ୍ତି
+à¬\95ିମà­\8dବା à¬\86ପଣ à¬\8fବà­\87 à¬¨à¬¿à¬\9cର à¬®à­\82ଳ à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ଼ à¬®à¬¨à­\87 à¬ªà¬\95ାà¬\87 à¬ªà¬¾à¬°à¬¿à¬¥à¬¾à¬¨à­\8dତି à¬¤à­\87ବà­\87 à¬\8fହି à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟିକୁ ଆଉ ବଦଳାଇବା ଲୋଡ଼ା ନାହିଁ ।
+à¬\86ପଣ à¬¨à¬¿à¬\9c à¬ªà­\81ରà­\81ଣା à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ଟି ଆଗପରି ବ୍ୟବହାର କରିପାରନ୍ତି ।',
 'passwordreset-emailelement' => 'ଇଉଜର ନାମ: $1
-à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼: $2',
+à¬\85ସà­\8dଥାà­\9fà­\80 à¬ªà¬¾à¬¸à­±ାର୍ଡ଼: $2',
 'passwordreset-emailsent' => 'ଏକ ମନେପକାଇବା ଇ-ମେଲ ପଠାଇଦିଆଯାଇଅଛି ।',
 'passwordreset-emailsent-capture' => 'ତଳେ ଦିଆଯାଇଥିବା ଭଳି ମନେପକାଇବା ଇ-ମେଲଟିଏ ପଠାଦିଆଗଲା ।',
-'passwordreset-emailerror-capture' => 'à¬\97à­\8bà¬\9fିà¬\8f à¬¸à¬¬à¬¿à¬¶à­\87ଷ à¬\8fମà­\87ଲà¬\9fିà¬\8f à¬¬à¬¾à¬¹à¬¾à¬°à¬¿à¬\9bି, ଯାହାକି ତଳେ ଅଛି, କିନ୍ତୁ ଏହାକୁ ବ୍ୟବହାରକାରୀକୁ ପଠାଇବାରେ ଅସଫଳ ହେଲା :$1',
+'passwordreset-emailerror-capture' => 'à¬\97à­\8bà¬\9fିà¬\8f à¬®à¬¨à­\87ପà¬\95ାà¬\87ବା à¬\87-ମà­\87ଲ à¬¤à¬¿à¬\86ରି à¬\95ରାଯାà¬\87ଥିଲା, ଯାହାକି ତଳେ ଅଛି, କିନ୍ତୁ ଏହାକୁ ବ୍ୟବହାରକାରୀକୁ ପଠାଇବାରେ ଅସଫଳ ହେଲା :$1',
 
 # Special:ChangeEmail
 'changeemail' => 'ଇ-ମେଲ ଠିକଣା ବଦଳାଇବେ',
 'changeemail-header' => 'ଖାତା ଇ-ମେଲ ଠିକଣା ବଦଳାଇବେ',
-'changeemail-text' => 'à¬\86ପଣା à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣା à¬¬à¬¦à¬³à¬¾à¬\87ବା à¬¨à¬¿à¬®à¬¨à­\8dତà­\87 à¬\8fହି à¬\86ବà­\87ଦନ à¬ªà¬¤à­\8dରà¬\9fି à¬ªà­\82ରଣ à¬\95ରନà­\8dତà­\81 à¥¤ à¬\86ପଣà¬\99à­\8dà¬\95à­\81 à¬\8fହି à¬¬à¬¦à¬³ à¬¥à­\9f à¬\95ରିବା à¬ªà¬¾à¬\87à¬\81 à¬¨à¬¿à¬\9cର à¬ªà¬¾à¬¸à¬¬ାର୍ଡ଼ ଦେବାକୁ ପଡ଼ିବ ।',
+'changeemail-text' => 'à¬\86ପଣା à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣା à¬¬à¬¦à¬³à¬¾à¬\87ବା à¬¨à¬¿à¬®à¬¨à­\8dତà­\87 à¬\8fହି à¬\86ବà­\87ଦନ à¬ªà¬¤à­\8dରà¬\9fି à¬ªà­\82ରଣ à¬\95ରନà­\8dତà­\81 à¥¤ à¬\86ପଣà¬\99à­\8dà¬\95à­\81 à¬\8fହି à¬¬à¬¦à¬³ à¬¥à­\9f à¬\95ରିବା à¬ªà¬¾à¬\87à¬\81 à¬¨à¬¿à¬\9cର à¬ªà¬¾à¬¸à­±ାର୍ଡ଼ ଦେବାକୁ ପଡ଼ିବ ।',
 'changeemail-no-info' => 'ଏହି ପୃଷ୍ଠାଟିକୁ ସିଧା ଖୋଲିବା ନିମନ୍ତେ ଆପଣଙ୍କୁ ଲଗ ଇନ କରିବାକୁ ପଡ଼ିବ ।',
 'changeemail-oldemail' => 'ଏବେକାର ଇ-ମେଲ ଠିକଣା:',
 'changeemail-newemail' => 'ନୂଆ ଇ-ମେଲ ଠିକଣା:',
@@ -848,19 +848,19 @@ $2
 'link_sample' => 'ଲିଙ୍କ ଶିରୋନାମା',
 'link_tip' => 'ଭିତର ଲିଙ୍କ',
 'extlink_sample' => 'http://www.example.com ଲିଙ୍କ ଶିରୋନାମା',
-'extlink_tip' => 'ବାହାର ଲିଙ୍କ (http:// ଆଗରେ ଲଗାଇବାକୁ ମନେରଖିଥିବେ)',
+'extlink_tip' => 'ବାହାର ଲିଙ୍କ (ଆରମ୍ଭରେ http:// ଲେଖିବାକୁ ମନେରଖିଥିବେ)',
 'headline_sample' => 'ଶିରୋନାମା ଲେଖା',
 'headline_tip' => '୨କ ଆକାରର ମୂଳଧାଡ଼ି',
 'nowiki_sample' => 'ଅସଜଡ଼ା ଲେଖା ଏଠାରେ ଭରିବେ',
 'nowiki_tip' => 'ଉଇକି ସଜାଣି ବିନା',
-'image_tip' => 'ଏମବେଡ଼ ହୋଇ ଥିବା ଫାଇଲ',
+'image_tip' => 'à¬\8fମà­\8dବà­\87ଡ଼ à¬¹à­\8bà¬\87 à¬¥à¬¿à¬¬à¬¾ à¬«à¬¾à¬\87ଲ',
 'media_tip' => 'ଫାଇଲର ଲିଙ୍କ',
-'sig_tip' => 'ଲà­\87à¬\96ାର à¬¸à¬®à­\9f à¬¸à¬¹ à¬\86ପଣà¬\99à­\8dà¬\95 à¬¸à¬¨à­\8dତà¬\95',
+'sig_tip' => 'ସମୟ ସହ ଆପଣଙ୍କ ସନ୍ତକ',
 'hr_tip' => 'ସମାନ୍ତରାଳ ରେଖା (ବେଳେବେଳେ ବ୍ୟବହାର କରିବେ)',
 
 # Edit pages
 'summary' => 'ସାରକଥା:',
-'subject' => 'ବିଷà­\9f/ମà­\82ଳ à¬²à­\87à¬\96ା',
+'subject' => 'ବିଷà­\9f/ଶିରà­\8bନାମା',
 'minoredit' => 'ଏହା ଖୁବ ଛୋଟ ବଦଳଟିଏ',
 'watchthis' => 'ଏହି ପୃଷ୍ଠାଟିକୁ ଦେଖିବେ',
 'savearticle' => 'ସାଇତିବେ',
@@ -869,8 +869,8 @@ $2
 'showlivepreview' => 'ଜୀବନ୍ତ ଦେଖଣା',
 'showdiff' => 'ବଦଳଗୁଡ଼ିକ ଦେଖାଇବେ',
 'anoneditwarning' => "'''ଜାଣିରଖନ୍ତୁ:''' ଆପଣ ଲଗଇନ କରିନାହାନ୍ତି ।
-à¬\8fହି à¬«à¬°à¬¦à¬° '''à¬\87ତିହାସ''' à¬ªà­\83ଷà­\8dଠାରେ ଆପଣଙ୍କ ଆଇପି ଠିକଣାଟି ସାଇତା ହୋଇଯିବ ।",
-'anonpreviewwarning' => "''à¬\86ପଣ à¬²à¬\97 à¬\87ନ à¬\95ରି à¬¨à¬¾à¬¹à¬¾à¬¨à­\8dତି à¥¤ à¬\86ପଣ à¬¯à­\87à¬\89à¬\81 à¬¬à¬¦à¬³à¬¸à¬¬à­\81 à¬\95ରିବେ ଆପଣଙ୍କର IP ଠିକଣା ଏହି ପୃଷ୍ଠାର ଇତିହାସରେ ସାଇତା ହୋଇଯିବ ।''",
+à¬\8fହି à¬ªà­\83ଷà­\8dଠାର à¬\87ତିହାସରେ ଆପଣଙ୍କ ଆଇପି ଠିକଣାଟି ସାଇତା ହୋଇଯିବ ।",
+'anonpreviewwarning' => "''à¬\86ପଣ à¬²à¬\97 à¬\87ନ à¬\95ରି à¬¨à¬¾à¬¹à¬¾à¬¨à­\8dତି à¥¤ à¬¬à¬¦à¬³à¬\95ରି à¬¸à¬¾à¬\87ତିଲେ ଆପଣଙ୍କର IP ଠିକଣା ଏହି ପୃଷ୍ଠାର ଇତିହାସରେ ସାଇତା ହୋଇଯିବ ।''",
 'missingsummary' => "'''ଚେତାବନୀ:''' ଆପଣ ଏକ ସମ୍ପାଦନା ସାରକଥା ଦେଇନାହାନ୍ତି ।
 ଯଦି ଆପଣ \"{{int:savearticle}}\"ରେ ଆଉଥରେ କ୍ଲିକ କରନ୍ତି, ତେବେ ଆପଣଙ୍କ ବଦଳ ସାରକଥା ବିନା ସାଇତା ହୋଇଯିବ ।",
 'missingcommenttext' => 'ଦୟାକରି ତଳେ ଏକ ମତାମତ ଦିଅନ୍ତୁ ।',
@@ -1009,8 +1009,8 @@ $1 ଦ୍ଵାରା ପ୍ରତିରୋଧ କରାଯାଇଛି
 '''ଅନୁମତି ବିନା ସତ୍ଵାଧିକାର ଥିବା କାମ ଏଠାରେ ଦିଅନ୍ତୁ ନାହିଁ !'''",
 'longpageerror' => "'''ଭୁଲ: ଆପଣ ଦେଇଥିବା ଲେଖାଟି {{PLURAL:$1|କିଲୋବାଇଟ|$1 କିଲୋବାଇଟ}} ଲମ୍ବା, ଯାହାକି ସବୁଠାରୁ ଅଧିକ {{PLURAL:$2|କିଲୋବାଇଟ|$2 କିଲୋବାଇଟ}} ଠାରୁ ବି ଅଧିକ ।'''
 ଏହା ସାଇତାଯାଇପାରିବ ନାହିଁ ।",
-'readonlywarning' => "'''ସୂଚନା: ଏହି ଡାଟାବେସଟି ରକ୍ଷଣାବେକ୍ଷଣା ପାଇଁ କିଳାଯାଇଛି । ତେଣୁ ଆପଣ ଆପଣା ସମ୍ପାଦନା ଏବେ ସାଇତି ପାରିବେ ନାହିଁ ।'''
-à¬\86ପଣ à¬²à­\87à¬\96ାସବà­\81 à¬\8fà¬\95 à¬\9fà­\87à¬\95à­\8dସà¬\9f à¬«à¬¾à¬\87ଲରà­\87 à¬¨à¬\95ଲ à¬\95ରି ପେଷ୍ଟ କରି ଆଗକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ସାଇତି ପାରିବେ ।
+'readonlywarning' => "ସୂଚନା: ଏହି ଡାଟାବେସଟି ରକ୍ଷଣାବେକ୍ଷଣା ପାଇଁ କିଳାଯାଇଛି । ତେଣୁ ଆପଣ ଆପଣା ସମ୍ପାଦନା ଏବେ ସାଇତି ପାରିବେ ନାହିଁ ।'''
+à¬\86ପଣ à¬²à­\87à¬\96ାସବà­\81 à¬\8fà¬\95 à¬\9fà­\87à¬\95à­\8dସà¬\9f à¬«à¬¾à¬\87ଲରà­\87 à¬¨à¬\95ଲ à¬\8fବà¬\82 ପେଷ୍ଟ କରି ଆଗକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ସାଇତି ପାରିବେ ।
 
 ଏହାକୁ କିଳିଥିବା ପରିଛା ଏହି କଇଫତ ଦେଇଛନ୍ତି: $1",
 'protectedpagewarning' => "'''ଚେତାବନୀ: ଏହି ପୃଷ୍ଠାଟିକୁ କିଳାଯାଇଅଛି ଯାହା ଫଳରେ କେବଳ ପରିଛାମାନେ ହିଁ ଏହାକୁ ବଦଳାଇ ପାରିବେ ।'''
@@ -1317,7 +1317,7 @@ $1",
 'search-interwiki-default' => '$1 ଫଳାଫଳ:',
 'search-interwiki-more' => '(ଅଧିକ)',
 'search-relatedarticle' => 'ଯୋଡ଼ା',
-'mwsuggest-disable' => 'AJAX ମତାମତକୁ ଅଚଳ କରାଇବେ',
+'mwsuggest-disable' => 'ଖୋଜା ମତାମତକୁ ଅଚଳ କରାଇବେ',
 'searcheverything-enable' => 'ସବୁଗୁଡ଼ିକ ନେମସ୍ପେସରେ ଖୋଜିବେ',
 'searchrelated' => 'ଯୋଡ଼ା',
 'searchall' => 'ସବୁ',
@@ -2229,7 +2229,7 @@ URLଟି ଠିକ ଅଚିକି କି ନାଁ ଓ ସାଇଟଟି ସ
 # Special:ActiveUsers
 'activeusers' => 'ସଚଳ ସଭ୍ୟଙ୍କ ତାଲିକା',
 'activeusers-intro' => 'ବିଗତ $1 {{PLURAL:$1|ଦିନ|ଦିନ}} ଭିତରେ କିଛି ପ୍ରକାରର କାମ କରିଥିବା ସଭ୍ୟମାନଙ୍କର ତାଲିକା ।',
-'activeusers-count' => 'ବିଗତ {{PLURAL:$3|ଦିନ|$3 ଦିନରେ}}ରେ $1ଟି {{PLURAL:$1|ସମ୍ପାଦନା|ସମ୍ପାଦନା}}',
+'activeusers-count' => 'ବିଗତ {{PLURAL:$3|ଦିନ|$3 ଦିନରେ}}ରେ $1ଟି {{PLURAL:$1|ସମ୍ପାଦନା|ସମ୍ପାଦନାଗୁଡିକ}}',
 'activeusers-from' => 'ଏହି ନାମରେ ଆରମ୍ଭ ହେଉଥିବା ସଭ୍ୟମାନଙ୍କୁ ଦେଖାଇବେ:',
 'activeusers-hidebots' => 'ଆପେଆପେ ଚାଳିତ ସଭ୍ୟମାନଙ୍କୁ ଲୁଚାନ୍ତୁ',
 'activeusers-hidesysops' => 'ପରିଚାଳକମାନଙ୍କୁ ଲୁଚାଇବେ',
@@ -2292,7 +2292,7 @@ URLଟି ଠିକ ଅଚିକି କି ନାଁ ଓ ସାଇଟଟି ସ
 'usermessage-editor' => 'ସିଷ୍ଟମ ଦୂତ',
 
 # Watchlist
-'watchlist' => 'ଦେଖାତାଲିକା',
+'watchlist' => 'ଦà­\87à¬\96ଣାତାଲିà¬\95ା',
 'mywatchlist' => 'ଦେଖଣାତାଲିକା',
 'watchlistfor2' => '$1 $2 ପାଇଁ',
 'nowatchlist' => 'ଆପଣଙ୍କ ଦେଖଣା ତାଲିକାରେ କିଛି ବି ଜିନିଷ ନାହିଁ ।',
@@ -2457,9 +2457,9 @@ $2ଙ୍କ ଦେଇ ଶେଷଥର ହୋଇଥିବା ସଂସ୍କର
 'protect-cascadeon' => 'ଏହି ପୃଷ୍ଠାଟି ଏବେ ପାଇଁ କିଳାଯାଇଛି {{PLURAL:$1|ପୃଷ୍ଠା, ଯେଉଁଥିରେ|ପୃଷ୍ଠମାନ, ଯେଉଁସବୁରେ}} କାସକେଡ଼କରା ସୁରକ୍ଷା ସଚଳ ଥିଲା ।
 ଆପଣ ପୃଷ୍ଠାଟିର ପ୍ରତିରକ୍ଷା ସ୍ତର ବଦଳାଇ ପାରିବେ, କିନ୍ତୁ ଏହା କାସକେଡ଼ ପ୍ରତିରକ୍ଷାକୁ ପ୍ରଭାବିତ କରିନଥାଏ ।',
 'protect-default' => 'ସବୁ ଇଉଜରଙ୍କୁ ଅନୁମତି ଦିଅନ୍ତୁ',
-'protect-fallback' => '"$1" ବାଲା ଅନୁମତି ଦରକାର',
-'protect-level-autoconfirmed' => 'ନà­\81à¬\86 à¬\93 à¬¨à¬¾à¬\86à¬\81 à¬²à­\87à¬\96ାà¬\87 à¬¨ à¬¥à¬¿à¬¬à¬¾ à¬\87à¬\89à¬\9cରମାନà¬\95à­\81 à¬\85à¬\9fà¬\95ାà¬\81ତà­\81',
-'protect-level-sysop' => 'à¬\95à­\87ବଳ à¬ªà¬°à¬¿à¬\9bାମାନà¬\81à¬\95 à¬ªà¬¾à¬\87à¬\81',
+'protect-fallback' => 'କେବଳ "$1" ଅନୁମତି ଥିବା ବ୍ୟବହାରକାରୀ ମାନଙ୍କୁ ଛାଡିବେ',
+'protect-level-autoconfirmed' => 'à¬\95à­\87ବଳ à¬\86ପà­\87 à¬\86ପà­\87 à¬¸à¬¹à¬®à¬¤ à¬¹à­\8bà¬\87ଥିବା à¬¬à­\8dà­\9fବହାରà¬\95ାରà­\80 à¬®à¬¾à¬¨à¬\99à­\8dà¬\95à­\81 à¬\9bାଡିବà­\87',
+'protect-level-sysop' => 'à¬\95à­\87ବଳ à¬ªà¬°à¬¿à¬\9bାମାନà¬\99à­\8dà¬\95à­\81 à¬\9bାଡିବà­\87',
 'protect-summary-cascade' => 'କାସକେଡ଼ ହୋଇଥିବା',
 'protect-expiring' => '$1 (ଇଉଟିସି)ରେ ଅଚଳ ହୋଇଯିବ',
 'protect-expiring-local' => '$1ରେ ଅଚଳ ହୋଇଯିବ',
@@ -2768,7 +2768,7 @@ $1ର ଅଟକ ପାଇଁ ଦିଆଯାଇଥିବା କାରଣଟି 
 
 ଲିଙ୍କସବୁ କେଉଁଠିକୁ ଯାଉଛି ତାହା ପାଇଁ ଆପଣ ଦାୟୀ ନୁହନ୍ତି ।
 
-ମନà­\87 à¬°à¬\96ନà­\8dତà­\81, à¬\86à¬\97ରà­\81 à¬\8fହି à¬\8fà¬\95ା à¬¨à¬¾à¬\86à¬\81ରà­\87 à¬ªà­\83ଷà­\8dଠାà¬\9fିà¬\8f à¬¥à¬¿à¬²à­\87 à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fି '''à¬\98à­\81à¬\9eà­\8dà¬\9aିବ à¬¨à¬¾à¬¹à¬¿à¬\81''' à¬¯à­\87ତà­\87 à¬¯à¬¾à¬\8fà¬\81 à¬¤à¬¾à¬¹à¬¾ à¬\96ାଲି à¬¨à¬¾à¬¹à¬¿à¬\81 à¬¬à¬¾ à¬\86à¬\97 à¬ªà­\83ଷà­\8dଠାà¬\9fିର à¬\95à­\8cଣସି à¬¬à¬¦à¬³ à¬\87ତିହାସ à¬¨à¬¾à¬¹à¬¿à¬\81 à¬¸à­\87ତà­\87 à¬¬à­\87ଳ à¬¯à¬¾à¬\8fà¬\81 à¬\8fହା à¬\8fମିତି à¬°à¬¹à¬¿à¬¬ à¥¤ à¬\8fହାର à¬®à¬¾à¬¨à­\87 à¬¹à­\87à¬\89à¬\9bି, à¬\86ପଣ à¬\97à­\8bà¬\9fିà¬\8f à¬ªà­\83ଷà­\8dଠାର à¬¨à¬¾à¬\86à¬\81à¬\95à­\81 à¬¤à¬¾à¬° à¬ªà­\81ରà­\81ଣା à¬¨à¬¾à¬\86à¬\81 à¬¦à­\87à¬\87ପାରିବà­\87, à¬\95ିନà­\8dତà­\81 à¬\86à¬\97ରà­\81 à¬¥à¬¿à¬¬à¬¾ à¬ªà­\83ଷà­\8dଠାà¬\9fି à¬\89ପରà­\87 à¬¨à­\82à¬\86 à¬ªà­\83ଷà­\8dଠାà¬\9fିà¬\8f à¬\9aାପି à¬¦à­\87à¬\87ପାରିବà­\87 à¬¨à¬¾à¬¹à¬¿à¬\81 à¥¤
+ମନେ ରଖନ୍ତୁ, ଆଗରୁ ଏହି ଏକା ନାଆଁରେ ପୃଷ୍ଠାଟିଏ ଥିଲେ ଏହି ପୃଷ୍ଠାଟି '''ଘୁଞ୍ଚିବ ନାହିଁ''' ଯେତେ ଯାଏଁ ଆଗ ପୃଷ୍ଠାଟିର କୌଣସି ବଦଳ ଇତିହାସ ନାହିଁ ସେତେ ବେଳ ଯାଏଁ ଏହା ଏମିତି ରହିବ । ଏହାର ମାନେ ହେଉଛି, ଆପଣ ଗୋଟିଏ ପୃଷ୍ଠାର ନାଆଁକୁ ତାର ପୁରୁଣା ନାଆଁ ଦେଇପାରିବେ, କିନ୍ତୁ ଆଗରୁ ଥିବା ପୃଷ୍ଠାଟି ଉପରେ ନୂଆ ପୃଷ୍ଠାଟିଏ ଚାପି ଦେଇପାରିବେ ନାହିଁ ।
 
 '''ଜାଣି ରଖନ୍ତୁ!'''
 ଏହା ଏକ ଜଣାଶୁଣା ପୃଷ୍ଠାରେ ଆମୂଳଚୂଳ ଓ ଅଜଣା ବଦଳ କରିପାରେ;
@@ -3090,6 +3090,7 @@ MediaWiki ବ୍ୟବହାର କରି [[Special:Import|ପୃଷ୍ଠା 
 'pageinfo-robot-noindex' => 'ସୂଚୀପତ୍ର କରିହେଉନଥିବା',
 'pageinfo-views' => 'ଦେଖଣା ସଂଖ୍ୟା',
 'pageinfo-watchers' => 'ପୃଷ୍ଠା ଦେଖଣାହାରି ସଂଖ୍ୟା',
+'pageinfo-few-watchers' => '$1ରୁ କମ {{PLURAL:$1|ଦେଖଣାକାରୀ|ଦେଖଣାକାରୀଗଣ}}',
 'pageinfo-redirects-name' => 'ଏହି ପୃଷ୍ଠାକୁ ଲେଉଟାଣି ଅଛି',
 'pageinfo-subpages-name' => 'ଏହି ପୃଷ୍ଠାରେ ଥିବା ଉପପୃଷ୍ଠା',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirect|redirects}}; $3 {{PLURAL:$3|non-redirect|non-redirects}})',
@@ -3849,7 +3850,7 @@ MediaWiki ଉପଯୋଗୀ ହେବା ଲକ୍ଷରେ ବଣ୍ଟାଯ
 'specialpages-group-highuse' => 'ଅଧିକ ବ୍ୟବହାର ହେଉଥିବା ପୃଷ୍ଠା',
 'specialpages-group-pages' => 'ପୃଷ୍ଠାମାନଙ୍କର ତାଲିକା',
 'specialpages-group-pagetools' => 'ପୃଷ୍ଠା ଉପକରଣ',
-'specialpages-group-wiki' => 'à¬\89à¬\87à¬\95ି à¬¡à¬¾à¬\9fା ଓ ଉପକରଣ',
+'specialpages-group-wiki' => 'ତଥà­\8dà­\9f ଓ ଉପକରଣ',
 'specialpages-group-redirects' => 'ବିଶେଷ ପୃଷ୍ଠାକୁ ପୁନପ୍ରେରଣ କରିବା',
 'specialpages-group-spam' => 'ଅଯଥା ଉପକରଣ',
 
@@ -3947,8 +3948,8 @@ MediaWiki ଉପଯୋଗୀ ହେବା ଲକ୍ଷରେ ବଣ୍ଟାଯ
 'logentry-newusers-newusers' => 'ସଭ୍ୟ ଖାତା $1 ତିଆରି କରାଗଲା',
 'logentry-newusers-create' => 'ସଭ୍ୟ ଖାତା $1 ତିଆରି କରାଗଲା',
 'logentry-newusers-create2' => 'ସଭ୍ୟ ଖାତା $3ଟି $1 ଦ୍ଵାରା ତିଆରି କରାଗଲା',
+'logentry-newusers-byemail' => '$1ଙ୍କ ଦ୍ଵାରା $3 ବ୍ୟବହାରକାରୀ ଖାତାଟି ଖୋଳାଗଲା ଏବଂ ପାସୱାର୍ଡଟି ଇ-ମେଲ ଦ୍ଵାରା ପଠାଗଲା',
 'logentry-newusers-autocreate' => '$1 ଖାତାଟି ଆପେଆପେ ତିଆରିହେଲା',
-'newuserlog-byemail' => 'ଇ-ମେଲରେ ପାସୱାର୍ଡ଼ ପଠାଇଦିଆଗଲା',
 'logentry-rights-rights' => '$1, $3 ପାଇଁ $4ରୁ $5କୁ ସଭ୍ୟପଦ ବଦଳାଇଲେ',
 'logentry-rights-rights-legacy' => '$1, $3 ପାଇଁ ଗୋଷ୍ଠୀ ସଭ୍ୟପଦ ବଦଳାଇଛି',
 'logentry-rights-autopromote' => '$1 ଆପେ ଆପେ $4ରୁ $5କୁ ଗଲେ',
@@ -4007,6 +4008,7 @@ MediaWiki ଉପଯୋଗୀ ହେବା ଲକ୍ଷରେ ବଣ୍ଟାଯ
 'api-error-ok-but-empty' => 'ଭିତର ଅସୁବିଧା: ସର୍ଭର ଠାରୁ କିଛି ଖବର ନାହିଁ ।',
 'api-error-overwrite' => 'ଆଗରୁଥିବା ଏକ ଫାଇଲ ଉପରେ ମଡ଼ାଇବା ଅନୁମୋଦିତ ନୁହେଁ ।',
 'api-error-stashfailed' => 'ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ସାଇତି ପାରିଲା ନାହିଁ ।',
+'api-error-publishfailed' => 'ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ପ୍ରକାଶ କରିପାରିଲା ନାହିଁ ।',
 'api-error-timeout' => 'ସର୍ଭର ଏକ ସୀମିତ କାଳ ଭିତରେ ଉତ୍ତର ଦେଲାନାହିଁ ।',
 'api-error-unclassified' => 'ଏକ ଅଜଣା ଅସୁବିଧା ଘଟିଲା ।',
 'api-error-unknown-code' => 'ଅଜଣା ତୃଟି: "$1"',
index e89ba24..984a3d7 100644 (file)
@@ -55,6 +55,8 @@ $specialPageAliases = array(
        'Activeusers'               => array( 'АктивонАрхайджытæ' ),
        'Allmessages'               => array( 'ФыстæджытæИууылдæр' ),
        'Allpages'                  => array( 'ФæрстæИууылдæр' ),
+       'Ancientpages'              => array( 'ЗæрондФæрстæ' ),
+       'Badtitle'                  => array( 'Æвзæрном' ),
        'Blankpage'                 => array( 'АфтидФарс' ),
        'Block'                     => array( 'Блок' ),
        'Blockme'                   => array( 'НыблокМæКæн' ),
@@ -67,25 +69,117 @@ $specialPageAliases = array(
        'Confirmemail'              => array( 'EmailБæлвырдКæнын' ),
        'Contributions'             => array( 'Бавæрд' ),
        'CreateAccount'             => array( 'АккаунтСкæнын' ),
+       'Deadendpages'              => array( 'ХæдбарФæрстæ' ),
        'DeletedContributions'      => array( 'ХафтБавæрд' ),
+       'Disambiguations'           => array( 'Бирæнысаниуæгджынтæ' ),
+       'DoubleRedirects'           => array( 'ДывæрÆрвыстытæ' ),
+       'EditWatchlist'             => array( 'ЦæстдардИвын' ),
+       'Emailuser'                 => array( 'АрхайæгмæEmail' ),
+       'Export'                    => array( 'Экспорт' ),
+       'Fewestrevisions'           => array( 'ЦъусдæрФæлтæртæ' ),
+       'FileDuplicateSearch'       => array( 'ФайлыДубликатАгурын' ),
+       'Filepath'                  => array( 'ФайлмæФæт' ),
+       'Import'                    => array( 'Импорт' ),
+       'Invalidateemail'           => array( 'EmailРабæлвырдКæнын' ),
+       'JavaScriptTest'            => array( 'JavaScriptТест' ),
+       'BlockList'                 => array( 'Блокты_Номхыгъд' ),
+       'LinkSearch'                => array( 'ÆрвитæнАгурын' ),
+       'Listadmins'                => array( 'РадгæстыНомхыгъд' ),
+       'Listbots'                  => array( 'БоттыНомхыгъд' ),
+       'Listfiles'                 => array( 'НывтыНомхыгъд' ),
+       'Listgrouprights'           => array( 'АрхайджытыБартыНомхыгъд' ),
+       'Listredirects'             => array( 'ÆрвыстытыНомхыгъд' ),
+       'Listusers'                 => array( 'АрхайджытыНомхыгъд' ),
+       'Lockdb'                    => array( 'РДСæхгæнын' ),
+       'Log'                       => array( 'Логтæ' ),
+       'Lonelypages'               => array( 'ИунæгФæрстæ' ),
+       'Longpages'                 => array( 'ДаргъФæрстæ' ),
+       'MergeHistory'              => array( 'ИсторитæБаиуКæнын' ),
+       'MIMEsearch'                => array( 'MIMEАгурын' ),
+       'Mostcategories'            => array( 'ФылдæрКатегоритæ' ),
+       'Mostimages'                => array( 'ÆппæтыАрхайдФайлтæ' ),
+       'Mostinterwikis'            => array( 'ФылдæрИнтервикитæ' ),
+       'Mostlinked'                => array( 'ФылдæрБастФæрстæ' ),
+       'Mostlinkedcategories'      => array( 'ФылдæрБастКатегоритæ' ),
+       'Mostlinkedtemplates'       => array( 'ФылдæрБастХуызæгтæ' ),
+       'Mostrevisions'             => array( 'ФылдæрФæлтæртæ' ),
+       'Movepage'                  => array( 'ФарсХæссын' ),
        'Mycontributions'           => array( 'МæБавæрд' ),
        'Mypage'                    => array( 'МæФарс' ),
        'Mytalk'                    => array( 'МæНыхас' ),
        'Myuploads'                 => array( 'МæБавгæд' ),
        'Newimages'                 => array( 'НогФайлтæ' ),
        'Newpages'                  => array( 'НогФæрстæ' ),
-       'Preferences'               => array( 'Фадæттæ' ),
+       'PasswordReset'             => array( 'ПарольНогКæнын' ),
+       'PermanentLink'             => array( 'УдгасÆрвитæн' ),
+       'Popularpages'              => array( 'АрæхФæрстæ' ),
+       'Preferences'               => array( 'Уагæвæрдтæ' ),
+       'Prefixindex'               => array( 'РазæфтуантыИндекс' ),
+       'Protectedpages'            => array( 'ÆхгæдФæрстæ' ),
+       'Protectedtitles'           => array( 'ÆхгæдНæмттæ' ),
        'Randompage'                => array( 'ÆрхаугæФарс' ),
+       'Randomredirect'            => array( 'ÆрхаугæРарвыст' ),
        'Recentchanges'             => array( 'ФæстагИвдтытæ' ),
+       'Recentchangeslinked'       => array( 'БастИвдтытæ' ),
+       'Revisiondelete'            => array( 'ИвдХафын' ),
        'Search'                    => array( 'Агурын' ),
+       'Shortpages'                => array( 'ЦыбырФæрстæ' ),
+       'Specialpages'              => array( 'СæрмагондФæрстæ' ),
+       'Statistics'                => array( 'Статистикæ' ),
+       'Tags'                      => array( 'Тегтæ' ),
+       'Unblock'                   => array( 'РаблокКæнын' ),
+       'Uncategorizedcategories'   => array( 'ÆнæКатегориКатегоритæ' ),
+       'Uncategorizedimages'       => array( 'ÆнæКатегориФайлтæ' ),
+       'Uncategorizedpages'        => array( 'ÆнæКатегориФæрстæ' ),
+       'Uncategorizedtemplates'    => array( 'ÆнæКатегориХуызæгтæ' ),
+       'Undelete'                  => array( 'Рацаразын' ),
+       'Unlockdb'                  => array( 'РДРаблокКæнын' ),
+       'Unusedcategories'          => array( 'ÆнæАрхайдКатегоритæ' ),
+       'Unusedimages'              => array( 'ÆнæАрхайдФайлтæ' ),
+       'Unusedtemplates'           => array( 'ÆнæАрхайдХуызæгтæ' ),
+       'Unwatchedpages'            => array( 'ÆнæЦæстдардФæрстæ' ),
+       'Upload'                    => array( 'Æвгæнын' ),
+       'Userlogin'                 => array( 'Бахизын' ),
+       'Userlogout'                => array( 'Рахизын' ),
+       'Userrights'                => array( 'АрхайæджыБартæ' ),
+       'Version'                   => array( 'Фæлтæр' ),
+       'Wantedcategories'          => array( 'ХъæугæКатегоритæ' ),
+       'Wantedfiles'               => array( 'ХъæугæФайлтæ' ),
+       'Wantedpages'               => array( 'ХъæугæФæрстæ' ),
+       'Wantedtemplates'           => array( 'ХъæугæХуызæгтæ' ),
        'Watchlist'                 => array( 'Цæстдард' ),
+       'Whatlinkshere'             => array( 'АрдæмЦыÆрвиты' ),
+       'Withoutinterwiki'          => array( 'ÆнæИнтервики' ),
 );
 
 
 $magicWords = array(
-       'redirect'                  => array( '0', '#РАРВЫСТ', '#перенаправление', '#перенапр', '#REDIRECT' ),
+       'redirect'                  => array( '0', '#ÆРВИТÆН', '#ÆРВЫСТ', '#РАРВЫСТ', '#перенаправление', '#перенапр', '#REDIRECT' ),
+       'notoc'                     => array( '0', '__ÆНÆСÆР__', '__БЕЗ_ОГЛАВЛЕНИЯ__', '__БЕЗ_ОГЛ__', '__NOTOC__' ),
+       'nogallery'                 => array( '0', '__ÆНÆГАЛЕРЕЙ__', '__БЕЗ_ГАЛЕРЕИ__', '__NOGALLERY__' ),
+       'forcetoc'                  => array( '0', '__СÆРТИМÆ__', '__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__', '__ОБЯЗ_ОГЛ__', '__FORCETOC__' ),
+       'toc'                       => array( '0', '__СÆРТÆ__', '__ОГЛАВЛЕНИЕ__', '__ОГЛ__', '__TOC__' ),
+       'noeditsection'             => array( '0', '__ÆНÆХАЙИВЫНÆЙ__', '__БЕЗ_РЕДАКТИРОВАНИЯ_РАЗДЕЛА__', '__NOEDITSECTION__' ),
+       'currentmonth'              => array( '1', 'АЦЫМÆЙ', 'АЦЫМÆЙ2', 'ТЕКУЩИЙ_МЕСЯЦ', 'ТЕКУЩИЙ_МЕСЯЦ_2', 'CURRENTMONTH', 'CURRENTMONTH2' ),
+       'currentmonth1'             => array( '1', 'АЦЫМÆЙ1', 'ТЕКУЩИЙ_МЕСЯЦ_1', 'CURRENTMONTH1' ),
+       'currentmonthname'          => array( '1', 'АЦЫМÆЙЫНОМ', 'НАЗВАНИЕ_ТЕКУЩЕГО_МЕСЯЦА', 'CURRENTMONTHNAME' ),
+       'currentmonthnamegen'       => array( '1', 'АЦЫМÆЙЫНОМГУЫР', 'НАЗВАНИЕ_ТЕКУЩЕГО_МЕСЯЦА_РОД', 'CURRENTMONTHNAMEGEN' ),
+       'currentmonthabbrev'        => array( '1', 'АЦЫМÆЙЫНОМЦЫБ', 'НАЗВАНИЕ_ТЕКУЩЕГО_МЕСЯЦА_АБР', 'CURRENTMONTHABBREV' ),
+       'currentday'                => array( '1', 'АБОН', 'ТЕКУЩИЙ_ДЕНЬ', 'CURRENTDAY' ),
+       'currentday2'               => array( '1', 'АБОН2', 'ТЕКУЩИЙ_ДЕНЬ_2', 'CURRENTDAY2' ),
+       'currentdayname'            => array( '1', 'АБОНЫБОНЫНОМ', 'НАЗВАНИЕ_ТЕКУЩЕГО_ДНЯ', 'CURRENTDAYNAME' ),
+       'currentyear'               => array( '1', 'АЦЫАЗ', 'ТЕКУЩИЙ_ГОД', 'CURRENTYEAR' ),
+       'currenttime'               => array( '1', 'НЫРЫРÆСТÆГ', 'ТЕКУЩЕЕ_ВРЕМЯ', 'CURRENTTIME' ),
+       'currenthour'               => array( '1', 'НЫРЫСАХАТ', 'ТЕКУЩИЙ_ЧАС', 'CURRENTHOUR' ),
+       'numberofpages'             => array( '1', 'ФÆРСТЫНЫМÆЦ', 'КОЛИЧЕСТВО_СТРАНИЦ', 'NUMBEROFPAGES' ),
+       'numberofarticles'          => array( '1', 'УАЦТЫНЫМÆЦ', 'КОЛИЧЕСТВО_СТАТЕЙ', 'NUMBEROFARTICLES' ),
+       'pagename'                  => array( '1', 'ФАРСЫНОМ', 'НАЗВАНИЕ_СТРАНИЦЫ', 'PAGENAME' ),
+       'img_thumbnail'             => array( '1', 'къаддæргонд', 'къаддæр', 'мини', 'миниатюра', 'thumbnail', 'thumb' ),
+       'img_manualthumb'           => array( '1', 'къаддæргонд=$1', 'къаддæр=$1', 'мини=$1', 'миниатюра=$1', 'thumbnail=$1', 'thumb=$1' ),
        'img_right'                 => array( '1', 'рахиз', 'справа', 'right' ),
        'img_left'                  => array( '1', 'галиу', 'слева', 'left' ),
+       'img_none'                  => array( '1', 'æнæ', 'без', 'none' ),
+       'img_center'                => array( '1', 'астæу', 'центр', 'center', 'centre' ),
 );
 
 $linkTrail = '/^((?:[a-z]|а|æ|б|в|г|д|е|ё|ж|з|и|й|к|л|м|н|о|п|р|с|т|у|ф|х|ц|ч|ш|щ|ъ|ы|ь|э|ю|я|“|»)+)(.*)$/sDu';
@@ -225,6 +319,7 @@ $messages = array(
 'newwindow' => '(кæны ног рудзынджы)',
 'cancel' => 'Ныууадзын',
 'moredotdotdot' => 'Фылдæр…',
+'morenotlisted' => 'Фылдæр æнææвдыст...',
 'mypage' => 'Фарс',
 'mytalk' => 'Ныхас',
 'anontalk' => 'Ацы IP-адрисы тæрхон',
index ff05c7b..06a3205 100644 (file)
@@ -16,6 +16,7 @@
  * @author Guglani
  * @author Kaganer
  * @author Raj Singh
+ * @author Saurabh123
  * @author Sukh
  * @author Surinder.wadhawan
  * @author TariButtar
@@ -61,32 +62,62 @@ $namespaceAliases = array(
 
 $specialPageAliases = array(
        'Activeusers'               => array( 'ਸਰਗਰਮ_ਮੈਂਬਰ' ),
+       'Allmessages'               => array( 'ਸਾਰੇ_ਸਨੇਹੇ' ),
+       'Allpages'                  => array( 'ਸਾਰੇ_ਪੰਨੇ' ),
+       'Ancientpages'              => array( 'ਪੁਰਾਣੇ_ਪੰਨੇ' ),
        'Badtitle'                  => array( 'ਖਰਾਬ_ਸਿਰਲੇਖ' ),
        'Blankpage'                 => array( 'ਖਾਲੀ_ਪੰਨਾ' ),
        'Block'                     => array( 'ਪਾਬੰਦੀ_ਲਾਓ', 'IP_’ਤੇ_ਪਾਬੰਦੀ_ਲਾਓ', 'ਮੈਂਬਰ_’ਤੇ_ਪਾਬੰਦੀ_ਲਾਓ' ),
+       'Blockme'                   => array( 'ਮੇਰੇ_’ਤੇ_ਪਾਬੰਦੀ_ਲਾਓ' ),
+       'Booksources'               => array( 'ਕਿਤਾਬ_ਸਰੋਤ' ),
+       'BrokenRedirects'           => array( 'ਟੁੱਟੇ_ਰੀਡਿਰੈਕਟ' ),
        'Categories'                => array( 'ਸ਼੍ਰੇਣੀਆਂ' ),
        'ChangeEmail'               => array( 'ਈ-ਮੇਲ_ਬਦਲੋ' ),
        'ChangePassword'            => array( 'ਪਾਸਵਰਡ_ਬਦਲੋ', 'ਪਾਸਵਰਡ_ਰੀਸੈੱਟ_ਕਰੋ' ),
+       'ComparePages'              => array( 'ਪੰਨਿਆਂ_ਦੀ_ਤੁਲਨਾ_ਕਰੋ' ),
+       'Confirmemail'              => array( 'ਈ-ਮੇਲ_ਤਸਦੀਕ_ਕਰੋ' ),
        'Contributions'             => array( 'ਯੋਗਦਾਨ' ),
        'CreateAccount'             => array( 'ਖਾਤਾ_ਬਣਾਓ' ),
+       'Deadendpages'              => array( 'ਬੰਦ_ਪੰਨੇ' ),
        'DeletedContributions'      => array( 'ਮਿਟਾਏ_ਯੋਗਦਾਨ' ),
+       'Disambiguations'           => array( 'ਗੁੰਝਲਖੋਲ੍ਹ' ),
        'DoubleRedirects'           => array( 'ਦੂਹਰੇ_ਰੀਡਿਰੈਕਟ' ),
        'EditWatchlist'             => array( 'ਨਿਗਰਾਨੀ-ਲਿਸਟ_ਸੋਧੋ' ),
-       'Emailuser'                 => array( 'ਵਰਤੋਂਕਾਰ_ਨੂੰ_ਈ-ਮੇਲ' ),
+       'Emailuser'                 => array( 'ਮੈਂਬਰ_ਨੂੰ_ਈ-ਮੇਲ_ਕਰੋ' ),
+       'Export'                    => array( 'ਨਿਰਯਾਤ' ),
+       'Fewestrevisions'           => array( 'ਸਭ_ਤੋਂ_ਘੱਟ_ਰੀਵਿਜ਼ਨਾਂ' ),
+       'FileDuplicateSearch'       => array( 'ਨਕਲੀ_ਫ਼ਾਈਲ_ਖੋਜੋ' ),
+       'Filepath'                  => array( 'ਫ਼ਾਈਲ_ਪਥ' ),
+       'Import'                    => array( 'ਆਯਾਤ' ),
+       'Invalidateemail'           => array( 'ਗਲਤ_ਈ-ਮੇਲ_ਪਤਾ' ),
        'JavaScriptTest'            => array( 'ਜਾਵਾਸਕ੍ਰਿਪਟ_ਪਰਖ' ),
-       'Listadmins'                => array( 'ਐਡਮਿਨਾਂ_ਦੀ_ਸੂਚੀ' ),
-       'Listbots'                  => array( 'ਬੋਟਾਂ_ਦੀ_ਲਿਸਟ' ),
-       'Listfiles'                 => array( 'ਫ਼ਾਈਲਾਂ_ਦੀ_ਲਿਸਟ', 'ਤਸਵੀਰਾਂ_ਦੀ_ਲਿਸਟ' ),
-       'Listredirects'             => array( 'ਰੀਡਿਰੈਕਟਾਂ_ਦੀ_ਲਿਸਟ' ),
-       'Listusers'                 => array( 'ਵਰਤੋਂਕਾਰਾਂ_ਦੀ_ਲਿਸਟ' ),
-       'Longpages'                 => array( 'ਲੰਬੇ_ਸਫ਼ੇ' ),
-       'MergeHistory'              => array( 'ਰਲ਼ਾਉਣ_ਦਾ_ਅਤੀਤ' ),
-       'MIMEsearch'                => array( 'MIME_ਖੋਜ' ),
+       'BlockList'                 => array( 'ਪਾਬੰਦੀਆਂ_ਦੀ_ਸੂਚੀ' ),
+       'LinkSearch'                => array( 'ਲਿੰਕ_ਖੋਜੋ' ),
+       'Listadmins'                => array( 'ਪ੍ਰਬੰਧਕਾਂ_ਦੀ_ਸੂਚੀ' ),
+       'Listbots'                  => array( 'ਬੋਟਾਂ_ਦੀ_ਸੂਚੀ' ),
+       'Listfiles'                 => array( 'ਫ਼ਾਈਲਾਂ_ਦੀ_ਸੂਚੀ' ),
+       'Listgrouprights'           => array( 'ਵਰਤੋਂਕਾਰ_ਹੱਕ_ਸੂਚੀ' ),
+       'Listredirects'             => array( 'ਰੀਡਿਰੈਕਟਾਂ_ਦੀ_ਸੂਚੀ' ),
+       'Listusers'                 => array( 'ਵਰਤੋਂਕਾਰਾਂ_ਦੀ_ਸੂਚੀ' ),
+       'Lockdb'                    => array( 'ਡੈਟਾਬੇਸ_’ਤੇ_ਤਾਲਾ_ਲਗਾਓ' ),
+       'Log'                       => array( 'ਚਿੱਠਾ', 'ਚਿੱਠੇ' ),
+       'Lonelypages'               => array( 'ਇਕੱਲੇ_ਪੰਨੇ' ),
+       'Longpages'                 => array( 'ਲੰਬੇ_ਪੰਨੇ' ),
+       'MergeHistory'              => array( 'ਰਲਾਉਣ_ਦਾ_ਅਤੀਤ' ),
+       'MIMEsearch'                => array( 'MIME_ਖੋਜੋ' ),
+       'Mostcategories'            => array( 'ਸਭ_ਤੋਂ_ਵੱਧ_ਸ਼੍ਰੇਣੀਆਂ' ),
+       'Mostimages'                => array( 'ਸਭ_ਤੋਂ_ਵੱਧ_ਜੁੜੀਆਂ_ਫ਼ਾਈਲਾਂ' ),
+       'Mostinterwikis'            => array( 'ਸਭ_ਤੋਂ_ਵੱਧ_ਇੰਟਰਵਿਕੀ' ),
+       'Mostlinked'                => array( 'ਸਭ_ਤੋਂ_ਵੱਧ_ਜੁੜੇ_ਪੰਨੇ' ),
+       'Mostlinkedcategories'      => array( 'ਸਭ_ਤੋਂ_ਵੱਧ_ਜੁੜੀਆਂ_ਸ਼੍ਰੇਣੀਆਂ' ),
+       'Mostlinkedtemplates'       => array( 'ਸਭ_ਤੋਂ_ਵੱਧ_ਜੁੜੇ_ਫਰਮੇ' ),
+       'Mostrevisions'             => array( 'ਸਭ_ਤੋਂ_ਵੱਧ_ਰੀਵਿਜ਼ਨ' ),
        'Movepage'                  => array( 'ਸਿਰਲੇਖ_ਬਦਲੋ' ),
        'Mycontributions'           => array( 'ਮੇਰੇ_ਯੋਗਦਾਨ' ),
+       'Mypage'                    => array( 'ਮੇਰਾ_ਪੰਨਾ' ),
        'Mytalk'                    => array( 'ਮੇਰੀ_ਚਰਚਾ' ),
        'Myuploads'                 => array( 'ਮੇਰੇ_ਅੱਪਲੋਡ' ),
-       'Newimages'                 => array( 'ਨਵੀਆਂ_ਫ਼ਾਈਲਾਂ', 'ਨਵੀਆਂ_ਤਸਵੀਰਾਂ' ),
+       'Newimages'                 => array( 'ਨਵੀਆਂ_ਫ਼ਾਈਲਾਂ' ),
        'Newpages'                  => array( 'ਨਵੇਂ_ਪੰਨੇ' ),
        'PasswordReset'             => array( 'ਪਾਸਵਰਡ_ਰੀਸੈੱਟ' ),
        'PermanentLink'             => array( 'ਪੱਕਾ_ਲਿੰਕ' ),
@@ -95,25 +126,51 @@ $specialPageAliases = array(
        'Prefixindex'               => array( 'ਅਗੇਤਰ_ਤਤਕਰਾ' ),
        'Protectedpages'            => array( 'ਸੁਰੱਖਿਅਤ_ਪੰਨੇ' ),
        'Protectedtitles'           => array( 'ਸੁਰੱਖਿਅਤ_ਸਿਰਲੇਖ' ),
-       'Randompage'                => array( 'ਰਲ਼ਵਾਂ', 'ਰਲਵਾਂ_ਪੰਨਾ' ),
-       'Randomredirect'            => array( 'ਰਲਵਾਂ_ਰੀਡਿਰੈਕਟ' ),
-       'Recentchanges'             => array( 'ਤਾਜਾ_ਤਬਦੀਲੀਆਂ' ),
-       'Search'                    => array( 'ਖੋਜ' ),
+       'Randompage'                => array( 'ਰਲਵਾਂ_ਪੰਨਾ' ),
+       'Randomredirect'            => array( 'ਸੁਰੱਖਿਅਤ_ਰੀਡਿਰੈਕਟ' ),
+       'Recentchanges'             => array( 'ਹਾਲ_\'ਚ_ਹੋਈਆਂ_ਤਬਦੀਲੀਆਂ' ),
+       'Recentchangeslinked'       => array( 'ਜੁੜੀਆਂ_ਤਾਜ਼ਾ_ਤਬਦੀਲੀਆਂ' ),
+       'Revisiondelete'            => array( 'ਰੀਵਿਜਨ_ਮਿਟਾਓ' ),
+       'Search'                    => array( 'ਖੋਜੋ' ),
        'Shortpages'                => array( 'ਛੋਟੇ_ਪੰਨੇ' ),
        'Specialpages'              => array( 'ਖਾਸ_ਪੰਨੇ' ),
-       'Statistics'                => array( 'à¨\86à¨\82ਕੜੇ' ),
+       'Statistics'                => array( 'à¨\85à©°ਕੜੇ' ),
        'Tags'                      => array( 'ਟੈਗ' ),
-       'Undelete'                  => array( 'ਅਣ-ਮਿਟਾਉਣ' ),
+       'Unblock'                   => array( 'ਪਾਬੰਦੀ_ਹਟਾਓ' ),
+       'Uncategorizedcategories'   => array( 'ਸ਼੍ਰੇਣੀਹੀਣ_ਸ਼੍ਰੇਣੀਆਂ' ),
+       'Uncategorizedimages'       => array( 'ਸ਼੍ਰੇਣੀਹੀਣ_ਫ਼ਾਈਲਾਂ' ),
+       'Uncategorizedpages'        => array( 'ਸ਼੍ਰੇਣੀਹੀਣ_ਪੰਨੇ' ),
+       'Uncategorizedtemplates'    => array( 'ਸ਼੍ਰੇਣੀਹੀਣ_ਸਾਂਚੇ' ),
+       'Undelete'                  => array( 'ਅਣ-ਹਟਾਓਣ' ),
+       'Unlockdb'                  => array( 'ਡੈਟਾਬੇਸ_ਖੋਲ੍ਹੋ' ),
+       'Unusedcategories'          => array( 'ਅਣਵਰਤੀਆਂ_ਸ਼੍ਰੇਣੀਆਂ' ),
+       'Unusedimages'              => array( 'ਅਣਵਰਤੀਆਂ_ਫ਼ਾਈਲਾਂ' ),
+       'Unusedtemplates'           => array( 'ਅਣਵਰਤੇ_ਫਰਮੇ' ),
+       'Unwatchedpages'            => array( 'ਬੇ-ਨਿਗਰਾਨ_ਪੰਨੇ' ),
        'Upload'                    => array( 'ਅੱਪਲੋਡ' ),
        'Userlogin'                 => array( 'ਮੈਂਬਰ_ਲਾਗਇਨ' ),
        'Userlogout'                => array( 'ਮੈਂਬਰ_ਲਾਗਆਊਟ' ),
+       'Userrights'                => array( 'ਮੈਂਬਰ_ਹੱਕ', 'ਪ੍ਰਬੰਧਕ_ਬਣਾਓ', 'ਬੋਟ_ਬਣਾਓ' ),
+       'Version'                   => array( 'ਰੂਪ' ),
        'Wantedcategories'          => array( 'ਚਾਹੀਦੀਆਂ_ਸ਼੍ਰੇਣੀਆਂ' ),
        'Wantedfiles'               => array( 'ਚਾਹੀਦੀਆਂ_ਫ਼ਾਈਲਾਂ' ),
+       'Wantedpages'               => array( 'ਚਾਹੀਦੇ_ਪੰਨੇ', 'ਟੁੱਟੇ_ਜੋੜ' ),
        'Wantedtemplates'           => array( 'ਚਾਹੀਦੇ_ਫਰਮੇ' ),
        'Watchlist'                 => array( 'ਨਿਗਰਾਨੀ-ਲਿਸਟ' ),
+       'Whatlinkshere'             => array( 'ਕਿਹੜੇ_ਪੰਨੇ_ਇੱਥੇ_ਜੋੜਦੇ_ਹਨ' ),
        'Withoutinterwiki'          => array( 'ਬਿਨਾਂ_ਇੰਟਰਵਿਕੀਆਂ_ਵਾਲੇ' ),
 );
 
+$magicWords = array(
+       'redirect'                  => array( '0', '#ਰੀਡਿਰੈਕਟ', '#REDIRECT' ),
+       'url_wiki'                  => array( '0', 'ਵਿਕੀ', 'WIKI' ),
+       'defaultsort_noerror'       => array( '0', 'ਗਲਤੀ_ਨਹੀਂ', 'noerror' ),
+       'pagesincategory_all'       => array( '0', 'ਸਬ', 'all' ),
+       'pagesincategory_pages'     => array( '0', 'ਪੰਨੇ', 'pages' ),
+       'pagesincategory_subcats'   => array( '0', 'ਉਪਸ਼੍ਰੇਣੀਆਂ', 'subcats' ),
+       'pagesincategory_files'     => array( '0', 'ਫ਼ਾਈਲਾਂ', 'files' ),
+);
+
 $digitTransformTable = array(
        '0' => '੦', # &#x0a66;
        '1' => '੧', # &#x0a67;
@@ -255,11 +312,11 @@ Manual:External_editors ਹੋਰ ਜਾਣਕਾਰੀ।])',
 'category-empty' => "''ਇਸ ਸ਼੍ਰੇਣੀ ਵਿੱਚ ਇਸ ਵੇਲੇ ਕੋਈ ਵੀ ਪੰਨਾ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ ਹੈ।''",
 'hidden-categories' => '{{PLURAL:$1|ਲੁਕਵੀਂ ਸ਼੍ਰੇਣੀ|ਲੁਕਵੀਂਆਂ ਸ਼੍ਰੇਣੀਆਂ}}',
 'hidden-category-category' => 'ਲੁਕੀਆਂ ਕੈਟੇਗਰੀਆਂ',
-'category-subcat-count' => 'à¨\87ਸ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨µà¨¿à©±à¨\9a, à¨\95à©\81ੱਲ $2 à¨µà¨¿à©±à¨\9aà©\8bà¨\82, {{PLURAL:$2|ਸਿਰਫ਼ ਇਹ ਉਪਸ਼੍ਰੇਣੀ ਹੈ|ਇਹ {{PLURAL:$1|ਉਪਸ਼੍ਰੇਣੀ ਹੈ|$1 ਉਪਸ਼੍ਰੇਣੀਆਂ ਹਨ}}}}।',
+'category-subcat-count' => 'à¨\87ਸ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨µà¨¿à©±à¨\9a, à¨\95à©\81ੱਲ $2 à¨µà¨¿à©±à¨\9aà©\8bà¨\82, {{PLURAL:$2|à¨\95à©\87ਵਲ ਇਹ ਉਪਸ਼੍ਰੇਣੀ ਹੈ|ਇਹ {{PLURAL:$1|ਉਪਸ਼੍ਰੇਣੀ ਹੈ|$1 ਉਪਸ਼੍ਰੇਣੀਆਂ ਹਨ}}}}।',
 'category-subcat-count-limited' => 'ਇਸ ਕੈਟੇਗਰੀ ਵਿਚ {{PLURAL:$1|ਸਬ-ਕੈਟੇਗਰੀ ਹੈ|$1 ਸਬ-ਕੈਟੇਗਰੀਆਂ ਹਨ}}।',
-'category-article-count' => '{{PLURAL:$2|à¨\87ਸ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨µà¨¿à©±à¨\9a à¨¸à¨¿à¨°à¨«à¨¼ ਇਹ ਪੰਨਾ ਹੈ।| ਇਸ ਸ਼੍ਰੇਣੀ ਵਿੱਚ, ਕੁੱਲ $2 ਵਿੱਚੋਂ, ਇਹ {{PLURAL:$1|ਪੰਨਾ ਹੈ|$1 ਪੰਨੇ ਹਨ}}}}।',
+'category-article-count' => '{{PLURAL:$2|à¨\87ਸ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨µà¨¿à©±à¨\9a à¨\95à©\87ਵਲ ਇਹ ਪੰਨਾ ਹੈ।| ਇਸ ਸ਼੍ਰੇਣੀ ਵਿੱਚ, ਕੁੱਲ $2 ਵਿੱਚੋਂ, ਇਹ {{PLURAL:$1|ਪੰਨਾ ਹੈ|$1 ਪੰਨੇ ਹਨ}}}}।',
 'category-article-count-limited' => 'ਮੌਜੂਦਾ ਕੈਟੇਗਰੀ ਵਿਚ ਇਹ {{PLURAL:$1|ਸਫ਼ਾ ਹੈ|$1 ਸਫ਼ੇ ਹਨ}}।',
-'category-file-count' => '{{PLURAL:$2|à¨\87ਸ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨µà¨¿à©±à¨\9a à¨¸à¨¿à¨°à¨«à¨¼ ਇਹ ਫ਼ਾਈਲ ਹੈ|ਇਸ ਸ਼੍ਰੇਣੀ ਵਿੱਚ {{PLURAL:$1|ਫ਼ਾਈਲ ਹੈ|$1 ਫ਼ਾਈਲਾਂ ਹਨ}}}}।',
+'category-file-count' => '{{PLURAL:$2|à¨\87ਸ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨µà¨¿à©±à¨\9a à¨\95à©\87ਵਲ ਇਹ ਫ਼ਾਈਲ ਹੈ|ਇਸ ਸ਼੍ਰੇਣੀ ਵਿੱਚ {{PLURAL:$1|ਫ਼ਾਈਲ ਹੈ|$1 ਫ਼ਾਈਲਾਂ ਹਨ}}}}।',
 'category-file-count-limited' => 'ਮੌਜੂਦਾ ਕੈਟੇਗਰੀ ਵਿਚ ਇਹ {{PLURAL:$1|ਫ਼ਾਈਲ ਹੈ|$1 ਫ਼ਾਈਲਾਂ ਹਨ}}।',
 'listingcontinuesabbrev' => 'ਜਾਰੀ',
 'index-category' => 'ਤਤਕਰੇ ਵਾਲ਼ੇ ਸਫ਼ੇ',
@@ -271,6 +328,7 @@ Manual:External_editors ਹੋਰ ਜਾਣਕਾਰੀ।])',
 'newwindow' => '(ਨਵੀਂ ਵਿੰਡੋ ਵਿੱਚ ਖੁੱਲ੍ਹਦੀ ਹੈ)',
 'cancel' => 'ਰੱਦ ਕਰੋ',
 'moredotdotdot' => 'ਹੋਰ...',
+'morenotlisted' => 'ਹੋਰ ਨਹੀ ਹੈਗੇ',
 'mypage' => 'ਪੰਨਾ',
 'mytalk' => 'ਚਰਚਾ',
 'anontalk' => 'ਇਸ IP ਲਈ ਗੱਲ-ਬਾਤ',
@@ -304,6 +362,7 @@ Manual:External_editors ਹੋਰ ਜਾਣਕਾਰੀ।])',
 'namespaces' => 'ਨਾਮ-ਥਾਂਵਾਂ',
 'variants' => 'ਬਦਲ',
 
+'navigation-heading' => 'ਦਿਕਚਾਲਨ ਸੂਚੀ',
 'errorpagetitle' => 'ਗਲਤੀ',
 'returnto' => '$1 ’ਤੇ ਵਾਪਸ ਜਾਓ।',
 'tagline' => '{{SITENAME}} ਤੋਂ',
@@ -353,7 +412,7 @@ Manual:External_editors ਹੋਰ ਜਾਣਕਾਰੀ।])',
 'otherlanguages' => 'ਹੋਰ ਭਾਸ਼ਾਵਾਂ',
 'redirectedfrom' => '($1 ਤੋਂ ਰੀਡਿਰੈਕਟ)',
 'redirectpagesub' => 'ਰੀਡਿਰੈਕਟ ਸਫ਼ਾ',
-'lastmodifiedat' => 'à¨\87ਹ à¨ªà©°à¨¨à¨¾ à¨\86à¨\96ਰà©\80 à¨µà¨¾à¨° $1 à¨¨à©\82à©° $2 â\80\99ਤà©\87 à¨¬à¨¦à¨² à¨\97ਿਆ ਸੀ।',
+'lastmodifiedat' => 'à¨\87ਸ à¨ªà©°à¨¨à¨¾ à¨¦à¨¾ à¨ªà¨¿à©±à¨\9bਲਾ à¨¬à¨¦à¨²à¨¾à¨µ  $1 à¨¨à©\82à©°  $2 à¨µà¨\9cà©\87 à¨¹à©\8bà¨\87ਆ ਸੀ।',
 'viewcount' => 'ਇਹ ਸਫ਼ਾ {{PLURAL:$1|ਇੱਕ ਵਾਰ|$1 ਵਾਰ}} ਵੇਖਿਆ ਗਿਆ।',
 'protectedpage' => 'ਸੁਰੱਖਿਅਤ ਪੇਜ',
 'jumpto' => 'ਇਸ ’ਤੇ ਜਾਓ:',
@@ -399,7 +458,7 @@ $1',
 'retrievedfrom' => '"$1" ਤੋਂ ਲਿਆ',
 'youhavenewmessages' => 'ਤੁਹਾਡੇ ਲਈ $1। ($2)',
 'newmessageslink' => 'ਨਵੇਂ ਸੁਨੇਹੇ',
-'newmessagesdifflink' => 'ਪਿà¨\9bਲà©\80 à¨¬à¨¦à¨²à©\80',
+'newmessagesdifflink' => 'ਪਿੱà¨\9bਲਾ à¨¬à¨¦à¨²à¨¾à¨µ',
 'youhavenewmessagesfromusers' => '{{PLURAL:$3|ਇੱਕ ਵਰਤੋਂਕਾਰ|$3 ਵਰਤੋਂਕਾਰਾਂ}} ਵੱਲੋਂ ਤੁਹਾਨੂੰ $1 ($2)।',
 'youhavenewmessagesmanyusers' => 'ਕਈ ਵਰਤੋਂਕਾਰਾਂ ਵੱਲੋਂ ਤੁਹਾਨੂੰ $1 ($2)।',
 'newmessageslinkplural' => '{{PLURAL:$1|ਇੱਕ ਨਵਾਂ ਸੁਨੇਹਾ|ਨਵੇਂ ਸੁਨੇਹੇ}} {{PLURAL:$1|ਹੈ|ਹਨ}}',
@@ -434,7 +493,7 @@ $1',
 'nstab-main' => 'ਪੰਨਾ',
 'nstab-user' => 'ਵਰਤੋਂਕਾਰ ਪੰਨੇ',
 'nstab-media' => 'ਮੀਡੀਆ ਸਫ਼ਾ',
-'nstab-special' => 'à¨\96ਾਸ ਪੰਨਾ',
+'nstab-special' => 'ਵਿਸ਼à©\87ਸ਼ ਪੰਨਾ',
 'nstab-project' => 'ਪਰਿਯੋਜਨਾ ਪੰਨਾ',
 'nstab-image' => 'ਫ਼ਾਈਲ',
 'nstab-mediawiki' => 'ਸੁਨੇਹਾ',
@@ -492,15 +551,25 @@ $1',
 ਇਸਨੇ ਕੋਈ ਕਾਰਨ ਨਹੀਂ ਦੱਸਿਆ।',
 'badtitle' => 'ਗਲਤ ਸਿਰਲੇਖ',
 'badtitletext' => 'ਤੁਹਾਡਾ ਦਰਖਾਸਤਸ਼ੁਦਾ ਸਿਰਲੇਖ ਨਾਕਾਬਿਲ, ਖਾਲੀ ਜਾਂ ਗਲਤ ਜੁੜਿਆ ਹੋਇਆ inter-languagd ਜਾਂ inter-wiki ਸਿਰਲੇਖ ਹੈ। ਇਹ ਵੀ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਸ ਵਿੱਚ ਇਕ-ਦੋ ਅੱਖਰ ਐਸੇ ਹੋਣ ਜੋ ਸਿਰਲੇਖ ਵਿੱਚ ਵਰਤੇ ਨਹੀਂ ਜਾ ਸਕਦੇ।',
+'querypage-no-updates' => 'ਇਸ ਪੇਜ  ਦਾ ਆਧੁਨੀਕਰਣ ਵਰਜਿਤ ਹੈ।
+ਆਂਕੜੇ ਹੱਲੇ ਤਾਜ਼ੇ ਨਹੀ ਹੋ ਸਕਦੇ ।',
+'wrong_wfQuery_params' => ' wfQuery()<br /> ਨੂ ਲਤ ਰਾਸ਼ੀ ਮਿਲੇ ਹੋਯੇ ਨੇ
+ ਫੁਨ੍ਕ੍ਤਿਓਂ:$1<br />
+ ਪ੍ਰਸ਼ਨ: $2',
 'viewsource' => 'ਸਰੋਤ ਵੇਖੋ',
 'viewsource-title' => '$1 ਲਈ ਸਰੋਤ ਵੇਖੋ',
 'actionthrottled' => 'ਕਾਰਜ ਬੰਦ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ',
+'actionthrottledtext' => 'ਸਪੈਮ ਦੀ ਰੋਕਥਾਮ ਲਈ, ਇਹ ਕਰੀਆ ਇਨ੍ਹੇ ਘੱਟ ਸਮੇਂ ਵਿੱਚ ਇੱਕ ਸੀਮਾ ਤੋਂ ਜਿਆਦਾ ਵਾਰ ਕਰਨ ਤੋਂ ਮਨਾਹੀ ਹੈ, ਅਤੇ ਤੁਸੀਂ ਇਸ ਸੀਮਾ ਨੂੰ ਪਾਰ ਕਰ ਚੁੱਕੇ ਹੋ।
+ਕਿਰਪਾ ਕਰਕੇ ਕੁਝ ਸਮੇਂ ਬਾਅਦ ਪੁੰਨ: ਜਤਨ ਕਰੋ।',
 'protectedpagetext' => 'ਇਹ ਪੰਨੇ ਸੰਪਾਦਨ ਅਤੇ ਹੋਰ ਕੰਮ ਤੋਂ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਹੋਇਆ ਹੈ।',
 'viewsourcetext' => 'ਤੁਸੀਂ ਇਸ ਸਫ਼ੇ ਦਾ ਸਰੋਤ ਵੇਖ ਅਤੇ ਨਕਲ ਕਰ ਸਕਦੇ ਹੋ:',
 'viewyourtext' => 'ਤੁਸੀਂ ਇਸ ਸਫ਼ੇ ’ਤੇ ਕੀਤੀਆਂ "ਆਪਣੀਆਂ ਸੋਧਾਂ" ਦਾ ਸਰੋਤ ਵੇਖ ਅਤੇ ਨਕਲ ਕਰ ਸਕਦੇ ਹੋ:',
 'protectedinterface' => 'ਇਹ ਪੰਨਾ ਸਾਫ਼ਟਵੇਅਰ ਇੰਟਰਫ਼ੇਸ ਦਾ ਮੂਲ ਪਾਠ ਹੈ ,ਅਤੇ ਦੁਰਵਰਤੌਂ ਤੌਂ ਬਚਾਅ ਲਈ ਰਾਖਵਾਂ ਕੀਤਾ ਗਿਆ ਹੈ।',
 'editinginterface' => "'''ਚਿਤਾਵਨੀ''' ਤੁਸੀਂ ਐਸੇ ਪੰਨੇ ਨੂੰ ਬਦਲ ਰਹੇ ਹੋ ਜੋ ਸਾਫ਼ਟਵੇਅਰ ਇੰਟਰਫ਼ੇਸ ਦੇ ਮੂਲ ਪਾਠ ਲਈ ਵਰਤਿਆ ਗਿਆ ਹੈ।
 ਇਸ ਪੰਨੇ ਦੇ ਬਦਲਾਅ ਦੁਸਰੇ ਵਰਤੋਂ ਕਰਣ ਵਾਲਿਆਂ ਲਈ ਵਰਤੇ ਜਾਣ ਵਾਲੇ ਇੰਟਰਫਲੇਸ ਦੀ ਸ਼ਕਲ ਤੇ ਅਸਰ ਪਾ ਦੇਣਗੇ।ਅਨੁਵਾਦ ਕਰਣ ਲਈ ,ਕਿਰਪਾ ਕਰਕੇ [//translatewiki.net/wiki/Main_Page?setlang=pa ਟ੍ਰਾਂਸਲੇਟਵਿਕੀ.ਨੈਟ] ਦੀ ਵਰਤੌਂ ਕਰੋ,ਇਹ ਮੀਡੀਆਵਿਕੀ ਦੀ ਸਥਾਨਕੀਕਰਣ ਯੋਜਨਾ ਹੈ।",
+'sqlhidden' => '(SQL ਪ੍ਰਸ਼ਨ ਚੁਪ੍ਪੇ ਹੁਏ ਨੇ)',
+'cascadeprotected' => 'ਇਹ ਪੰਨਾ ਸੁਰੱਖਿਅਤ ਹੈ, ਕਿਉਂਕਿ ਇਹ ਨਿੱਚੇ ਲਿਖੇ {{PLURAL:$1|ਪੰਨਾ|ਪੰਨੇ}} ਦੀ ਸੁਰੱਖਿਆ-ਸੀੜੀ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ:
+$2',
 'namespaceprotected' => "ਤੁਹਾਨੂੰ '''$1''' ਥਾਂ-ਨਾਮ ਵਾਲ਼ੇ ਸਫ਼ਿਆਂ ਵਿਚ ਫੇਰ-ਬਦਲ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।",
 'customcssprotected' => 'ਤੁਹਾਨੂੰ ਇਸ CSS ਸਫ਼ੇ ਵਿਚ ਸੋਧ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ ਕਿਉਂਕਿ ਇਸ ਵਿਚ ਕਿਸੇ ਹੋਰ ਮੈਂਬਰ ਦੀਆਂ ਨਿੱਜੀ ਸੈਟਿੰਗਾਂ ਹਨ।',
 'customjsprotected' => 'ਤੁਹਾਨੂੰ ਇਸ CSS ਸਫ਼ੇ ਵਿਚ ਸੋਧ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ ਕਿਉਂਕਿ ਇਸ ਵਿਚ ਕਿਸੇ ਹੋਰ ਮੈਂਬਰ ਦੀਆਂ ਨਿੱਜੀ ਸੈਟਿੰਗਾਂ ਹਨ।',
@@ -520,7 +589,7 @@ You can continue to use {{SITENAME}} anonymously, or you can log in again as the
 Note that some pages may continue to be displayed as if you were still logged in, until you clear your browser cache.",
 'welcomeuser' => 'ਸੁਆਗਤ, $1!',
 'welcomecreation-msg' => 'ਤੁਹਾਡਾ ਖਾਤਾ ਬਣ ਚੁੱਕਾ ਹੈ। ਆਪਣੀਆਂ [[Special:Preferences|{{SITENAME}} ਪਸੰਦਾਂ]] ਬਦਲਣੀਆਂ ਨਾ ਭੁੱਲੋ।',
-'yourname' => 'ਮà©\88à¨\82ਬਰ ਨਾਮ:',
+'yourname' => 'ਵਰਤà©\8bà¨\82à¨\95ਾਰ ਨਾਮ:',
 'yourpassword' => 'ਪਾਸਵਰਡ:',
 'yourpasswordagain' => 'ਪਾਸਵਰਡ ਦੁਬਾਰਾ ਲਿਖੋ:',
 'remembermypassword' => 'ਇਸ ਕੰਪਿਊਟਰ ’ਤੇ ਮੇਰਾ ਲਾਗਇਨ ਯਾਦ ਰੱਖੋ (ਵੱਧ ਤੋਂ ਵੱਧ $1 {{PLURAL:$1|ਦਿਨ|ਦਿਨਾਂ}} ਲਈ)',
@@ -528,7 +597,7 @@ Note that some pages may continue to be displayed as if you were still logged in
 'password-change-forbidden' => 'ਇਸ ਵਿਕੀ ਤੇ ਤੁਸੀਂ ਪਾਸਵਰਡ ਨਹੀਂ ਬਦਲ ਸਕਦੇ।',
 'login' => 'ਲਾਗ ਇਨ',
 'nav-login-createaccount' => 'ਲਾਗ ਇਨ/ਖਾਤਾ ਬਣਾਓ',
-'loginprompt' => 'ਤà©\81ਹਾਨà©\82à©° {{SITENAME}} â\80\99ਤà©\87 à¨²à¨¾à¨\97à¨\87ਨ à¨\95ਰਨ à¨²à¨\88 à¨\95à©\82à¨\95à©\80à¨\9c਼ ਯੋਗ ਕਰਨੇ ਜ਼ਰੂਰੀ ਹਨ।',
+'loginprompt' => 'ਤà©\81ਹਾਨà©\82à©° {{SITENAME}} â\80\99ਤà©\87 à¨²à¨¾à¨\97à¨\87ਨ à¨\95ਰਨ à¨²à¨\88 à¨\95à©\82à¨\95à©\80ਸ ਯੋਗ ਕਰਨੇ ਜ਼ਰੂਰੀ ਹਨ।',
 'userlogin' => 'ਲਾਗ ਇਨ/ਖਾਤਾ ਬਣਾਓ',
 'userloginnocreate' => 'ਲਾਗ ਇਨ',
 'logout' => 'ਲਾਗ ਆਉਟ',
@@ -676,13 +745,13 @@ $2
 # Edit pages
 'summary' => 'ਸਾਰ:',
 'subject' => 'ਵਿਸ਼ਾ/ਹੈੱਡਲਾਈਨ:',
-'minoredit' => 'à¨\87ਹ à¨\87ੱà¨\95 à¨\9bà©\8bà¨\9fà©\80 à¨¬à¨¦à¨²à©\80 ਹੈ',
+'minoredit' => 'à¨\87ਹ à¨\87ੱà¨\95 à¨\9bà©\8bà¨\9fਾ à¨¬à¨¦à¨²à¨¾à¨µ ਹੈ',
 'watchthis' => 'ਇਸ ਪੰਨੇ ’ਤੇ ਧਿਆਨ ਰੱਖੋ',
 'savearticle' => 'ਪੰਨਾ ਸਾਂਭੋ',
 'preview' => 'ਝਲਕ',
 'showpreview' => 'ਝਲਕ ਵੇਖੋ',
 'showlivepreview' => 'ਲਾਈਵ ਝਲਕ',
-'showdiff' => 'ਤਬਦà©\80ਲà©\80 à¨µà©\87à¨\96à©\8b',
+'showdiff' => 'ਬਦਲਾਵ à¨µà¨¿à¨\96ਾà¨\93',
 'anoneditwarning' => "'''ਚੇਤਾਵਨੀ:''' ਤੁਸੀਂ ਲਾਗਇਨ ਨਹੀਂ ਕੀਤਾ ਹੈ। ਤੁਹਾਡਾ IP ਐਡਰੈੱਸ ਇਸ ਪੰਨੇ ਦੇ ਇਤਿਹਾਸ ਵਿੱਚ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਵੇਗਾ।",
 'anonpreviewwarning' => "''ਤੁਸੀਂ ਲਾਗਇਨ ਨਹੀਂ ਕੀਤਾ। ਤਬਦੀਲੀ ਸਾਂਭਣ ਨਾਲ਼ ਤੁਹਾਡਾ IP ਪਤਾ ਸਫ਼ੇ ਦੇ ਸੋਧ ਅਤੀਤ ਵਿਚ ਰਿਕਾਰਡ ਹੋ ਜਾਵੇਗਾ।''",
 'missingsummary' => "'''ਯਾਦ-ਦਹਾਨੀ:''' ਤੁਸੀਂ ਸੋਧ ਸਾਰ ਮੁਹੱਈਆ ਨਹੀਂ ਕਰਵਾਇਆ। ਜੇ ਤੁਸੀਂ \"{{int:savearticle}}\" ਤੇ ਦੁਬਾਰਾ ਕਲਿੱਕ ਕੀਤਾ ਤਾਂ ਤੁਹਾਡਾ ਸਫ਼ਾ ਇਸਦੇ ਬਿਨਾਂ ਹੀ ਸਾਂਭਿਆ ਜਾਵੇਗਾ।",
@@ -746,7 +815,8 @@ sysop}}|administrator]] ਨਾਲ ਰਾਬਤਾ ਕਰ ਸਕਦੇ ਹੋ।
 '''ਇਹ ਹਾਲੇ ਸਾਂਭੀ ਨਹੀਂ ਗਈ ਹੈ!'''",
 'updated' => '(ਅੱਪਡੇਟ)',
 'note' => "'''ਨੋਟ:'''",
-'previewnote' => "'''ਯਾਦ ਰੱਖੋ ਇਹ ਕੇਵਲ ਇੱਕ ਝਲਕ ਹੈ।''' ਤੁਹਾਡੀਆਂ ਬਦਲੀਆਂ ਹਾਲੇ ਸਾਂਭੀਆਂ ਨਹੀਂ ਗਈਆਂ!",
+'previewnote' => "'''ਯਾਦ ਰੱਖੋ, ਇਹ ਕੇਵਲ ਇੱਕ ਝਲਕ ਹੈ।'''
+ਤੁਹਾਡੇ ਬਦਲਾਵ ਹੁਣੇ ਤੱਕ ਸਾਂਭੇ ਨਹੀਂ ਗਏ ਹਨ!",
 'continue-editing' => 'ਸੰਪਾਦਨ ਜਾਰੀ ਰੱਖੋ',
 'previewconflict' => 'ਇਹ ਝਲਕ ਲਿਖਤ ਦਾ ਓਹ ਅਕਸ ਪੇਸ਼ ਕਰਦੀ ਹੈ ਜਿਵੇਂ ਓਹ ਤੁਹਾਡੇ ਸਾਂਭੇ ਜਾਣ ਤੋਂ ਬਾਅਦ ਦਿੱਸੇਗਾ।',
 'editing' => '$1 ਸੰਪਾਦਨ',
@@ -781,7 +851,7 @@ $1 ਲੁਕਵੀਆਂ ਸ਼੍ਰੇਣੀਆਂ}} ਦਾ ਮੈਂਬਰ 
 'nocreate-loggedin' => 'ਤੁਹਾਨੂੰ ਨਵੇਂ ਸਫ਼ੇ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।',
 'permissionserrors' => 'ਅਧਿਕਾਰ ਗਲਤੀਆਂ',
 'permissionserrorstext' => 'ਤੁਹਾਨੂੰ ਇੰਝ ਕਰਨ ਦੇ ਅਧਿਕਾਰ ਨਹੀਂ ਹਨ। ਹੇਠ ਦਿੱਤੇ {{PLURAL:$1|ਕਾਰਨ|ਕਾਰਨ}} ਨੇ:',
-'permissionserrorstext-withaction' => '{{PLURAL:$1|ਇਸ ਕਾਰਨ|ਇਹਨਾਂ ਕਾਰਨਾਂ}} ਕਰਕੇ ਤੁਹਾਨੂੰ $2 ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ:',
+'permissionserrorstext-withaction' => 'ਤੁਹਾਨੂੰ  $2 ਦੀ ਅਨੁਮਤੀ ਨਹੀਂ ਹਨ, ਨਿੱਚੇ ਲਿਖੇ {{PLURAL:$1|ਕਾਰਨ|ਕਾਰਨਾਂ}} ਦੀ ਵਜ੍ਹਾ:',
 'recreate-moveddeleted-warn' => "'''ਚਿਤਾਵਣੀ:
 ਤੁਸੀਂ ਐਸਾ ਪੰਨਾ ਬਣਾ ਰਹੇ ਹੋ ਜੋ ਪਹਿਲਾਂ ਹਟਾਇਆ ਜਾ ਚੁੱਕਾ ਹੈ।'''
 
@@ -799,7 +869,7 @@ $1 ਲੁਕਵੀਆਂ ਸ਼੍ਰੇਣੀਆਂ}} ਦਾ ਮੈਂਬਰ 
 # Parser/template warnings
 'post-expand-template-inclusion-warning' => "'''ਖਬਰਦਾਰ:''' ਸਾਂਚਾ ਦਾ ਅਕਾਰ ਬਹੁਤ ਵੱਡਾ ਹੈ। ਕੁਝ ਟੈਂਪਲੇਟ ਸ਼ਾਮਲ ਨਹੀਂ ਹੋਣਗੇ।",
 'post-expand-template-inclusion-category' => 'ਓਹ ਪੰਨੇ ਜਿੱਥੇ ਟੈਂਪਲੇਟਾਂ ਦੇ ਸ਼ਾਮਲ ਕਰਨ ਦਾ ਅਕਾਰ ਹੱਦੋਂ ਵਧ ਗਿਆ ਹੈ',
-'post-expand-template-argument-warning' => "'''à¨\96਼ਬਰਦਾਰ:'''
+'post-expand-template-argument-warning' => "'''à¨\9aà©\87ਤਾਵਨà©\80:'''
 ਇਸ ਪੰਨੇ ਤੇ ਘੱਟੋ ਘੱਟ ਇੱਕ ਐਸੀ ਸਾਂਚਾ ਬਹਿਸ ਹੈ ਜਿਸ ਦਾ ਅਕਾਰ ਬਹੁਤ ਵੱਡਾ ਹੈ। ਅਜਿਹੀਆਂ ਬਹਿਸਾਂ ਨੂੰ ਛੱਡ ਦਿੱਤਾ ਗਿਆ ਹੈ।",
 'post-expand-template-argument-category' => 'ਐਸੇ ਪੰਨੇ ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਸਾਂਚੇ ਦੇ ਸਁਘਟਕ ਛੁੱਟ ਗਏ ਹਨ ।',
 'parser-template-loop-warning' => 'ਸਾਂਚੇ ਦਾ ਲੂਪ ਲੱਭਿਆ: [[$1]]',
@@ -828,15 +898,15 @@ $3 ਨੇ ਕਾਰਨ ਇਹ ਦੱਸਿਆ ਹੈ, ''$2''",
 'currentrevisionlink' => 'ਸਭ ਤੋ ਨਵਾਂ ਰੀਵਿਜਨ',
 'cur' => 'ਮੌਜੂਦਾ',
 'next' => 'ਅੱਗੇ',
-'last' => 'à¨\86à¨\96ਰà©\80',
+'last' => 'ਪਿੱà¨\9bਲਾ',
 'page_first' => 'ਪਹਿਲਾਂ',
 'page_last' => 'ਆਖਰੀ',
-'histlegend' => "ਫ਼ਰà¨\95 ਵੇਖੋ:
+'histlegend' => "à¨\85ੰਤਰ ਵੇਖੋ:
 ਮੁਕਾਬਲਾ ਕਰਨ ਲਈ ਰੀਵਿਜਨਾਂ ਦੇ ਰੇਡੀਓ ਬਟਨਾਂ ਵਿੱਚ ਨਿਸ਼ਾਨ ਲਾਓ ਅਤੇ ਜਾਓ ਜਾਂ ਸਭ ਤੋਂ ਥੱਲੇ ਵਾਲੇ ਬਟਨ ਤੇ ਕਲਿੱਕ ਕਰੋ। <br />
 ਲੈਜਅੰਡ:
-'''({{int:cur}})''' = à¨¨à¨µà©\87à¨\82 à¨°à©\80ਵਿà¨\9cਨ à¨¨à¨¾à¨²à©\8bà¨\82 à¨«à¨¼à¨°à¨\95, '''({{int:last}})''' = à¨\86à¨\96ਰà©\80 à¨°à©\80ਵਿà¨\9cਨ à¨¨à¨¾à¨²à©\8bà¨\82 à¨«à¨¼à¨°à¨\95, '''({{int:minoreditletter}})''' = à¨\9bà©\8bà¨\9fà©\80 à¨¸à©\8bਧ।",
+'''({{int:cur}})''' = à¨¨à¨µà©\87à¨\82 à¨°à©\80ਵਿà¨\9cਨ à¨¨à¨¾à¨²à©\8bà¨\82 à¨\85ੰਤਰ, '''({{int:last}})''' = à¨ªà¨¿à©±à¨\9bਲà©\80 à¨°à©\80ਵਿà¨\9cਨ à¨¨à¨¾à¨²à©\8bà¨\82 à¨\85ੰਤਰ, '''({{int:minoreditletter}})''' = à¨\9bà©\8bà¨\9fਾ à¨¬à¨¦à¨²à¨¾à¨µ।",
 'history-fieldset-title' => 'ਇਤਿਹਾਸ ਨੂੰ ਬ੍ਰਾਊਜ਼ ਕਰੋ',
-'history-show-deleted' => 'ਸਿਰਫ਼ ਹਟਾਏ ਗਏ',
+'history-show-deleted' => 'à¨\95à©\87ਵਲ ਹਟਾਏ ਗਏ',
 'histfirst' => 'ਸਭ ਤੋਂ ਪਹਿਲਾਂ ਦੇ',
 'histlast' => 'ਸਭ ਤੋਂ ਨਵਾਂ',
 'historysize' => '($1 ਬਾਈਟ)',
@@ -873,7 +943,7 @@ page={{FULLPAGENAMEE}}}} ਮਿਟਾਉਣ ਦੇ ਚਿੱਠੇ] ਵਿਚ 
 'rev-suppressed-diff-view' => "ਇਸ ਫ਼ਰਕ ਵਿੱਚੋਂ ਇੱਕ ਰੀਵਿਜ਼ਨ '''ਜ਼ਬਤ''' ਕੀਤੀ ਜਾ ਚੁੱਕੀ ਹੈ।
 ਤਫ਼ਸੀਲ [{{fullurl:{{#Special:Log}}/delete|
 page={{FULLPAGENAMEE}}}} ਜ਼ਬਤੀ ਦੇ ਚਿੱਠੇ] ਵਿਚ ਵੇਖੀ ਜਾ ਸਕਦੀ ਹੈ।",
-'rev-delundel' => 'ਦਿà¨\96ਾà¨\93/ਲà©\81à¨\95ਾਓ',
+'rev-delundel' => 'ਵਿà¨\96ਾà¨\93/à¨\9bà©\81ਪਾਓ',
 'rev-showdeleted' => 'ਵਖਾਓ',
 'revisiondelete' => 'ਰੀਵਿਜ਼ਨ ਮਿਟਾਓ/ਮਿਟਾਈ ਰੱਦ ਕਰੋ',
 'revdelete-nooldid-title' => 'ਕੋਈ ਟਾਰਗੇਟ ਰੀਵਿਜ਼ਨ ਨਹੀਂ',
@@ -938,7 +1008,7 @@ page={{FULLPAGENAMEE}}}} ਜ਼ਬਤੀ ਦੇ ਚਿੱਠੇ] ਵਿਚ ਵ
 'compareselectedversions' => 'ਚੁਣੇ ਵਰਜਨਾਂ ਦੀ ਤੁਲਨਾ',
 'showhideselectedversions' => 'ਚੁਣੇ ਰੀਵਿਜ਼ਨ ਵਖਾਓ/ਲੁਕਾਓ',
 'editundo' => 'ਉਧੇੜੋ',
-'diff-multi' => '({{PLURAL:$2|ਮà©\88à¨\82ਬਰ à¨¦à©\80|$2 à¨®à©\88à¨\82ਬਰਾà¨\82 à¨¦à©\80à¨\86à¨\82}} {{PLURAL:$1|ਵਿà¨\9aà¨\95ਾਰਲà©\80 à¨°à©\80ਵਿà¨\9cਨ à¨¨à¨¹à©\80à¨\82 à¨¦à¨¿à¨\96ਾà¨\88 à¨\9cਾ à¨°à¨¹à©\80|ਵਿà¨\9aà¨\95ਾਰਲà©\80à¨\86à¨\82 $1 à¨°à©\80ਵਿà¨\9c਼ਨਾਂ ਨਹੀਂ ਦਿਖਾਈਆਂ ਜਾ ਰਹੀਆਂ}})',
+'diff-multi' => '({{PLURAL:$2|ਵਰਤà©\8bà¨\82à¨\95ਾਰ à¨¦à©\80|$2 à¨µà¨°à¨¤à©\8bà¨\82à¨\95ਾਰਾà¨\82 à¨¦à©\80à¨\86à¨\82}} {{PLURAL:$1|ਵਿà¨\9aà¨\95ਾਰਲà©\80 à¨°à©\80ਵਿà¨\9cਨ à¨¨à¨¹à©\80à¨\82 à¨¦à¨¿à¨\96ਾà¨\88 à¨\9cਾ à¨°à¨¹à©\80|ਵਿà¨\9aà¨\95ਾਰਲà©\80à¨\86à¨\82 $1 à¨°à©\80ਵਿà¨\9cਨਾਂ ਨਹੀਂ ਦਿਖਾਈਆਂ ਜਾ ਰਹੀਆਂ}})',
 
 # Search results
 'searchresults' => 'ਖੋਜ ਨਤੀਜੇ',
@@ -1004,6 +1074,10 @@ $3|'''1''' ਨਤੀਜਾ|'''$3''' ਨਤੀਜੇ}} ਵਖਾਓ।",
 # Quickbar
 'qbsettings' => 'ਤੁਰੰਤ ਬਾਰ',
 'qbsettings-none' => 'ਕੋਈ ਨਹੀਂ',
+'qbsettings-fixedleft' => 'ਕਾਬ੍ਬ੍ਹੇ ਨੂ ਸਥਾਪਿਤ',
+'qbsettings-fixedright' => 'ਸੱਜੇ ਨੂ ਸਥਾਪਿਤ',
+'qbsettings-floatingleft' => 'ਕਾਬ੍ਬ੍ਹੇ ਨੂ ਰੁਲਦੀ',
+'qbsettings-floatingright' => 'ਸੱਜੇ ਨੂ ਰੁਲਦੀ',
 
 # Preferences page
 'preferences' => 'ਮੇਰੀ ਪਸੰਦ',
@@ -1082,7 +1156,7 @@ $3|'''1''' ਨਤੀਜਾ|'''$3''' ਨਤੀਜੇ}} ਵਖਾਓ।",
 'gender-female' => 'ਔਰਤ',
 'email' => 'ਈਮੇਲ',
 'prefs-help-realname' => 'ਅਸਲੀ ਨਾਂ ਚੋਣਵਾਂ ਹੈ, ਅਤੇ ਜੇ ਤੁਸੀਂ ਇਹ ਦਿੱਤਾ ਹੈ ਤਾਂ ਤੁਹਾਡੇ ਕੰਮ ਵਾਸਤੇ ਗੁਣ ਦੇ ਤੌਰ ਉੱਤੇ ਵਰਤਿਆ ਜਾਵੇਗਾ।',
-'prefs-help-email' => 'ਤà©\81ਹਾਡà©\80 à¨®à¨°à¨\9c਼à©\80 à¨¹à©\88 à¨\88ਮà©\87ਲ à¨ªà¨¤à¨¾ à¨¦à¨¿à¨\93 à¨\9cਾà¨\82 à¨¨à¨¾ à¨¦à¨¿à¨\93 à¨ªà¨° à¨ªà¨¾à¨¸à¨µà¨°à¨¡ à¨­à©\81ੱਲ à¨\9cਾਣ à¨¤à©\87 à¨¨à¨µà¨¾à¨\82 à¨ªà¨¾à¨¸à¨µà¨°à¨¡ à¨¹à¨¾à¨¸à¨² à¨\95ਰਨ à¨²à¨\88 à¨\87ਹ à¨\9c਼ਰੂਰੀ ਹੈ।',
+'prefs-help-email' => 'ਤà©\81ਹਾਡà©\80 à¨®à¨°à¨\9cà©\80 à¨¹à©\88 à¨\88ਮà©\87ਲ à¨ªà¨¤à¨¾ à¨¦à¨¿à¨\93 à¨\9cਾà¨\82 à¨¨à¨¾ à¨¦à¨¿à¨\93 à¨ªà¨° à¨ªà¨¾à¨¸à¨µà¨°à¨¡ à¨­à©\81ੱਲ à¨\9cਾਣ à¨¤à©\87 à¨¨à¨µà¨¾à¨\82 à¨ªà¨¾à¨¸à¨µà¨°à¨¡ à¨¹à¨¾à¨¸à¨² à¨\95ਰਨ à¨²à¨\88 à¨\87ਹ à¨\9cਰੂਰੀ ਹੈ।',
 'prefs-help-email-others' => 'ਤੁਸੀਂ ਇਹ ਵੀ ਚੁਣ ਸਕਦੇ ਹੋ ਕਿ ਤੁਹਾਡੇ ਵਰਤੋਂਕਾਰ ਜਾਂ ਚਰਚਾ ਪੰਨੇ ਤੋਂ ਹੋਰ ਵਰਤੋਂਕਾਰ ਤੁਹਾਨੂੰ ਈ-ਮੇਲ ਭੇਜ ਸਕਣ?
 ਜਦੋਂ ਹੋਰ ਵਰਤੋਂਕਾਰ ਤੁਹਾਨੂੰ ਈ-ਮੇਲ ਭੇਜਦੇ ਹਨ ਤਾਂ ਤੁਹਾਡਾ ਈ-ਮੇਲ ਪਤਾ ਜ਼ਾਹਰ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ।',
 'prefs-help-email-required' => 'ਈ-ਮੇਲ ਪਤਾ ਚਾਹੀਦਾ ਹੈ।',
@@ -1182,46 +1256,45 @@ $3|'''1''' ਨਤੀਜਾ|'''$3''' ਨਤੀਜੇ}} ਵਖਾਓ।",
 'action-sendemail' => 'ਈ-ਮੇਲਾਂ ਭੇਜਣ',
 
 # Recent changes
-'nchanges' => '$1 {{PLURAL:$1|ਬਦਲੀ|
-ਬਦਲੀਆਂ}}',
-'recentchanges' => 'ਹਾਲ ਹੀ ’ਚ ਹੋਈਆਂ ਤਬਦੀਲੀਆਂ',
-'recentchanges-legend' => 'ਹਾਲ ਦੀਆਂ ਬਦਲੀਆਂ ਸਬੰਧੀ ਚੋਣਾਂ',
+'nchanges' => '$1 {{PLURAL:$1|ਬਦਲਾਵ}}',
+'recentchanges' => 'ਹਾਲ ’ਚ ਹੋਏ ਬਦਲਾਵ',
+'recentchanges-legend' => 'ਹਾਲ ਦੇ ਪਰਿਵਰਤਨ ਸਬੰਧੀ ਵਿਕਲਪ',
 'recentchanges-summary' => 'ਇਸ ਵਿਕੀ ’ਤੇ ਹੋਈਆਂ ਸਭ ਤੋਂ ਨਵੀਆਂ ਤਬਦੀਲੀਆਂ ਇਸ ਸਫ਼ੇ ’ਤੇ ਵੇਖੋ।',
-'recentchanges-feed-description' => 'ਇਸ ਵਿਕੀ ’ਤੇ ਹਾਲ ਹੀ ਵਿਚ ਹੋਈਆਂ ਬਦਲੀਆਂ ਇਸ ਫ਼ੀਡ ’ਚ ਵੇਖੀਆਂ ਜਾ ਸਕਦੀਆਂ ਹਨ।',
+'recentchanges-feed-description' => 'ਇਸ ਵਿਕੀ ’ਤੇ ਹਾਲ ‘ਚ ਹੋਏ ਬਦਲਾਵ ਇਸ ਫ਼ੀਡ ’ਚ ਵੇਖੀਆਂ ਜਾ ਸਕਦੀਆਂ ਹਨ।',
 'recentchanges-label-newpage' => 'ਇਹ ਸੰਪਾਦਨ ਨੇ ਨਵਾਂ ਪੰਨਾ ਬਣਾਇਆ ਹੈ',
 'recentchanges-label-minor' => 'ਇਹ ਇੱਕ ਛੋਟਾ ਸੰਪਾਦਨ ਹੈ',
 'recentchanges-label-bot' => 'ਇਹ ਸੰਪਾਦਨ ਬੋਟ ਵਲੋਂ ਕੀਤੀ ਗਈ ਹੈ',
 'recentchanges-label-unpatrolled' => 'ਇਹ ਫੇਰ-ਬਦਲ ਹਾਲੇ ਵੇਖਿਆ ਨਹੀਂ ਗਿਆ',
 'rcnote' => "$4, $5 ਤੱਕ ਆਖਰੀ {{PLURAL:$2|ਦਿਨ|'''$2''' ਦਿਨਾਂ}} ਵਿੱਚ {{PLURAL:$1|'''1''' ਬਦਲੀ ਹੋਈ ਹੈ।|'''$1''' ਬਦਲੀਆਂ ਹੋਈਆਂ ਹਨ।}}",
-'rcnotefrom' => "'''$2''' à¨¤à©±à¨\95 ('''$1''' à¨¤à©±à¨\95 à¨¦à¨¿à©±à¨¸à¨¦à©\80à¨\86à¨\82) à¨¤à¨¬à¨¦à©\80ਲà©\80à¨\86à¨\82 ਹੇਠ ਦਿੱਤੀਆਂ ਹਨ।",
-'rclistfrom' => '$1 à¨¤à©\8bà¨\82 à¨¸à¨¼à©\81ਰà©\82 à¨\95ਰà¨\95à©\87 à¨¨à¨µà©\80à¨\86à¨\82 à¨¬à¨¦à¨²à©\80à¨\86à¨\82 ਵੇਖਾਓ',
-'rcshowhideminor' => '$1 à¨\9bà©\8bà¨\9fà©\80à¨\86à¨\82 à¨¬à¨¦à¨²à©\80à¨\86à¨\82',
+'rcnotefrom' => "'''$2''' à¨¤à©±à¨\95 ('''$1''' à¨¤à©±à¨\95 à¨¦à¨¿à©±à¨¸à¨¦à©\87) à¨¬à¨¦à¨²à¨¾à¨µ ਹੇਠ ਦਿੱਤੀਆਂ ਹਨ।",
+'rclistfrom' => '$1 à¨¤à©\8bà¨\82 à¨¸à¨¼à©\81ਰà©\82 à¨\95ਰà¨\95à©\87 à¨¨à¨µà©\87à¨\82 à¨¬à¨¦à¨²à¨¾à¨µ ਵੇਖਾਓ',
+'rcshowhideminor' => '$1 à¨\9bà©\8bà¨\9fà©\87 à¨¬à¨¦à¨²à¨¾à¨µ',
 'rcshowhidebots' => '$1 ਬੋਟ',
-'rcshowhideliu' => '$1 à¨²à¨¾à¨\97à¨\87ਨ à¨¹à©\8bà¨\8f à¨®à©\88à¨\82ਬਰ',
+'rcshowhideliu' => '$1 à¨²à¨¾à¨\97à¨\87ਨ à¨¹à©\8bà¨\8f à¨µà¨°à¨¤à©\8bà¨\82à¨\95ਾਰਾà¨\82',
 'rcshowhideanons' => '$1 ਗੁਮਨਾਮ ਵਰਤੋਂਕਾਰ',
 'rcshowhidepatr' => 'ਜਾਂਚੇ ਹੋਏ ਸੰਪਾਦਨ $1',
-'rcshowhidemine' => 'ਮà©\87ਰà©\80à¨\86à¨\82 à¨¬à¨¦à¨²à©\80à¨\86à¨\82 $1',
-'rclinks' => 'ਪਿà¨\9bਲà©\87 $2 à¨¦à¨¿à¨¨à¨¾à¨\82 à¨µà¨¿à©±à¨\9a à¨¹à©\8bà¨\88à¨\86à¨\82 $1 à¨¬à¨¦à¨²à©\80à¨\86à¨\82 ਵੇਖਾਓ<br /> $3',
-'diff' => 'ਫ਼ਰà¨\95',
+'rcshowhidemine' => 'ਮà©\87ਰà©\87 à¨¬à¨¦à¨²à¨¾à¨µ $1',
+'rclinks' => 'ਪਿà¨\9bਲà©\87 $2 à¨¦à¨¿à¨¨à¨¾à¨\82 à¨µà¨¿à©±à¨\9a à¨¹à©\8bà¨\8f $1 à¨¬à¨¦à¨²à¨¾à¨µ ਵੇਖਾਓ<br /> $3',
+'diff' => 'à¨\85ੰਤਰ',
 'hist' => 'ਇਤਿਹਾਸ',
-'hide' => 'ਲà©\81à¨\95ਾਓ',
-'show' => 'ਵਖਾਓ',
+'hide' => 'à¨\9bà©\81ਪਾਓ',
+'show' => 'ਵਿà¨\96ਾà¨\93',
 'minoreditletter' => 'ਛੋ',
 'newpageletter' => 'ਨ',
-'boteditletter' => 'ਬ',
+'boteditletter' => 'ਬ',
 'rc_categories_any' => 'ਕੋਈ ਵੀ',
-'rc-enhanced-expand' => 'ਵੇਰਵਾ ਵਖਾਓ (ਜਾਵਾਸਕ੍ਰਿਪਟ ਲੋੜੀਂਦੀ ਹੈ)',
-'rc-enhanced-hide' => 'ਵà©\87ਰਵਾ à¨²à©\81à¨\95ਾਓ',
+'rc-enhanced-expand' => 'ਵà©\87ਰਵਾ à¨µà©\87à¨\96ਾà¨\93 (à¨\9cਾਵਾਸà¨\95à©\8dਰਿਪà¨\9f à¨²à©\8bà©\9cà©\80à¨\82ਦà©\80 à¨¹à©\88)',
+'rc-enhanced-hide' => 'ਵà©\87ਰਵਾ à¨\9bà©\81ਪਾਓ',
 
 # Recent changes linked
-'recentchangeslinked' => 'ਸਬੰਧਤ à¨¤à¨¬à¨¦à©\80ਲà©\80à¨\86à¨\82',
+'recentchangeslinked' => 'ਸਬੰਧਤ à¨¬à¨¦à¨²à¨¾à¨µ',
 'recentchangeslinked-feed' => 'ਸਬੰਧਤ ਤਬਦੀਲੀਆਂ',
-'recentchangeslinked-toolbox' => 'ਸਬੰਧਿਤ à¨¬à¨¦à¨²à©\80à¨\86à¨\82',
-'recentchangeslinked-title' => '"$1" à¨¨à¨¾à¨² à¨¸à¨¬à©°à¨§à¨¿à¨¤ à¨¤à¨¬à¨¦à©\80ਲà©\80à¨\86à¨\82',
-'recentchangeslinked-noresult' => 'à¨\9cà©\81à©\9cà©\87 à¨ªà©°à¨¨à¨¿à¨\86à¨\82 â\80\99ਤà©\87, à¨¦à¨¿à©±à¨¤à©\87 à¨¸à¨®à©\87à¨\82 â\80\99à¨\9a à¨\95à©\8bà¨\88 à¨¬à¨¦à¨²à©\80 ਨਹੀਂ ਹੋਈ।',
-'recentchangeslinked-summary' => 'à¨\87ਹ à¨¸à©\82à¨\9aà©\80 à¨\87ੱà¨\95 à¨\96ਾਸ à¨ªà©°à¨¨à©\87 à¨¨à¨¾à¨² à¨¸à¨¬à©°à¨§à¨¿à¨¤ à¨ªà©°à¨¨à¨¿à¨\86à¨\82 à¨\9cਾà¨\82 à¨\95ਿਸà©\87 à¨\96ਾਸ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨¦à©\87 à¨®à©\88à¨\82ਬਰਾà¨\82 à¨¦à©\87 à¨¹à¨¾à¨² à¨µà¨¿à©±à¨\9a à¨¹à©\8bà¨\88à¨\86à¨\82 à¨¬à¨¦à¨²à©\80à¨\86ਂ ਨੂੰ ਦਰਸਾਂਉਦੀ ਹੈ। [[Special:Watchlist|ਤੁਹਾਡੀ ਧਿਆਨਸੂਚੀ]] ਵਿੱਚ ਮੌਜੂਦ ਪੰਨੇ ਮੋਟੇ ਅੱਖਰਾਂ ਵਿੱਚ ਦਿਖਾਈ ਦੇਣਗੇ।',
+'recentchangeslinked-toolbox' => 'ਪੰਨà©\87 à¨¨à¨¾à¨² à¨¸à©°à¨¬à©°à¨§à¨¿à¨¤ à¨¬à¨¦à¨²à¨¾à¨µ',
+'recentchangeslinked-title' => '"$1" à¨¨à¨¾à¨² à¨¸à¨¬à©°à¨§à¨¿à¨¤ à¨¬à¨¦à¨²à¨¾à¨µ',
+'recentchangeslinked-noresult' => 'à¨\9cà©\81à©\9cà©\87 à¨ªà©°à¨¨à¨¿à¨\86à¨\82 â\80\99ਤà©\87, à¨¦à¨¿à©±à¨¤à©\87 à¨¸à¨®à©\87à¨\82 â\80\99à¨\9a à¨\95à©\8bà¨\88 à¨¬à¨¦à¨²à¨¾à¨µ ਨਹੀਂ ਹੋਈ।',
+'recentchangeslinked-summary' => 'à¨\87ਹ à¨¸à©\82à¨\9aà©\80 à¨\87ੱà¨\95 à¨µà¨¿à¨¸à¨¼à©\87ਸ਼ à¨ªà©°à¨¨à©\87 à¨¨à¨¾à¨² à¨¸à¨¬à©°à¨§à¨¿à¨¤ à¨ªà©°à¨¨à¨¿à¨\86à¨\82 à¨\9cਾà¨\82 à¨\95ਿਸà©\87 à¨µà¨¿à¨¸à¨¼à©\87ਸ਼ à¨¸à¨¼à©\8dਰà©\87ਣà©\80 à¨¦à©\87 à¨®à©\88à¨\82ਬਰਾà¨\82 à¨¦à©\87 à¨¹à¨¾à¨² â\80\98à¨\9a à¨¹à©\8bà¨\8f à¨¬à¨¦à¨²à¨¾à¨µà¨¾ਂ ਨੂੰ ਦਰਸਾਂਉਦੀ ਹੈ। [[Special:Watchlist|ਤੁਹਾਡੀ ਧਿਆਨਸੂਚੀ]] ਵਿੱਚ ਮੌਜੂਦ ਪੰਨੇ ਮੋਟੇ ਅੱਖਰਾਂ ਵਿੱਚ ਦਿਖਾਈ ਦੇਣਗੇ।',
 'recentchangeslinked-page' => 'ਪੰਨੇ ਦਾ ਨਾਮ:',
-'recentchangeslinked-to' => 'à¨\87ਸਦà©\87 à¨¬à¨¦à¨²à©\87 à¨\87ਸ à¨ªà©°à¨¨à©\87 à¨¨à¨¾à¨² à¨\9cà©\81à©\9cà©\87 à¨ªà©°à¨¨à¨¿à¨\86à¨\82 à¨µà¨¿à©±à¨\9a à¨¹à©\8bà¨\8f à¨¬à¨¦à¨²à¨¾à¨\85 à¨¦ਿਖਾਓ',
+'recentchangeslinked-to' => 'à¨\87ਸਦà©\87 à¨¬à¨¦à¨²à©\87 à¨\87ਸ à¨ªà©°à¨¨à©\87 à¨¨à¨¾à¨² à¨\9cà©\81à©\9cà©\87 à¨ªà©°à¨¨à¨¿à¨\86à¨\82 à¨µà¨¿à©±à¨\9a à¨¹à©\8bà¨\8f à¨¬à¨¦à¨²à¨¾à¨\85 à¨µਿਖਾਓ',
 
 # Upload
 'upload' => 'ਫ਼ਾਈਲ ਅੱਪਲੋਡ ਕਰੋ',
@@ -1581,7 +1654,7 @@ to upload files.',
 'watchlistcontains' => 'ਤੁਹਾਡੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿਚ $1 {{PLURAL:$1|ਸਫ਼ਾ ਹੈ|ਸਫ਼ੇ ਹਨ}}।',
 'wlnote' => "$3, $4 ਮੁਤਾਬਕ ਆਖ਼ਰੀ {{PLURAL:$2|ਘੰਟੇ|'''$2''' ਘੰਟਿਆਂ}} ਵਿਚ {{PLURAL:
 $1|ਤਬਦੀਲੀ ਹੋਈ|'''$1''' ਤਬਦੀਲੀਆਂ ਹੋਈਆਂ}}, ਹੇਠਾਂ ਵੇਖੋ।",
-'wlshowlast' => 'à¨\86à¨\96ਰà©\80 $1 à¨¦à¨¿à¨¨ $2 à¨\98à©°à¨\9fà©\87 $3 à¨µà¨\96ਾà¨\93',
+'wlshowlast' => 'ਪਿੱà¨\9bਲà©\87 $1 à¨\98à©°à¨\9fà©\87 $2 à¨¦à¨¿à¨¨ $3 à¨µà©\87à¨\96à©\8b',
 'watchlist-options' => 'ਧਿਆਨਸੂਚੀ ਦੇ ਇਖਤਿਆਰ',
 
 # Displayed when you click the "watch" button and it is in the process of watching
@@ -1828,7 +1901,7 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 ਮਿਹਰਬਾਨੀ ਕਰਕੇ ਕੋਈ ਹੋਰ ਨਾਮ ਚੁਣੋ।',
 'movedto' => 'ਮੂਵ ਕੀਤਾ',
 'movepage-page-moved' => 'ਸਫ਼ਾ $1 ਨੂੰ $2 ’ਤੇ ਭੇਜਿਆ ਜਾ ਚੁੱਕਾ ਹੈ।',
-'movelogpage' => 'ਸਿਰਲà©\87à¨\96 à¨¬à¨¦à¨²à©\80 ਦਾ ਚਿੱਠਾ',
+'movelogpage' => 'ਸਥਾਨਾà¨\82ਤਰਣ ਦਾ ਚਿੱਠਾ',
 'movereason' => 'ਕਾਰਨ:',
 'revertmove' => 'ਰੱਦ ਕਰੋ',
 'delete_and_move' => 'ਹਟਾਓ ਅਤੇ ਮੂਵ ਕਰੋ',
@@ -1916,7 +1989,7 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 'tooltip-t-print' => 'ਇਹ ਪੰਨੇ ਦਾ ਛਪਣਯੋਗ ਵਰਜਨ',
 'tooltip-t-permalink' => 'ਪੰਨੇ ਦੇ ਇਸ ਰੀਵਿਜਨ ਲਈ ਪੱਕਾ ਲਿੰਕ',
 'tooltip-ca-nstab-main' => 'ਸਮੱਗਰੀ ਪੰਨਾ ਵੇਖੋ',
-'tooltip-ca-nstab-user' => 'ਮà©\88à¨\82ਬਰ ਪੰਨਾ ਵੇਖੋ',
+'tooltip-ca-nstab-user' => 'ਵਰਤà©\8bà¨\82à¨\95ਾਰ ਪੰਨਾ ਵੇਖੋ',
 'tooltip-ca-nstab-media' => 'ਮੀਡਿਆ ਪੇਜ ਵੇਖੋ',
 'tooltip-ca-nstab-special' => 'ਇਹ ਵਿਸ਼ੇਸ਼ ਪੰਨਾ ਹੈ, ਤੁਸੀਂ ਇਸ ਪੰਨੇ ਨੂੰ ਬਦਲ ਨਹੀਂ ਸਕਦੇ।',
 'tooltip-ca-nstab-project' => 'ਪਰਿਯੋਜਨਾ ਪੰਨਾ ਵੇਖੋ',
@@ -1925,9 +1998,9 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 'tooltip-ca-nstab-template' => 'ਸਾਂਚਾ ਵੇਖੋ',
 'tooltip-ca-nstab-help' => 'ਮੱਦਦ ਪੇਜ ਵੇਖੋ',
 'tooltip-ca-nstab-category' => 'ਸ਼੍ਰੇਣੀ ਪੰਨਾ ਵੇਖੋ',
-'tooltip-minoredit' => 'à¨\87ਸ â\80\99ਤà©\87 à¨¬à¨¤à©\8cਰ à¨\9bà©\8bà¨\9fà©\80 à¨¬à¨¦à¨²à©\80 ਨਿਸ਼ਾਨ ਲਾਓ',
+'tooltip-minoredit' => 'à¨\87ਸ â\80\99ਤà©\87 à¨¬à¨¤à©\8cਰ à¨\9bà©\8bà¨\9fਾ à¨¬à¨¦à¨²à¨¾à¨µ ਨਿਸ਼ਾਨ ਲਾਓ',
 'tooltip-save' => 'ਆਪਣੀਆਂ ਤਬਦੀਲੀਆਂ ਸਾਂਭੋ',
-'tooltip-preview' => 'à¨\86ਪਣà©\80 à¨¤à¨¬à¨¦à©\80ਲà©\80 ਦੀ ਝਲਕ ਵੇਖੋ, ਸਾਂਭਣ ਤੋਂ ਪਹਿਲਾਂ ਇਹ ਵਰਤੋਂ!',
+'tooltip-preview' => 'à¨\86ਪਣà©\87 à¨¬à¨¦à¨²à¨¾à¨µ ਦੀ ਝਲਕ ਵੇਖੋ, ਸਾਂਭਣ ਤੋਂ ਪਹਿਲਾਂ ਇਹ ਵਰਤੋਂ!',
 'tooltip-diff' => 'ਤੁਹਾਡੇ ਦੁਆਰਾ ਲਿਖਤ ਵਿੱਚ ਕੀਤੀਆਂ ਤਬਦੀਲੀਆਂ ਵਖਾਉਂਦਾ ਹੈ',
 'tooltip-compareselectedversions' => 'ਇਸ ਪੰਨੇ ਦੇ ਦੋ ਚੁਣੇ ਹੋਏ ਸੋਧਾਂ ਵਿੱਚ ਫ਼ਰਕ ਵੇਖੋ',
 'tooltip-watch' => 'ਇਸ ਪੰਨੇ ਨੂੰ ਆਪਣੀ ਧਿਆਨਸੂਚੀ ਵਿੱਚ ਪਾਓ',
@@ -1935,8 +2008,8 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 'tooltip-watchlistedit-raw-submit' => 'ਨਿਗਰਾਨੀ-ਲਿਸਟ ਨਵੀਂ ਕਰੋ',
 'tooltip-upload' => 'ਅੱਪਲੋਡ ਸਟਾਰਟ ਕਰੋ',
 'tooltip-rollback' => "''ਵਾਪਸ ਮੋੜੋ'' ਇੱਕ ਹੀ ਕਲਿੱਕ ਨਾਲ ਆਖਰੀ ਯੋਗਦਾਨ ਨੂੰ ਰੱਦ ਕਰ ਦਿੰਦਾ ਹੈ",
-'tooltip-undo' => '"à¨\89ਧà©\87à©\9cਨਾ" à¨\87ਸ à¨¤à¨¬à¨¦à©\80ਲà©\80 ਨੂੰ ਰੱਦ ਕਰਕੇ ਸੋਧ ਫ਼ਾਰਮ ਨੂੰ ਝਲਕ ਦੇ ਸ਼ੈਲੀ ਵਿੱਚ ਦਿਖਾਉਂਦਾ ਹੈ।
-à¨\87à©°à¨\9d "ਸਾਰ" à¨µà¨¿à©±à¨\9a à¨¤à¨¬à¨¦à©\80ਲà©\80 ਨਕਾਰਨ ਦਾ ਕਾਰਨ ਲਿਖਿਆ ਜਾ ਸਕਦਾ ਹੈ।',
+'tooltip-undo' => '"à¨\89ਧà©\87à©\9cਨਾ" à¨\87ਸ à¨¬à¨¦à¨²à¨¾à¨µ ਨੂੰ ਰੱਦ ਕਰਕੇ ਸੋਧ ਫ਼ਾਰਮ ਨੂੰ ਝਲਕ ਦੇ ਸ਼ੈਲੀ ਵਿੱਚ ਦਿਖਾਉਂਦਾ ਹੈ।
+à¨\87à©°à¨\9d "ਸਾਰ" à¨µà¨¿à©±à¨\9a à¨¬à¨¦à¨²à¨¾à¨µ ਨਕਾਰਨ ਦਾ ਕਾਰਨ ਲਿਖਿਆ ਜਾ ਸਕਦਾ ਹੈ।',
 'tooltip-preferences-save' => 'ਪਸੰਦਾਂ ਸਾਂਭੋ',
 'tooltip-summary' => 'ਸੰਖੇਪ ਸਾਰ ਦਰਜ ਕਰੋ',
 
@@ -1951,6 +2024,7 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 
 # Info page
 'pageinfo-header-edits' => 'ਸੋਧਾਂ ਦਾ ਅਤੀਤ',
+'pageinfo-article-id' => 'ਪੰਨਾ ਆਈ.ਡੀ',
 'pageinfo-watchers' => 'ਸਫ਼ੇ ’ਤੇ ਨਜ਼ਰ ਰੱਖਣ ਵਾਲਿਆਂ ਦੀ ਗਿਣਤੀ',
 'pageinfo-edits' => 'ਕੁੱਲ ਸੋਧਾਂ',
 
@@ -1962,8 +2036,8 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 'skinname-simple' => 'ਸੈਂਪਲ',
 
 # Browsing diffs
-'previousdiff' => 'â\86\90 à¨\87ਸ à¨¤à©\8bà¨\82 à¨ªà©\81ਰਾਣà©\80 à¨¬à¨¦à¨²à©\80',
-'nextdiff' => 'ਤਾà¨\9c਼ਾ à¨¸à©°à¨ªà¨¾à¨¦à¨¨ â\86\92',
+'previousdiff' => 'â\86\90 à¨\87ਸ à¨¤à©\8bà¨\82 à¨ªà©\81ਰਾਣਾ à¨¬à¨¦à¨²à¨¾à¨µ',
+'nextdiff' => 'ਤਾਜਾ ਸੰਪਾਦਨ →',
 
 # Media information
 'thumbsize' => 'ਥੰਮਨੇਲ ਆਕਾਰ:',
@@ -1972,7 +2046,7 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 'file-info-size' => '$1 × $2 ਪਿਕਸਲ, ਫ਼ਾਈਲ ਆਕਾਰ: $3, MIME ਕਿਸਮ: $4',
 'file-nohires' => 'ਇਸ ਤੋਂ ਵੱਡੀ ਚਿੱਤਰ ਮੌਜੂਦ ਨਹੀਂ ਹੈ।',
 'svg-long-desc' => 'SVG ਫ਼ਾਈਲ, ਆਮ ਤੌਰ ’ਤੇ $1 × $2 ਪਿਕਸਲ, ਫ਼ਾਈਲ ਦਾ ਅਕਾਰ: $3',
-'show-big-image' => 'ਪà©\82ਰਾ à¨°à©\88à¨\9c਼à©\8bਲà©\87ਸ਼ਨ',
+'show-big-image' => 'ਪੂਰਾ ਰੈਜੋਲੇਸ਼ਨ',
 
 # Special:NewFiles
 'newimages' => 'ਨਵੀਆਂ ਫ਼ਾਈਲਾਂ ਦੀ ਗੈਲਰੀ',
@@ -2094,7 +2168,7 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 'watchlistedit-raw-removed' => '{{PLURAL:$1|1 title was|$1 titles were}} ਹਟਾਓ:',
 
 # Watchlist editing tools
-'watchlisttools-view' => 'ਮà©\8cà¨\95à©\87 à¨®à©\81ਤਾਬà¨\95 à¨¬à¨¦à¨²à©\80à¨\86à¨\82 ਵੇਖੋ',
+'watchlisttools-view' => 'à¨\86ਧਾਰਿਤ à¨¬à¨¦à¨²à¨¾à¨µ ਵੇਖੋ',
 'watchlisttools-edit' => 'ਧਿਆਨਸੂਚੀ ਵੇਖੋ ’ਤੇ ਸੰਪਾਦਨ ਕਰੋ',
 'watchlisttools-raw' => 'ਕੱਚੀ ਧਿਆਨਸੂਚੀ ਸੰਪਾਦਨ ਕਰੋ',
 
@@ -2152,4 +2226,15 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 # Search suggestions
 'searchsuggest-search' => 'ਖੋਜ',
 
+# Durations
+'duration-seconds' => '$1 {{PLURAL:$1|ਸੇਕੋੰਡ|ਵਧੇਰੇ ਸੇਕੋੰਡ}}',
+'duration-minutes' => '$1 {{PLURAL:$1|ਮਿਨੁਟ |ਵਧੇਰੇ ਮਿਨੁਟ }}',
+'duration-hours' => '$1 {{PLURAL:$1|ਘੰਟੇ |ਵਧੇਰੇ ਘੰਟੇ }}',
+'duration-days' => '$1 {{PLURAL:$1|ਦਿਨ |ਵਧੇਰੇ ਦਿਨ }}',
+'duration-weeks' => '$1 {{PLURAL:$1|ਹਫ਼ਤੇ |ਵਧੇਰੇ ਹਫ਼ਤੇ }}',
+'duration-years' => '$1 {{PLURAL:$1|ਸਾਲ |ਵਧੇਰੇ ਸਾਲ }}',
+'duration-decades' => '$1 {{PLURAL:$1|ਦਸ਼ਕ  |ਵਧੇਰੇ ਦਸ਼ਕ }}',
+'duration-centuries' => '$1 {{PLURAL:$1|ਸ਼ਤਾਬਦੀ |ਵਧੇਰੇ ਸ਼ਤਾਬਦੀ }}',
+'duration-millennia' => '$1 {{PLURAL:$1|ਸਾਹਸ਼ਤਾਬਦੀ  |ਵਧੇਰੇ ਸਾਹਸ਼ਤਾਬਦੀ  }}',
+
 );
index e22c428..8beee8e 100644 (file)
@@ -648,10 +648,15 @@ Ale doét mie éte pu longue éq $1 {{PLURAL:$1|caracter|caractéres}}.',
 'imagelinks' => 'Usage dech fichié',
 'linkstoimage' => "{{PLURAL:$1|L'pache d'apreu est liée|Chés $1 paches d'apreu sont liées}} à ch'fichié-lo :",
 'nolinkstoimage' => "Autchune pache n'est loïée aveuc ch'fichié-lo",
-'sharedupload' => "Cht'fichié vient éd $1 pi i put ète imploïé par d'eutes proujés.",
-'sharedupload-desc-here' => "Ch'fichié i vient éd $1. I put ète uzer pèr d’eutes prodjés.
-Vir apré ([$2 pache]).",
+'sharedupload' => "Ch'fichié i vient éd $1. I put ète imploïé par d'eutes proujés.",
+'sharedupload-desc-there' => "Ch'fichié i vient éd $1. I put ète uzé pèr d’eutes prodjés. Vir l'pache [$2 édseur Commons].",
+'sharedupload-desc-here' => "Ch'fichié i vient éd $1. I put ète uzé pèr d’eutes prodjés.
+Vir l'pache [$2 édseur Commons].",
+'sharedupload-desc-edit' => "Ch'fichié i vient éd $1. I put ète imploïé par d'eutes proujés. Os pouvez canjer l' déscripcion dsu s' [$2 pache Commons].",
+'sharedupload-desc-create' => "Ch'fichié i vient éd $1. I put ète imploïé par d'eutes proujés. Os pouvez canjer l' déscripcion dsu s' [$2 pache Commons].",
 'uploadnewversion-linktext' => 'Quértcher eune novèle vérchion del pache-lo',
+'shared-repo-from' => 'à : $1',
+'shared-repo' => 'un dépôt partagé',
 
 # MIME search
 'mimesearch' => 'Tracher pèr type éd contenu MIME',
@@ -774,7 +779,7 @@ Vir apré ([$2 pache]).",
 # Delete
 'deletepage' => "Défacer l'pache",
 'confirmdeletetext' => "Vos alez défacer eune pache ou un fichié aveuc toutes chés antieusses vérchons.<br /> Confreumer éq ch'est cho éq vos voulez foaire, éq vos conprindez chés consécanches et pi éq ch'est bin s'lon el [[{{MediaWiki:Policy-url}}|politique éd MédiaWiki]].",
-'actioncomplete' => 'Plònne acchon',
+'actioncomplete' => 'Accion toute piéte',
 'actionfailed' => "L’action n'a poin réussi",
 'deletedtext' => "« $1 » o té défacé.
 Vir $2 pou eune lisse d'chés darinnes défachons.",
index ff3e36a..60a8a21 100644 (file)
 
 $fallback = 'de';
 
+$namespaceNames = array(
+       NS_MEDIA            => 'Medium',
+       NS_SPECIAL          => 'Schbezial',
+       NS_TALK             => 'Babble',
+       NS_USER             => 'Benudzer',
+       NS_USER_TALK        => 'Benudzer_Dischbediere',
+       NS_PROJECT_TALK     => '$1_Dischbediere',
+       NS_FILE             => 'Dadai',
+       NS_FILE_TALK        => 'Dadai_Dischbediere',
+       NS_MEDIAWIKI        => 'MediaWiki',
+       NS_MEDIAWIKI_TALK   => 'MediaWiki_Dischbediere',
+       NS_TEMPLATE         => 'Vorlach',
+       NS_TEMPLATE_TALK    => 'Vorlach_Dischbediere',
+       NS_HELP             => 'Hilf',
+       NS_HELP_TALK        => 'Hilf_Dischbediere',
+       NS_CATEGORY         => 'Kadegorie',
+       NS_CATEGORY_TALK    => 'Kadegorie_Dischbediere',
+);
+
+$namespaceAliases = array(
+       # German namespaces
+       'Medium'               => NS_MEDIA,
+       'Spezial'              => NS_SPECIAL,
+       'Diskussion'           => NS_TALK,
+       'Benutzer'             => NS_USER,
+       'Benutzer_Diskussion'  => NS_USER_TALK,
+       '$1_Diskussion'        => NS_PROJECT_TALK,
+       'Datei'                => NS_FILE,
+       'Datei_Diskussion'     => NS_FILE_TALK,
+       'MediaWiki_Diskussion' => NS_MEDIAWIKI_TALK,
+       'Vorlage'              => NS_TEMPLATE,
+       'Vorlage_Diskussion'   => NS_TEMPLATE_TALK,
+       'Hilfe'                => NS_HELP,
+       'Hilfe_Diskussion'     => NS_HELP_TALK,
+       'Kategorie'            => NS_CATEGORY,
+       'Kategorie_Diskussion' => NS_CATEGORY_TALK,
+);
+
 $messages = array(
 # User preference toggles
 'tog-showtoolbar' => "Werkzaich zum Bearwaide zaische (dodezu brauchd's JavaScript)",
@@ -370,6 +408,7 @@ Erklärung: '''({{int:cur}})''' = Unnerschied zu jetzert,
 'resetprefs' => 'Oischdellunge verwerfe',
 'guesstimezone' => 'Aus em Browser iwwernemme',
 'yourrealname' => 'Birscherlischer Nome:',
+'yourlanguage' => 'Schbrooch:',
 'gender-unknown' => 'Ghoim gkalde',
 
 # Groups
@@ -379,9 +418,9 @@ Erklärung: '''({{int:cur}})''' = Unnerschied zu jetzert,
 'group-bureaucrat' => 'Birokrade',
 'group-all' => '(alle)',
 
-'group-bot-member' => 'Bot',
-'group-sysop-member' => 'Adminischdrador',
-'group-bureaucrat-member' => 'Birokrad',
+'group-bot-member' => '{{GENDER:$1|Bot}}',
+'group-sysop-member' => '{{GENDER:$1|Adminischdrador}}',
+'group-bureaucrat-member' => '{{GENDER:$1|Birokrad}}',
 
 'grouppage-sysop' => '{{ns:project}}:Adminischtratore',
 
@@ -409,7 +448,7 @@ Erklärung: '''({{int:cur}})''' = Unnerschied zu jetzert,
 'rcshowhidemine' => 'Mai Bearwaidunge $1',
 'rclinks' => 'Zeich die letschte $1 Ännerunge in de letschte $2 Dache<br />$3',
 'diff' => 'Unnerschied',
-'hist' => 'Gschicht',
+'hist' => 'Gschichd',
 'hide' => 'vaschdeggle',
 'show' => 'zaische',
 'minoreditletter' => 'k',
@@ -433,8 +472,9 @@ Saide uff [[Special:Watchlist|Dainer Beowachdungslischt]] sin '''fett'''.",
 'uploadbtn' => 'Datei hochlade',
 'uploadlogpage' => 'Dateie-Logbuch',
 'filedesc' => 'Zommefassung',
+'fileuploadsummary' => 'Zommefassung:',
 'savefile' => 'Datei schbeichere',
-'uploadedimage' => 'hot „[[$1]]“ hochglade',
+'uploadedimage' => 'hod „[[$1]]“ nuffglade',
 
 # Lock manager
 'lockmanager-notlocked' => '„$1“ hod ned uffgmachd were kenne, die isch ganed gschberd gwesd.',
index 562583a..2cea497 100644 (file)
@@ -20,6 +20,7 @@
  * @author Holek
  * @author Jwitos
  * @author Kaganer
+ * @author Kaligula
  * @author Karol007
  * @author Lajsikonik
  * @author Lampak
@@ -39,6 +40,7 @@
  * @author Reedy
  * @author Remedios44
  * @author Remember the dot
+ * @author Rezonansowy
  * @author Rzuwig
  * @author Saper
  * @author Sovq
@@ -213,7 +215,7 @@ $magicWords = array(
        'redirect'                  => array( '0', '#PATRZ', '#PRZEKIERUJ', '#TAM', '#REDIRECT' ),
        'notoc'                     => array( '0', '__BEZSPISU__', '__NOTOC__' ),
        'nogallery'                 => array( '0', '__BEZGALERII__', '__NOGALLERY__' ),
-       'forcetoc'                  => array( '0', '__ZESPISEM__', '__FORCETOC__' ),
+       'forcetoc'                  => array( '0', '__ZESPISEM__', '__WYMUŚSPIS__', '__FORCETOC__' ),
        'toc'                       => array( '0', '__SPIS__', '__TOC__' ),
        'noeditsection'             => array( '0', '__BEZEDYCJISEKCJI__', '__NOEDITSECTION__' ),
        'currentday'                => array( '1', 'AKTUALNYDZIEŃ', 'CURRENTDAY' ),
@@ -731,7 +733,7 @@ Nie zapomnij dostosować [[Special:Preferences|preferencji]].',
 'gotaccount' => "Masz już konto? '''$1'''.",
 'gotaccountlink' => 'Zaloguj się',
 'userlogin-resetlink' => 'Zapomniałeś danych do zalogowania się?',
-'createaccountmail' => 'Wyślij hasło e-mailem',
+'createaccountmail' => 'Użyj tymczasowego hasła wygenerowanego losowo i wyślij je na podany poniżej adres e-mail',
 'createaccountreason' => 'Powód',
 'badretype' => 'Wprowadzone hasła różnią się między sobą.',
 'userexists' => 'Wybrana przez Ciebie nazwa użytkownika jest już zajęta.
@@ -1036,7 +1038,7 @@ Jeśli nie chcesz, żeby Twój tekst był dowolnie zmieniany przez każdego i ro
 Zapisując swoją edycję, oświadczasz, że ten tekst jest Twoim dziełem lub pochodzi z materiałów dostępnych na warunkach ''domeny publicznej'' lub kompatybilnych (zobacz także $1).
 '''PROSZĘ NIE WPROWADZAĆ MATERIAŁÓW CHRONIONYCH PRAWEM AUTORSKIM BEZ POZWOLENIA WŁAŚCICIELA!'''",
 'longpageerror' => "'''Błąd! Wprowadzony przez Ciebie tekst ma {{PLURAL:$1|1 kilobajt|$1 kilobajty|$1 kilobajtów}}. Długość tekstu nie może przekraczać {{PLURAL:$2|1 kilobajt|$2 kilobajty|$2 kilobajtów}}. Tekst nie może być zapisany.'''",
-'readonlywarning' => "'''Uwaga! Baza danych została zablokowana do celów administracyjnych. W tej chwili nie można zapisać nowej wersji strony. Zapisz jej treść do pliku, używając wytnij i wklej, aby zachować na później.'''
+'readonlywarning' => "'''Uwaga! Baza danych została zablokowana do celów administracyjnych. W tej chwili nie można zapisać nowej wersji strony. Jeśli chcesz, może skopiować ją do pliku, aby móc zapisać ją później.'''
 
 Administrator, który zablokował bazę, podał następujące wyjaśnienie: $1",
 'protectedpagewarning' => "'''Uwaga! Możliwość modyfikacja tej strony została zabezpieczona. Mogą ją edytować jedynie użytkownicy z uprawnieniami administratora.'''
@@ -1995,9 +1997,9 @@ Więcej informacji odnajdziesz na [$2 stronie opisu pliku].',
 'sharedupload-desc-here' => 'Ten plik znajduje się w $1 i może być używany w innych projektach.
 Poniżej znajdują się informacje ze [$2 strony opisu] tego pliku.',
 'sharedupload-desc-edit' => 'Plik ten pochodzi z $1 i może być wykorzystany w innych projektach.
-Być może zechcesz zmienić opis na tej [$2 stronie opisu pliku].',
+Jeżeli chcesz zmienić opis, zrób to na [$2 stronie opisu pliku].',
 'sharedupload-desc-create' => 'Plik ten pochodzi z $1 i może być wykorzystany w innych projektach.
-Być może zechcesz zmienić opis na tej [$2 stronie opisu pliku].',
+Jeżeli chcesz zmienić opis, zrób to na [$2 stronie opisu pliku].',
 'filepage-nofile' => 'Plik o tej nazwie nie istnieje.',
 'filepage-nofile-link' => 'Plik o tej nazwie nie istnieje, ale możesz go [$1 przesłać].',
 'uploadnewversion-linktext' => 'Załaduj nowszą wersję tego pliku',
@@ -2242,7 +2244,7 @@ Zobacz również [[Special:WantedCategories|brakujące kategorie]].',
 'linksearch-ok' => 'Szukaj',
 'linksearch-text' => 'Można użyć symboli wieloznacznych jak „*.wikipedia.org”.
 Wymaga podania co najmniej domeny najwyższego poziomu np. „*.org”.<br />
-Obsługiwane protokoły: <code>$1</code> (jeśli nie podano, domyślny to http://).',
+{{PLURAL:$2|Obsługiwany protokół|Obsługiwane protokoły}}: <code>$1</code> (jeśli nie podano, domyślny to http://).',
 'linksearch-line' => '$1 link na stronie $2',
 'linksearch-error' => 'Symbolu wieloznacznego można użyć wyłącznie na początku nazwy hosta.',
 
@@ -2337,7 +2339,7 @@ Każda zmiana treści tej strony lub związanej z nią strony dyskusji zostanie
 'notanarticle' => 'To nie jest artykuł',
 'notvisiblerev' => 'Wersja została usunięta',
 'watchnochange' => 'Żadna z obserwowanych stron nie była edytowana w podanym okresie.',
-'watchlist-details' => 'Na liście obserwowanych {{PLURAL:$1|jest 1 strona|są $1 strony|jest $1 stron}}, nie licząc stron dyskusji.',
+'watchlist-details' => 'Lista obserwowanych przez Ciebie stron zawiera {{PLURAL:$1|$1 pozycję|$1 pozycje|$1 pozycji}}, nie licząc stron dyskusji.',
 'wlheader-enotif' => '* Wysyłanie powiadomień na adres e‐mail jest włączone.',
 'wlheader-showupdated' => "* '''Wytłuszczone''' zostały strony, które zostały zmodyfikowane od Twojej ostatniej na nich wizyty.",
 'watchmethod-recent' => 'poszukiwanie ostatnich zmian wśród obserwowanych stron',
@@ -2361,7 +2363,7 @@ Każda zmiana treści tej strony lub związanej z nią strony dyskusji zostanie
 'enotif_subject_moved' => 'Strona projektu {{SITENAME}} o nazwie $1 została przeniesiona przez {{gender:$2|$2}}',
 'enotif_subject_restored' => 'Strona projektu {{SITENAME}} o nazwie $1 została przywrócona przez {{gender:$2|$2}}',
 'enotif_subject_changed' => 'Strona projektu {{SITENAME}} o nazwie $1 została zmieniona przez {{gender:$2|$2}}',
-'enotif_body_intro_deleted' => 'Strona projektu {{SITENAME}} o nazwie $1 została usunięta $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
+'enotif_body_intro_deleted' => 'Strona projektu {{SITENAME}} o nazwie $1 została usunięta $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz: $3',
 'enotif_body_intro_created' => 'Strona projektu {{SITENAME}} o nazwie $1 została stworzona $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
 'enotif_body_intro_moved' => 'Strona projektu {{SITENAME}} o nazwie $1 została przeniesiona $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
 'enotif_body_intro_restored' => 'Strona projektu {{SITENAME}} o nazwie $1 została przywrócona $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
@@ -2456,8 +2458,8 @@ Naciśnij „wstecz” w przeglądarce, przeładuj stronę, po czym ponownie wyd
 'protectlogpage' => 'Zabezpieczone',
 'protectlogtext' => 'Poniżej znajduje się lista zmian w zabezpieczeniu pojedynczych stron.
 Wszystkie aktywne zabezpieczenia odnajdziesz na liście [[Special:ProtectedPages|zabezpieczonych stron]].',
-'protectedarticle' => 'zabezpieczył [[$1]]',
-'modifiedarticleprotection' => 'zmienił poziom zabezpieczenia [[$1]]',
+'protectedarticle' => '{{GENDER:$2|zabezpieczył|zabezpieczyła}} [[$1]]',
+'modifiedarticleprotection' => '{{GENDER:$2|zmienił|zmieniła}} poziom zabezpieczenia [[$1]]',
 'unprotectedarticle' => 'odbezpieczył [[$1]]',
 'movedarticleprotection' => 'przeniósł ustawienia zabezpieczeń z [[$2]] do [[$1]]',
 'protect-title' => 'Zmiana poziomu zabezpieczenia „$1”',
@@ -2465,6 +2467,7 @@ Wszystkie aktywne zabezpieczenia odnajdziesz na liście [[Special:ProtectedPages
 'prot_1movedto2' => 'stronę [[$1]] przeniósł do [[$2]]',
 'protect-badnamespace-title' => 'Przestrzeń nazw, w której nie można zabezpieczać stron',
 'protect-badnamespace-text' => 'Stron w tej przestrzeni nazw nie można zabezpieczać.',
+'protect-norestrictiontypes-text' => 'Ta strona nie może być chroniona, gdyż nie ma dla niej żadnych dostępnych typów ograniczeń.',
 'protect-norestrictiontypes-title' => 'Nieblokowalna strona',
 'protect-legend' => 'Potwierdź zabezpieczenie',
 'protectcomment' => 'Powód',
@@ -2481,7 +2484,7 @@ Obecne ustawienia dla strony '''$1''' to:",
 'protect-default' => 'Dostęp mają wszyscy użytkownicy',
 'protect-fallback' => 'Wymaga uprawnień „$1”',
 'protect-level-autoconfirmed' => 'Blokuj nowych i niezarejestrowanych użytkowników',
-'protect-level-sysop' => 'Dostęp mają tylko administratorzy',
+'protect-level-sysop' => 'Dozwolone tylko dla administratorów',
 'protect-summary-cascade' => 'dziedziczenie',
 'protect-expiring' => 'wygasa $1 (UTC)',
 'protect-expiring-local' => 'wygasa $1',
@@ -2716,12 +2719,12 @@ Przyczyna blokady $1 to: „$2”',
 'blocklogpage' => 'Historia blokad',
 'blocklog-showlog' => '{{GENDER:$1|Ten użytkownik był|Ta użytkowniczka była}} już wcześniej {{GENDER:$1|blokowany|blokowana}}. Poniżej znajduje się rejestr blokad:',
 'blocklog-showsuppresslog' => '{{GENDER:$1|Ten użytkownik był|Ta użytkowniczka była}} już wcześniej {{GENDER:$1|blokowany oraz ukrywany|blokowana oraz ukrywana}}. Poniżej znajduje się rejestr ukrywania:',
-'blocklogentry' => 'blokuje [[$1]], czas blokady: $2 $3',
-'reblock-logentry' => 'zmienia ustawienia blokady dla [[$1]], czas blokady: $2 $3',
+'blocklogentry' => 'zablokował(a) [[$1]], czas blokady: $2 $3',
+'reblock-logentry' => '{{GENDER:$2|zmienił|zmieniła}} ustawienia blokady dla [[$1]], czas blokady: $2 $3',
 'blocklogtext' => 'Poniżej znajduje się lista blokad założonych i zdjętych z poszczególnych adresów IP.
 Na liście nie znajdą się adresy IP, które zablokowano w sposób automatyczny.
 By przejrzeć listę obecnie aktywnych blokad, przejdź na stronę [[Special:BlockList|zablokowanych adresów i użytkowników]].',
-'unblocklogentry' => 'zdejmuje blokadę $1',
+'unblocklogentry' => '{{GENDER:$2|zdjął|zdjęła}} blokadę $1',
 'block-log-flags-anononly' => 'tylko anonimowi',
 'block-log-flags-nocreate' => 'blokada tworzenia konta',
 'block-log-flags-noautoblock' => 'automatyczne blokowanie wyłączone',
@@ -2784,7 +2787,7 @@ Blokowanie i odblokowywanie bazy danych, wymaga by plik mógł być zapisywany p
 Pod starym tytułem zostanie umieszczona strona przekierowująca.
 Możesz automatycznie zaktualizować przekierowania wskazujące na tytuł przed zmianą.
 Jeśli nie wybierzesz tej opcji, upewnij się po przeniesieniu strony, czy nie powstały [[Special:DoubleRedirects|podwójne]] lub [[Special:BrokenRedirects|zerwane przekierowania]].
-Jesteś odpowiedzialny za to, by linki w dalszym ciągu pokazywały tam, gdzie powinny.
+Jesteś odpowiedzialny za to, by linki w dalszym ciągu prowadziły tam, gdzie powinny.
 
 Strona '''nie''' zostanie przeniesiona, jeśli strona o nowej nazwie już istnieje, chyba że jest pusta lub jest przekierowaniem i ma pustą historię edycji.
 To oznacza, że błędną operację zmiany nazwy można bezpiecznie odwrócić, zmieniając nową nazwę strony na poprzednią, i że nie można nadpisać istniejącej strony.
@@ -2977,9 +2980,9 @@ Brak katalogu dla plików tymczasowych.',
 # Import log
 'importlogpage' => 'Rejestr importu',
 'importlogpagetext' => 'Rejestr przeprowadzonych importów stron z innych serwisów wiki.',
-'import-logentry-upload' => 'importuje [[$1]] przez przesłanie pliku',
+'import-logentry-upload' => '{{GENDER:$2|zaimportował|zaimportowała}} [[$1]] przez przesłanie pliku',
 'import-logentry-upload-detail' => '$1 {{PLURAL:$1|wersja|wersje|wersji}}',
-'import-logentry-interwiki' => 'importuje $1 używając transwiki',
+'import-logentry-interwiki' => '{{GENDER:$2|zaimportował|zaimportowała}} $1 używając transwiki',
 'import-logentry-interwiki-detail' => '$1 {{PLURAL:$1|wersja|wersje|wersji}} z $2',
 
 # JavaScriptTest
@@ -3147,6 +3150,7 @@ Najprawdopodobniej zostało to spowodowane przez link do zewnętrznej strony int
 'pageinfo-magic-words' => 'Magiczne {{PLURAL:$1|słowo|słowa|słowa}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Ukryta kategoria|Ukryte kategorie|Ukryte kategorie}} ($1)',
 'pageinfo-templates' => 'Wykorzystywan{{PLURAL:$1|y szablon|e szablony}} ($1)',
+'pageinfo-transclusions' => 'Dołączona na {{PLURAL:$1|stronie|stronach}} ($1)',
 'pageinfo-toolboxlink' => 'Informacje o tej stronie',
 'pageinfo-redirectsto' => 'Przekierowuje na',
 'pageinfo-redirectsto-info' => 'informacje',
@@ -3155,6 +3159,10 @@ Najprawdopodobniej zostało to spowodowane przez link do zewnętrznej strony int
 'pageinfo-protect-cascading' => 'Zabezpieczona z włączoną opcją dziedziczenia',
 'pageinfo-protect-cascading-yes' => 'Tak',
 'pageinfo-protect-cascading-from' => 'Zabezpieczenie dziedziczone z',
+'pageinfo-category-info' => 'Informacje o kategorii',
+'pageinfo-category-pages' => 'Liczba stron',
+'pageinfo-category-subcats' => 'Liczba podkategorii',
+'pageinfo-category-files' => 'Liczba plików',
 
 # Skin names
 'skinname-standard' => 'Standardowa',
@@ -3245,6 +3253,8 @@ Jeśli go otworzysz, możesz zarazić swój system.",
 'minutes' => '{{PLURAL:$1|$1 minuta|$1 minuty|$1 minut}}',
 'hours' => '{{PLURAL:$1|$1 godzina|$1 godziny|$1 godzin}}',
 'days' => '{{PLURAL:$1|$1 dzień|$1 dni}}',
+'months' => '{{PLURAL:$1|$1 miesiąc|$1 miesiące|$1 miesięcy}}',
+'years' => '{{PLURAL:$1|$1 rok|$1 lata|$1 lat}}',
 'ago' => '$1 temu',
 'just-now' => 'przed chwilą',
 
@@ -3957,7 +3967,7 @@ Grafiki są pokazywane w pełnej rozdzielczości. Inne typy plików są otwieran
 'specialpages-group-highuse' => 'Strony często używane',
 'specialpages-group-pages' => 'Zestawienia stron',
 'specialpages-group-pagetools' => 'Narzędzia stron',
-'specialpages-group-wiki' => 'Informacje oraz narzędzia wiki',
+'specialpages-group-wiki' => 'Informacje i narzędzia',
 'specialpages-group-redirects' => 'Specjalne strony przekierowujące',
 'specialpages-group-spam' => 'Narzędzia do walki ze spamem',
 
@@ -4030,7 +4040,7 @@ Grafiki są pokazywane w pełnej rozdzielczości. Inne typy plików są otwieran
 'logentry-delete-restore' => '$1 {{GENDER:$2|odtworzył|odtworzyła}} stronę $3',
 'logentry-delete-event' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność {{PLURAL:$5|zdarzenia|$5 zdarzeń}} w rejestrze $3, wykonano następujące operacje: $4',
 'logentry-delete-revision' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność {{PLURAL:$5|wersji|$5 wersji}} strony $3, wykonano następujące operacje: $4',
-'logentry-delete-event-legacy' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność zdarzeń w rejestrze $3',
+'logentry-delete-event-legacy' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność zdarzeń w rejestrze strony $3',
 'logentry-delete-revision-legacy' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność wersji strony $3',
 'logentry-suppress-delete' => '$1 ukrywa stronę $3',
 'logentry-suppress-event' => '$1 potajemnie zmienia widoczność {{PLURAL:$5|zdarzenia|$5 zdarzeń}} w $3, wykonano następujące operacje: $4',
@@ -4049,13 +4059,13 @@ Grafiki są pokazywane w pełnej rozdzielczości. Inne typy plików są otwieran
 'logentry-move-move-noredirect' => '$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 na $4, bez pozostawienia przekierowania pod starym tytułem',
 'logentry-move-move_redir' => '$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 na $4 w miejsce przekierowania',
 'logentry-move-move_redir-noredirect' => '$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 na $4 w miejsce przekierowania i bez pozostawienia przekierowania pod starym tytułem',
-'logentry-patrol-patrol' => '$1 {{GENDER:$2|odznaczył|odznaczyła}} wersję $4 strony $3 jako sprawdzoną',
-'logentry-patrol-patrol-auto' => '$1 automatycznie {{GENDER:$2|odznaczył|odznaczyła}} wersję $4 strony $3 jako sprawdzoną',
+'logentry-patrol-patrol' => '$1 {{GENDER:$2|oznaczył|oznaczyła}} wersję $4 strony $3 jako sprawdzoną',
+'logentry-patrol-patrol-auto' => '$1 automatycznie {{GENDER:$2|oznaczył|oznaczyła}} wersję $4 strony $3 jako sprawdzoną',
 'logentry-newusers-newusers' => 'Konto użytkownika $1 zostało utworzone',
 'logentry-newusers-create' => 'Konto użytkownika $1 zostało utworzone',
 'logentry-newusers-create2' => 'Konto użytkownika $3 zostało utworzone przez użytkownika $1',
+'logentry-newusers-byemail' => 'Konto $3 zostało utworzone przez użytkownika $1, hasło wysłano e-mailem',
 'logentry-newusers-autocreate' => '$1 automatycznie tworzy konto użytkownika',
-'newuserlog-byemail' => 'hasło zostało wysłane e‐mailem',
 'logentry-rights-rights' => '$1 {{GENDER:$2|zmienił|zmieniła}} przynależność $3 do grup ($4 → $5)',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$2|zmienił|zmieniła}} przynależność $3 do grup',
 'logentry-rights-autopromote' => '$1 automatycznie {{GENDER:$2|zmienił|zmieniła}} przynależność ($4 → $5)',
@@ -4113,6 +4123,7 @@ W przeciwnym wypadku można użyć prostego formularza poniżej. Komentarz zosta
 'api-error-ok-but-empty' => 'Błąd wewnętrzny – brak odpowiedzi od serwera.',
 'api-error-overwrite' => 'Nadpisanie istniejącego pliku nie jest dopuszczalne.',
 'api-error-stashfailed' => 'Błąd wewnętrzny – serwer nie mógł zapisać pliku tymczasowego.',
+'api-error-publishfailed' => 'Błąd wewnętrzny: serwer nie mógł zapisać pliku tymczasowego.',
 'api-error-timeout' => 'Serwer nie odpowiedział w oczekiwanym czasie.',
 'api-error-unclassified' => 'Wystąpił nieznany błąd',
 'api-error-unknown-code' => 'Błąd nieznany – „$1”',
index b5bf0aa..b99fecd 100644 (file)
@@ -1973,7 +1973,7 @@ Ch'a bèica ëdcò [[Special:WantedCategories|le categorìe domandà]].",
 'linksearch-ok' => 'Sërché',
 'linksearch-text' => 'As peulo dovresse dij ciapatut com "*.wikipedia.org".
 A-i é dabzògn almanch d\'un domini a livel pi àut, për esempi "*.org".<br />
-{{PLURAL:$2|Protocòl|Protocòj}} ch\'as peulo dovresse: <code>$1</code> (predefinì http:// se gnun protocòj a son specificà).',
+{{PLURAL:$2|Protocòl|Protocòj}} ch\'as peulo dovresse: <code>$1</code> (predefinì http:// se gnun protocòl a l\'é specificà).',
 'linksearch-line' => "$1 a l'ha n'anliura ch'a-j riva dzora da $2",
 'linksearch-error' => 'Ij ciapatut as peulo butesse mach an prinsipi dël nòm dël sërvent.',
 
@@ -2050,7 +2050,7 @@ L'adrëssa ëd pòsta eletrònica ch'a l'ha butà ant ij [[Special:Preferences|s
 'usermessage-editor' => 'Mëssagerìa ëd sistema',
 
 # Watchlist
-'watchlist' => 'Ròba che im ten-o sot-euj',
+'watchlist' => 'Ròba che as ten sot euj',
 'mywatchlist' => 'Ròba che as ten sot euj',
 'watchlistfor2' => 'Për $1 $2',
 'nowatchlist' => "A l'ha ancó pa marcà dj'artìcoj coma ròba da tnì sot-euj.",
@@ -3739,7 +3739,6 @@ Le figure a së smon-o a amzura pijn-a, j'àotre sòrt d'archivi a ven-o fàite
 'logentry-newusers-create' => "Ël cont utent $1 a l'é stàit creà",
 'logentry-newusers-create2' => "Ël cont utent $3 a l'é stàit creà da $1",
 'logentry-newusers-autocreate' => "Ël cont $1 a l'é stàit creà an automàtich",
-'newuserlog-byemail' => 'ciav spedìa për pòsta eletrònica',
 'logentry-rights-rights' => "$1 a l'ha tramudà l'apartenesa a la partìa për $3 da $4 a $5",
 'logentry-rights-rights-legacy' => "$1 a l'ha tramudà l'apartenensa a la partìa për $3",
 'logentry-rights-autopromote' => "$1 a l'é stàit automaticament promovù da $4 a $5",
index 5ed26d0..8e0e7c1 100644 (file)
@@ -3531,7 +3531,6 @@ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 'logentry-newusers-create' => '$1 {{جنس:$2|بنایا}} اک ورتن والا کھاتہ',
 'logentry-newusers-create2' => '$1 {{جنس:$2|بنایا}} {{جنس:$4|اک ورتن کھاتہ}} $3',
 'logentry-newusers-autocreate' => 'کھاتہ $1 اپنے آپ ای {{جنس:$2|بنایا گیا}} بنایا گیا۔',
-'newuserlog-byemail' => 'کنجی ای-میل راہ پیج دتی گئی۔',
 'rightsnone' => '(کوئی وی نئیں)',
 
 # Feedback
index e81e4fa..3819ced 100644 (file)
@@ -2707,7 +2707,6 @@ Enpeisāis zūrbrukes pabilīsnan šlāit "{{ns:file}}:" prefiksan.',
 # New logging system
 'revdelete-restricted' => 'ensadinnais arāikinsenins per perwaldītajans',
 'revdelete-unrestricted' => 'āupausinais arāikinsenins per perwaldītajans',
-'newuserlog-byemail' => 'kliptaswīrds tengīntan pra e-mail',
 'rightsnone' => '(nisātausna)',
 
 );
index 33ab6f8..3b701cd 100644 (file)
@@ -308,7 +308,7 @@ $messages = array(
 'vector-action-addsection' => 'سرليکونه ورګډول',
 'vector-action-delete' => 'ړنګول',
 'vector-action-move' => 'لېږدول',
-'vector-action-protect' => 'پروژه',
+'vector-action-protect' => 'ژغورل',
 'vector-action-undelete' => 'ناړنګول',
 'vector-action-unprotect' => 'ژغورنه بدلول',
 'vector-view-create' => 'جوړول',
@@ -553,7 +553,7 @@ $1',
 'gotaccount' => 'آيا وار دمخې يو ګڼون لری؟ $1.',
 'gotaccountlink' => 'ننوتل',
 'userlogin-resetlink' => 'د ننوتلو مالومات مو هېر شوي؟',
-'createaccountmail' => 'د برېښليک له مخې',
+'createaccountmail' => 'يو لنډمهاله ناټاکلی پټنوم کارول او په لاندې ورکړل شوې برېښليک پته کې ورلېږل',
 'createaccountreason' => 'سبب:',
 'badretype' => 'دا پټنوم چې تاسې ليکلی د مخکني پټنوم سره ورته نه دی.',
 'userexists' => 'کوم کارن نوم چې تاسې ورکړی هغه بل چا کارولی.
@@ -2675,7 +2675,6 @@ $5
 'logentry-newusers-newusers' => 'د $1 کارن ګڼون جوړ شو',
 'logentry-newusers-create' => 'د $1 کارن ګڼون جوړ شو',
 'logentry-newusers-autocreate' => 'د $1 ګڼون په اتوماتيک ډول جوړ شو',
-'newuserlog-byemail' => 'پټنوم مو برېښليک ته درولېږه',
 'rightsnone' => '(هېڅ)',
 
 # Feedback
index 98d541b..93cca94 100644 (file)
@@ -12,6 +12,7 @@
  * @author Capmo
  * @author Crazymadlover
  * @author Daemorris
+ * @author Dicionarista
  * @author Francisco Leandro
  * @author Giro720
  * @author GoEThe
@@ -155,6 +156,7 @@ $specialPageAliases = array(
        'Mytalk'                    => array( 'Minha_discussão' ),
        'Newimages'                 => array( 'Ficheiros_novos', 'Imagens_novas', 'Arquivos_novos' ),
        'Newpages'                  => array( 'Páginas_novas', 'Artigos_novos' ),
+       'PermanentLink'             => array( 'Ligação_permanente', 'Link_permanente' ),
        'Popularpages'              => array( 'Páginas_populares', 'Artigos_populares' ),
        'Preferences'               => array( 'Preferências' ),
        'Prefixindex'               => array( 'Índice_por_prefixo', 'Índice_de_prefixo' ),
@@ -310,7 +312,7 @@ $magicWords = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Sublinhar links:',
+'tog-underline' => 'Sublinhar ligação:',
 'tog-justify' => 'Justificar parágrafos',
 'tog-hideminor' => 'Esconder edições menores nas mudanças recentes',
 'tog-hidepatrolled' => 'Esconder edições patrulhadas nas mudanças recentes',
@@ -368,12 +370,12 @@ $messages = array(
 'editfont-serif' => 'Fonte serifada',
 
 # Dates
-'sunday' => 'Domingo',
-'monday' => 'Segunda-feira',
-'tuesday' => 'Terça-feira',
-'wednesday' => 'Quarta-feira',
-'thursday' => 'Quinta-feira',
-'friday' => 'Sexta-feira',
+'sunday' => 'domingo',
+'monday' => 'segunda-feira',
+'tuesday' => 'terça-feira',
+'wednesday' => 'quarta-feira',
+'thursday' => 'quinta-feira',
+'friday' => 'sexta-feira',
 'saturday' => 'Sábado',
 'sun' => 'Dom',
 'mon' => 'Seg',
@@ -382,18 +384,18 @@ $messages = array(
 'thu' => 'Qui',
 'fri' => 'Sex',
 'sat' => 'Sáb',
-'january' => 'Janeiro',
-'february' => 'Fevereiro',
-'march' => 'Março',
-'april' => 'Abril',
+'january' => 'janeiro',
+'february' => 'fevereiro',
+'march' => 'março',
+'april' => 'abril',
 'may_long' => 'Maio',
-'june' => 'Junho',
-'july' => 'Julho',
-'august' => 'Agosto',
-'september' => 'Setembro',
-'october' => 'Outubro',
-'november' => 'Novembro',
-'december' => 'Dezembro',
+'june' => 'junho',
+'july' => 'julho',
+'august' => 'agosto',
+'september' => 'setembro',
+'october' => 'outubro',
+'november' => 'novembro',
+'december' => 'dezembro',
 'january-gen' => 'Janeiro',
 'february-gen' => 'Fevereiro',
 'march-gen' => 'Março',
@@ -410,7 +412,7 @@ $messages = array(
 'feb' => 'Fev.',
 'mar' => 'Mar.',
 'apr' => 'Abr.',
-'may' => 'Maio',
+'may' => 'maio',
 'jun' => 'Jun.',
 'jul' => 'Jul.',
 'aug' => 'Ago.',
@@ -526,7 +528,7 @@ $messages = array(
 'otherlanguages' => 'Noutras línguas',
 'redirectedfrom' => '(Redireccionado de $1)',
 'redirectpagesub' => 'Página de redireccionamento',
-'lastmodifiedat' => 'Esta página foi modificada pela última vez às $2 de $1.',
+'lastmodifiedat' => 'Esta página foi modificada pela última vez à(s) $2 de $1.',
 'viewcount' => 'Esta página foi acedida {{PLURAL:$1|uma vez|$1 vezes}}.',
 'protectedpage' => 'Página protegida',
 'jumpto' => 'Ir para:',
@@ -744,7 +746,7 @@ Não se esqueça de personalizar as suas [[Special:Preferences|preferências]].'
 'gotaccount' => "Já possui uma conta? '''$1'''.",
 'gotaccountlink' => 'Autentique-se',
 'userlogin-resetlink' => 'Esqueceu-se do seu nome de utilizador ou da palavra-chave?',
-'createaccountmail' => 'por correio electrónico',
+'createaccountmail' => 'Usar uma palavra passe aleatória e temporária e enviar para o endereço de e-mail especificado abaixo',
 'createaccountreason' => 'Motivo:',
 'badretype' => 'As palavras-chave que introduziu não são iguais.',
 'userexists' => 'O nome de utilizador introduzido já existe.
@@ -1359,7 +1361,7 @@ Os detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{F
 'search-interwiki-default' => 'Resultados de $1:',
 'search-interwiki-more' => '(mais)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Desactivar sugestões AJAX',
+'mwsuggest-disable' => 'Desactivar sugestões de pesquisa',
 'searcheverything-enable' => 'Pesquisar em todos os espaços nominais',
 'searchrelated' => 'relacionados',
 'searchall' => 'todos',
@@ -1405,7 +1407,7 @@ Note, no entanto, que a indexação da {{SITENAME}} neste motor de busca pode es
 'prefs-datetime' => 'Data e hora',
 'prefs-labs' => 'Funcionalidades dos laboratórios',
 'prefs-user-pages' => 'Páginas de utilizador',
-'prefs-personal' => 'Perfil de utilizador',
+'prefs-personal' => 'Dados do utilizador',
 'prefs-rc' => 'Mudanças recentes',
 'prefs-watchlist' => 'Páginas vigiadas',
 'prefs-watchlist-days' => 'Dias a mostrar nas mudanças às páginas vigiadas:',
@@ -1654,7 +1656,7 @@ Esta informação será pública.',
 'action-suppressionlog' => 'ver este registo privado',
 'action-block' => 'impedir este utilizador de editar',
 'action-protect' => 'alterar os níveis de protecção desta página',
-'action-rollback' => 'Reverter rapidamente as edições do último utilizador que editou uma dada página',
+'action-rollback' => 'reverter rapidamente as edições do último utilizador que editou uma dada página',
 'action-import' => 'importar esta página a partir de outra wiki',
 'action-importupload' => 'importar esta página a partir de um ficheiro xml',
 'action-patrol' => 'marcar as edições de outros utilizadores como patrulhadas',
@@ -1687,7 +1689,7 @@ Esta informação será pública.',
 'rcshowhidemine' => '$1 as minhas edições',
 'rclinks' => 'Mostrar as últimas $1 mudanças nos últimos $2 dias<br />$3',
 'diff' => 'dif',
-'hist' => 'hist',
+'hist' => 'his',
 'hide' => 'Esconder',
 'show' => 'Mostrar',
 'minoreditletter' => 'm',
@@ -1707,7 +1709,7 @@ Esta informação será pública.',
 'recentchangeslinked-feed' => 'Alterações relacionadas',
 'recentchangeslinked-toolbox' => 'Alterações relacionadas',
 'recentchangeslinked-title' => 'Alterações relacionadas com "$1"',
-'recentchangeslinked-noresult' => 'Não ocorreram alterações em páginas para as quais a página fornecida contém links, no intervalo de tempo escolhido.',
+'recentchangeslinked-noresult' => 'Nenhuma mudança nas páginas relacionadas durante o período.',
 'recentchangeslinked-summary' => "Lista das mudanças recentes a todas as páginas para as quais a página fornecida contém links (ou de todas as que pertencem à categoria fornecida).
 As suas [[Special:Watchlist|páginas vigiadas]] aparecem a '''negrito'''.",
 'recentchangeslinked-page' => 'Nome da página:',
@@ -2134,7 +2136,7 @@ Agora redirecciona para [[$2]].',
 'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
 'ncategories' => '$1 {{PLURAL:$1|categoria|categorias}}',
 'ninterwikis' => '$1 {{PLURAL:$1|interwiki|interwikis}}',
-'nlinks' => '$1 {{PLURAL:$1|link|links}}',
+'nlinks' => '$1 {{PLURAL:$1|ligação|ligações}}',
 'nmembers' => '$1 {{PLURAL:$1|membro|membros}}',
 'nrevisions' => '$1 {{PLURAL:$1|edição|edições}}',
 'nviews' => '$1 {{PLURAL:$1|visita|visitas}}',
@@ -2201,8 +2203,8 @@ No entanto, outros sites na internet podem ter links para um ficheiro através d
 'querypage-disabled' => 'Esta página especial está desactivada para não prejudicar o desempenho.',
 
 # Book sources
-'booksources' => 'Fontes de livros',
-'booksources-search-legend' => 'Procurar fontes de livros',
+'booksources' => 'Fontes bibliográficas',
+'booksources-search-legend' => 'Pesquisar referências bibliográficas',
 'booksources-go' => 'Prosseguir',
 'booksources-text' => 'É apresentada abaixo uma lista de links para outros sites 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.',
@@ -2230,7 +2232,7 @@ Pode reduzir a lista escolhendo um tipo de registo, um nome de utilizador ou um
 'allnotinnamespace' => 'Todas as páginas (excepto as do espaço nominal $1)',
 'allpagesprev' => 'Anterior',
 'allpagesnext' => 'Próximo',
-'allpagessubmit' => 'Prosseguir',
+'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.
 Talvez contenha um ou mais caracteres que não podem ser usados nos títulos.',
@@ -2261,9 +2263,9 @@ Veja também as [[Special:WantedCategories|categorias desejadas]].',
 'linksearch-pat' => 'Padrão de busca:',
 'linksearch-ns' => 'Espaço nominal:',
 'linksearch-ok' => 'Prosseguir',
-'linksearch-text' => 'É possível usar caracteres de substituição \'\'(wildcards)\'\', como por exemplo: "*.wikipedia.org".
+'linksearch-text' => 'É possível usar caracteres de substituição \'\'(wildcards)\'\', tais como "*.wikipedia.org".
 É necessário, pelo menos, um domínio de topo, por exemplo "*.org".<br />
-Protocolos suportados: <code>$1</code> (não adicione nenhum destes na sua pesquisa).',
+{{PLURAL:$2|Protocolo suportado|Protocolos suportados}}: <code>$1</code> (será utilizado http:// se não for especificado um protocolo).',
 'linksearch-line' => 'Link para $1 na página $2',
 'linksearch-error' => "Caracteres de substituição ''(wildcards)'' só podem ser usados no início do endereço.",
 
@@ -2276,7 +2278,7 @@ Protocolos suportados: <code>$1</code> (não adicione nenhum destes na sua pesqu
 # Special:ActiveUsers
 'activeusers' => 'Utilizadores activos',
 'activeusers-intro' => 'Esta é uma lista dos utilizadores com qualquer tipo de actividade {{PLURAL:$1|no último dia|nos últimos $1 dias}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|edição recente|edições recentes}} {{PLURAL:$3|no último dia|nos últimos $3 dias}}',
+'activeusers-count' => '$1 {{PLURAL:$1|ação|ações}} {{PLURAL:$3|no último dia|nos últimos $3 dias}}',
 'activeusers-from' => 'Mostrar utilizadores começando por:',
 'activeusers-hidebots' => 'Esconder robôs',
 'activeusers-hidesysops' => 'Esconder administradores',
@@ -2496,13 +2498,13 @@ Esta é a configuração actual da página '''$1''':",
 'protect-cascadeon' => 'Esta página está protegida porque se encontra incluída {{PLURAL:$1|na página listada a seguir, protegida|nas páginas listadas a seguir, protegidas}} com protecção em cascata.
 Pode alterar o nível de protecção desta página, mas isso não afectará a protecção em cascata.',
 'protect-default' => 'Permitir todos os utilizadores',
-'protect-fallback' => 'É necessário o privilégio de "$1"',
-'protect-level-autoconfirmed' => 'Bloquear utilizadores novos e não registados',
-'protect-level-sysop' => 'Apenas administradores',
+'protect-fallback' => 'Permitir apenas utilizadores com o privilégio de "$1"',
+'protect-level-autoconfirmed' => 'Permitir apenas utilizadores auto-confirmados',
+'protect-level-sysop' => 'Permitir apenas administradores',
 'protect-summary-cascade' => 'em cascata',
 'protect-expiring' => 'expira a $1 (UTC)',
 'protect-expiring-local' => 'expira a $1',
-'protect-expiry-indefinite' => 'tempo indefinido',
+'protect-expiry-indefinite' => 'indefinidamente',
 'protect-cascade' => 'Proteja quaisquer páginas que estejam incluídas nesta (protecção em cascata)',
 'protect-cantedit' => 'Não pode alterar o nível de protecção desta página, porque não tem permissão para editá-la.',
 'protect-othertime' => 'Outra duração:',
@@ -2626,7 +2628,7 @@ Para referência é apresentado abaixo o último registo de bloqueio:',
 'whatlinkshere-title' => 'Páginas que têm links para "$1"',
 'whatlinkshere-page' => 'Página:',
 'linkshere' => "As seguintes páginas têm links para '''[[:$1]]''':",
-'nolinkshere' => "Não existem links para '''[[:$1]]'''.",
+'nolinkshere' => "Não existem afluentes para '''[[:$1]]''' com as condições especificadas.",
 'nolinkshere-ns' => "Não existem links para '''[[:$1]]''' no espaço nominal seleccionado.",
 'isredirect' => 'página de redireccionamento',
 'istemplate' => 'inclusão',
@@ -2883,7 +2885,7 @@ O último registo é apresentado abaixo para referência:",
 Escolha outro nome, por favor.',
 
 # Export
-'export' => 'Exportação de páginas',
+'export' => 'Exportar páginas',
 'exporttext' => 'Pode exportar o texto e o histórico de edições de uma página em particular para um ficheiro XML. Poderá então importar esse conteúdo noutra wiki que utilize o programa MediaWiki, através da [[Special:Import|página de importações]].
 
 Para exportar páginas, introduza os títulos na caixa de texto abaixo (um título por linha) e seleccione se deseja todas as versões, com as linhas de histórico de edições, ou apenas a edição actual e informações sobre a mais recente das edições.
@@ -3104,7 +3106,7 @@ Permite colocar uma justificação no resumo da edição.',
 'anonymous' => '{{PLURAL:$1|Utilizador anónimo|Utilizadores anónimos}} da {{SITENAME}}',
 'siteuser' => '$1 da {{SITENAME}}',
 'anonuser' => 'utilizador anónimo $1 da {{SITENAME}}',
-'lastmodifiedatby' => 'Esta página foi modificada pela última vez às $2 de $1 por $3.',
+'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)',
@@ -3138,7 +3140,7 @@ Este bloqueio foi provavelmente causado por um link para um site externo que con
 'pageinfo-robot-noindex' => 'Não indexável',
 'pageinfo-views' => 'Número de visitas',
 'pageinfo-watchers' => 'Número de vigilantes da página',
-'pageinfo-redirects-name' => 'Redireciona para esta página',
+'pageinfo-redirects-name' => 'Redirecionamentos para esta página',
 'pageinfo-subpages-name' => 'Subpáginas desta página',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecionamento|redirecionamentos}}; $3 {{PLURAL:$3|não-redirecionamento|não-redirecionamentos}})',
 'pageinfo-firstuser' => 'Criador da página',
@@ -3157,6 +3159,10 @@ Este bloqueio foi provavelmente causado por um link para um site externo que con
 'pageinfo-contentpage' => 'Contada como página de conteúdo',
 'pageinfo-contentpage-yes' => 'Sim',
 'pageinfo-protect-cascading-yes' => 'Sim',
+'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',
 
 # Skin names
 'skinname-standard' => 'Clássico',
@@ -3977,7 +3983,7 @@ Imagens serão apresentadas pelo browser na resolução máxima; ficheiros de ou
 'logentry-delete-delete' => '$1 apagou a página $3',
 'logentry-delete-restore' => '$1 restaurou a página $3',
 'logentry-delete-event' => '$1 alterou a visibilidade {{PLURAL:$5|de uma entrada|das $5 entradas}} em $3: $4',
-'logentry-delete-revision' => '$1 alterou a visibilidade {{PLURAL:$5|de uma revisão|das $5 revisões}} em $3: $4',
+'logentry-delete-revision' => '$1 alterou a visibilidade de {{PLURAL:$5|uma revisão|$5 revisões}} em $3: $4',
 'logentry-delete-event-legacy' => '$1 alterou a visibilidade de uma entrada em $3',
 'logentry-delete-revision-legacy' => '$1 alterou a visibilidade de uma revisão em $3',
 'logentry-suppress-delete' => '$1 suprimiu a página $3',
@@ -3988,9 +3994,9 @@ Imagens serão apresentadas pelo browser na resolução máxima; ficheiros de ou
 'revdelete-content-hid' => 'conteúdo oculto',
 'revdelete-summary-hid' => 'sumário de edição oculto',
 'revdelete-uname-hid' => 'utilizador oculto',
-'revdelete-content-unhid' => 'conteúdo não oculto',
-'revdelete-summary-unhid' => 'sumário de edição não oculto',
-'revdelete-uname-unhid' => 'utilizador não oculto',
+'revdelete-content-unhid' => 'conteúdo desocultado',
+'revdelete-summary-unhid' => 'sumário de edição desocultado',
+'revdelete-uname-unhid' => 'utilizador desocultado',
 'revdelete-restricted' => 'restrições a administradores aplicadas',
 'revdelete-unrestricted' => 'restrições a administradores removidas',
 'logentry-move-move' => '$1 moveu a página $3 para $4',
@@ -4003,8 +4009,8 @@ Imagens serão apresentadas pelo browser na resolução máxima; ficheiros de ou
 'logentry-newusers-create' => 'A conta de utilizador $1 foi criada',
 'logentry-newusers-create2' => 'A conta de utilizador $3 foi criada por $1',
 'logentry-newusers-autocreate' => 'A conta $1 foi criada automaticamente',
-'newuserlog-byemail' => 'palavra-chave enviada por correio-electrónico',
 'logentry-rights-rights' => '$1 modificou os privilégios do utilizador  $3  de  $4  para $5',
+'logentry-rights-autopromote' => '$1 foi automaticamente {{GENDER:$2|promovido|promovida}} de $4 a $5',
 'rightsnone' => '(nenhum)',
 
 # Feedback
index 2f5af33..4af987f 100644 (file)
@@ -19,6 +19,7 @@
  * @author Crazymadlover
  * @author Daemorris
  * @author Danielsouzat
+ * @author Dicionarista
  * @author Diego Queiroz
  * @author Eduardo.mps
  * @author Emufarmers
@@ -158,6 +159,7 @@ $specialPageAliases = array(
        'Mytalk'                    => array( 'Minha_discussão' ),
        'Newimages'                 => array( 'Arquivos_novos', 'Imagens_novas', 'Ficheiros_novos' ),
        'Newpages'                  => array( 'Páginas_novas', 'Artigos_novos' ),
+       'PermanentLink'             => array( 'Ligação_permanente', 'Link_permanente' ),
        'Popularpages'              => array( 'Páginas_populares', 'Artigos_populares' ),
        'Preferences'               => array( 'Preferências' ),
        'Prefixindex'               => array( 'Índice_de_prefixo', 'Índice_por_prefixo' ),
@@ -314,7 +316,7 @@ $magicWords = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Sublinhar links:',
+'tog-underline' => 'Sublinhar linques:',
 'tog-justify' => 'Justificar parágrafos',
 'tog-hideminor' => 'Ocultar edições menores nas mudanças recentes',
 'tog-hidepatrolled' => 'Ocultar edições patrulhadas nas mudanças recentes',
@@ -447,6 +449,7 @@ $messages = array(
 'newwindow' => '(abre em uma nova janela)',
 'cancel' => 'Cancelar',
 'moredotdotdot' => 'Mais...',
+'morenotlisted' => 'Outros não listados...',
 'mypage' => 'Página',
 'mytalk' => 'Discussão',
 'anontalk' => 'Discussão para este IP',
@@ -530,7 +533,7 @@ $messages = array(
 'otherlanguages' => 'Em outros idiomas',
 'redirectedfrom' => '(Redirecionado de $1)',
 'redirectpagesub' => 'Página de redirecionamento',
-'lastmodifiedat' => 'Esta página foi modificada pela última vez às $2 de $1.',
+'lastmodifiedat' => 'Esta página foi modificada pela última vez à(s) $2 de $1.',
 'viewcount' => 'Esta página foi acessada {{PLURAL:$1|uma vez|$1 vezes}}.',
 'protectedpage' => 'Página protegida',
 'jumpto' => 'Ir para:',
@@ -589,7 +592,7 @@ Veja a [[Special:Version|página sobre a versão do sistema]].',
 'editlink' => 'editar',
 'viewsourcelink' => 'ver código-fonte',
 'editsectionhint' => 'Editar seção: $1',
-'toc' => 'Conteúdo',
+'toc' => 'Índice',
 'showtoc' => 'exibir',
 'hidetoc' => 'ocultar',
 'collapsible-collapse' => 'Ocultar',
@@ -752,7 +755,7 @@ Não se esqueça de personalizar as suas [[Special:Preferences|preferências no
 'gotaccount' => "Já possui uma conta? '''$1'''.",
 'gotaccountlink' => 'Autenticar-se',
 'userlogin-resetlink' => 'Esqueceu-se do seu nome de usuário ou da senha?',
-'createaccountmail' => 'por e-mail',
+'createaccountmail' => 'Usar uma senha aleatória e temporária que será enviada ao endereço de e-mail especificado a seguir',
 'createaccountreason' => 'Razão:',
 'badretype' => 'As senhas que você digitou não são iguais.',
 'userexists' => 'O nome de usuário fornecido já está em uso.
@@ -823,6 +826,7 @@ Por favor aguarde antes de tentar novamente.',
 # E-mail sending
 'php-mail-error-unknown' => 'Erro desconhecido na função mail() do PHP',
 'user-mail-no-addy' => 'Tentou enviar uma mensagem sem um endereço de e-mail.',
+'user-mail-no-body' => 'Você tentou enviar com o campo de e-mail vazio ou com poucos caracteres.',
 
 # Change password dialog
 'resetpass' => 'Alterar senha',
@@ -1049,10 +1053,10 @@ Você está, ao mesmo tempo, a garantir-nos que isto é algo escrito por si, ou
 '''NÃO ENVIE TRABALHO PROTEGIDO POR DIREITOS DE AUTOR SEM A DEVIDA PERMISSÃO!'''",
 '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}}.'''
 A página não pode ser salva.",
-'readonlywarning' => "'''Aviso: A base de dados foi bloqueada para manutenção, por isso você não poderá salvar a sua edição neste momento.'''
-Pode, no entanto, copiar o seu texto num editor externo e guardá-lo para posterior envio.
+'readonlywarning' => "'''Aviso: O banco de dados foi bloqueado para manutenção, por isso você não poderá salvar a sua edição neste momento.'''
+Talvez você queira copiar o seu texto num editor externo e guardá-lo, para posterior envio.
 
-Quem bloqueou o banco de dados forneceu a seguinte justificativa: $1",
+Quem bloqueou o banco de dados forneceu a seguinte explicação: $1",
 'protectedpagewarning' => "'''Atenção: Esta página foi protegida para que apenas usuários com privilégios de administrador possam editá-la.'''
 A última entrada no histórico é fornecida abaixo como referência:",
 'semiprotectedpagewarning' => "'''Nota:''' Esta página foi protegida, sendo que apenas usuários registrados poderão editá-la.
@@ -1093,7 +1097,7 @@ Ela já existia.',
 'defaultmessagetext' => 'Texto da mensagem padrão',
 'content-failed-to-parse' => 'Falha ao analisar o conteúdo $2 para o modelo $1: $3',
 'invalid-content-data' => 'Dados de conteúdo inválidos',
-'content-not-allowed-here' => 'O conteúdo de tipo "$1" não é permitido na página [[$2]]',
+'content-not-allowed-here' => 'Conteúdo do tipo "$1" não é permitido na página [[$2]]',
 
 # Content models
 'content-model-wikitext' => 'wikitexto',
@@ -1224,13 +1228,13 @@ Outros administradores no {{SITENAME}} continuarão podendo acessar ao conteúdo
 'revdelete-hide-comment' => 'Ocultar o sumário de edição',
 'revdelete-hide-user' => 'Ocultar nome de usuário/IP do editor',
 'revdelete-hide-restricted' => 'Suprimir dados de administradores assim como de outros',
-'revdelete-radio-same' => '(não altere)',
+'revdelete-radio-same' => '(não alterar)',
 'revdelete-radio-set' => 'Sim',
 'revdelete-radio-unset' => 'Não',
 'revdelete-suppress' => 'Suprimir dados de administradores, bem como de outros',
 'revdelete-unsuppress' => 'Remover restrições das edições restauradas',
 'revdelete-log' => 'Motivo:',
-'revdelete-submit' => 'Aplicar {{PLURAL:$1|à revisão selecionada|à revisões selecionadas}}',
+'revdelete-submit' => 'Aplicar {{PLURAL:$1|à revisão selecionada|às revisões selecionadas}}',
 'revdelete-success' => "'''A visibilidade da revisão foi definida com sucesso.'''",
 'revdelete-failure' => "'''A visibilidade da revisão não foi atualizada:'''
 $1",
@@ -1355,7 +1359,7 @@ Os detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{F
 'search-interwiki-default' => 'Resultados de $1:',
 'search-interwiki-more' => '(mais)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Desativar sugestões AJAX',
+'mwsuggest-disable' => 'Desativar sugestões de pesquisa',
 'searcheverything-enable' => 'Procurar em todos os espaços nominais',
 'searchrelated' => 'relacionados',
 'searchall' => 'todos',
@@ -1401,7 +1405,7 @@ Note que os índices do sistema de busca externo poderão conter referências de
 'prefs-datetime' => 'Data e hora',
 'prefs-labs' => 'Características de laboratório',
 'prefs-user-pages' => 'Páginas de usuário',
-'prefs-personal' => 'Perfil de usuário',
+'prefs-personal' => 'Dados do usuário',
 'prefs-rc' => 'Mudanças recentes',
 'prefs-watchlist' => 'Lista de páginas vigiadas',
 'prefs-watchlist-days' => 'Dias a mostrar na lista de páginas vigiadas:',
@@ -1426,7 +1430,7 @@ Note que os índices do sistema de busca externo poderão conter referências de
 'resultsperpage' => 'Resultados por página:',
 'stub-threshold' => 'Links para páginas de conteúdo aparecerão <a href="#" class="stub">desta forma</a> se elas possuírem menos de (bytes):',
 'stub-threshold-disabled' => 'Desabilitado',
-'recentchangesdays' => 'Dias a serem exibidos nas Mudanças recentes:',
+'recentchangesdays' => 'Dias a apresentar nas mudanças recentes:',
 'recentchangesdays-max' => '(máximo: $1 {{PLURAL:$1|dia|dias}})',
 'recentchangescount' => 'Número de edições a serem exibidas por padrão:',
 'prefs-help-recentchangescount' => 'Isto inclui mudanças recentes, histórico de páginas e registros.',
@@ -1649,7 +1653,7 @@ Caso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu tra
 'action-suppressionlog' => 'ver este registro privado',
 'action-block' => 'impedir que este usuário edite',
 'action-protect' => 'alterar os níveis de proteção desta página',
-'action-rollback' => 'Reverter rapidamente as edições do último usuário que editou uma página em particular',
+'action-rollback' => 'reverter rapidamente as edições do último usuário que editou uma página em particular',
 'action-import' => 'importar esta página a partir de outro wiki',
 'action-importupload' => 'importar esta página através do carregamento de um arquivo',
 'action-patrol' => 'marcar as edições de outros usuários como patrulhadas',
@@ -1669,20 +1673,20 @@ Caso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu tra
 'recentchanges-feed-description' => 'Acompanhe neste feed as mudanças mais recentes do wiki.',
 'recentchanges-label-newpage' => 'Esta edição criou uma nova página',
 'recentchanges-label-minor' => 'Esta é uma edição menor',
-'recentchanges-label-bot' => 'Esta edição foi feita por um bot',
+'recentchanges-label-bot' => 'Esta edição foi feita por um robô',
 'recentchanges-label-unpatrolled' => 'Esta edição ainda não foi patrulhada',
 'rcnote' => "A seguir {{PLURAL:$1|está listada '''uma''' alteração ocorrida|estão listadas '''$1''' alterações ocorridas}} {{PLURAL:$2|no último dia|nos últimos '''$2''' dias}}, a partir das $5 de $4.",
 'rcnotefrom' => "Seguem as alterações desde as '''$4''' de '''$3''' (limitadas a '''$1''').",
 'rclistfrom' => 'Mostrar as novas alterações a partir das $1',
 'rcshowhideminor' => '$1 edições menores',
-'rcshowhidebots' => '$1 bots',
+'rcshowhidebots' => '$1 robôs',
 'rcshowhideliu' => '$1 usuários registrados',
 'rcshowhideanons' => '$1 usuários anônimos',
 'rcshowhidepatr' => '$1 edições patrulhadas',
 'rcshowhidemine' => '$1 minhas edições',
 'rclinks' => 'Exibir as $1 alterações recentes feitas nos últimos $2 dias<br />$3',
 'diff' => 'dif',
-'hist' => 'hist',
+'hist' => 'his',
 'hide' => 'Ocultar',
 'show' => 'Exibir',
 'minoreditletter' => 'm',
@@ -1702,7 +1706,7 @@ Caso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu tra
 'recentchangeslinked-feed' => 'Alterações relacionadas',
 'recentchangeslinked-toolbox' => 'Alterações relacionadas',
 'recentchangeslinked-title' => 'Alterações relacionadas com "$1"',
-'recentchangeslinked-noresult' => 'Não ocorreram alterações em páginas relacionadas no intervalo de tempo especificado.',
+'recentchangeslinked-noresult' => 'Nenhuma mudança nas páginas relacionadas durante o período.',
 'recentchangeslinked-summary' => "Esta página lista alterações feitas recentemente em páginas com links a uma em específico (ou de membros de uma categoria especificada).
 Páginas de sua [[Special:Watchlist|lista de páginas vigiadas]] são exibidas em '''negrito'''.",
 'recentchangeslinked-page' => 'Nome da página:',
@@ -2134,7 +2138,7 @@ Entradas <del>riscadas</del> foram resolvidas.',
 'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
 'ncategories' => '$1 {{PLURAL:$1|categoria|categorias}}',
 'ninterwikis' => '$1 {{PLURAL:$1|interwiki|Interwikis}}',
-'nlinks' => '$1 {{PLURAL:$1|link|links}}',
+'nlinks' => '$1 {{PLURAL:$1|linque|linques}}',
 'nmembers' => '$1 {{PLURAL:$1|membro|membros}}',
 'nrevisions' => '$1 {{PLURAL:$1|revisão|revisões}}',
 'nviews' => '$1 {{PLURAL:$1|visita|visitas}}',
@@ -2202,7 +2206,7 @@ Por favor note que outros websites podem apontar para um arquivo através de um
 
 # Book sources
 'booksources' => 'Fontes bibliográficas',
-'booksources-search-legend' => 'Procurar fontes bibliográficas',
+'booksources-search-legend' => 'Pesquisar referências bibliográficas',
 'booksources-go' => 'Ir',
 'booksources-text' => 'É exibida a seguir uma listagem de links para outros sites que vendem livros novos e usados e que possam possuir informações adicionais sobre os livros que você está pesquisando:',
 'booksources-invalid-isbn' => 'O número ISBN fornecido não parece ser válido; verifique se houve erros ao copiar da fonte original.',
@@ -2230,7 +2234,7 @@ Você pode diminuir a lista escolhendo um tipo de registro, um nome de usuário
 'allnotinnamespace' => 'Todas as páginas (excepto as do espaço nominal $1)',
 'allpagesprev' => 'Anterior',
 'allpagesnext' => 'Próximo',
-'allpagessubmit' => 'Ir',
+'allpagessubmit' => 'Ver',
 'allpagesprefix' => 'Exibir páginas com o prefixo:',
 'allpagesbadtitle' => 'O título de página fornecido encontrava-se inválido ou tinha um prefixo interlíngua ou inter-wiki. Ele poderá conter um ou mais caracteres que não podem ser utilizados em títulos.',
 'allpages-bad-ns' => '{{SITENAME}} não possui o espaço nominal "$1".',
@@ -2262,7 +2266,7 @@ Veja também [[Special:WantedCategories|categorias pedidas]].',
 'linksearch-ok' => 'Pesquisar',
 'linksearch-text' => 'É possível usar caracteres coringa, como "*.wikipedia.org".
 Necessário no mínimo um domínio de nível superior, por exemplo "*.org".<br />
-Protocolos suportados: <code>$1</code> (o padrão é http://).',
+{{PLURAL:$2|Protocolo suportado|Protocolos suportados}}: <code>$1</code> (caso nenhum seja especificado, o protocolo http:// será selecionado automaticamente).',
 'linksearch-line' => '$2 possui links para $1',
 'linksearch-error' => "\"Caracteres mágicos\" (''wildcards'') só podem ser usados no início do endereço.",
 
@@ -2275,7 +2279,7 @@ Protocolos suportados: <code>$1</code> (o padrão é http://).',
 # Special:ActiveUsers
 'activeusers' => 'Lista de usuários ativos',
 '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|edição|edições}} {{PLURAL:$3|no último dia|nos últimos $3 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 em:',
 'activeusers-hidebots' => 'Esconder robôs',
 'activeusers-hidesysops' => 'Esconder administradores',
@@ -2437,7 +2441,7 @@ Por favor, confirme que possui a intenção de fazer isto, que compreende as con
 Consulte $2 para um registro de eliminações recentes.',
 'dellogpage' => 'Registro de eliminação',
 'dellogpagetext' => 'Abaixo uma lista das eliminações mais recentes.',
-'deletionlog' => 'registro de eliminação',
+'deletionlog' => 'registro de eliminações',
 'reverted' => 'Revertido para versão anterior',
 'deletecomment' => 'Motivo:',
 'deleteotherreason' => 'Justificativa adicional:',
@@ -2489,6 +2493,8 @@ Consulte a [[Special:ProtectedPages|lista de páginas protegidas]] para ver as p
 'prot_1movedto2' => '[[$1]] foi movido para [[$2]]',
 'protect-badnamespace-title' => 'Espaço de nomes não-protegidos',
 'protect-badnamespace-text' => 'As páginas presentes nesse espaço de nomes não se pode proteger',
+'protect-norestrictiontypes-text' => 'Esta página não pode ser protegida, pois não há nenhum tipo de restrição disponível.',
+'protect-norestrictiontypes-title' => 'Página com proteção indisponível',
 'protect-legend' => 'Confirmar proteção',
 'protectcomment' => 'Motivo:',
 'protectexpiry' => 'Expiração',
@@ -2503,13 +2509,13 @@ Esta é a configuração atual para a página '''$1''':",
 Esta é a configuração atual para a página '''$1''':",
 'protect-cascadeon' => 'Esta página encontra-se protegida, uma vez que se encontra incluída {{PLURAL:$1|na página listada a seguir, protegida|nas páginas listadas a seguir, protegidas}} com a "proteção progressiva" ativada. Você poderá alterar o nível de proteção desta página, mas isso não afetará a "proteção progressiva".',
 'protect-default' => 'Permitir todos os usuários',
-'protect-fallback' => 'É necessário o privilégio de "$1"',
-'protect-level-autoconfirmed' => 'Bloquear usuários novos e não registrados',
-'protect-level-sysop' => 'Apenas administradores',
+'protect-fallback' => 'Permitir apenas os usuários com privilégio de "$1"',
+'protect-level-autoconfirmed' => 'Permitir apenas usuários auto-confirmados',
+'protect-level-sysop' => 'Permitir apenas administradores',
 'protect-summary-cascade' => 'p. progressiva',
 'protect-expiring' => 'expira em $1 (UTC)',
 'protect-expiring-local' => 'expira $1',
-'protect-expiry-indefinite' => 'tempo indefinido',
+'protect-expiry-indefinite' => 'indefinidamente',
 'protect-cascade' => '"Proteção progressiva" - proteja quaisquer páginas que estejam incluídas nesta.',
 'protect-cantedit' => 'Você não pode alterar o nível de proteção desta página uma vez que você não se encontra habilitado a editá-la.',
 'protect-othertime' => 'Outra duração:',
@@ -2613,7 +2619,7 @@ $1',
 'sp-contributions-newbies' => 'Mostrar apenas as contribuições das novas contas',
 'sp-contributions-newbies-sub' => 'Para contas novas',
 'sp-contributions-newbies-title' => 'Contribuições de contas novas',
-'sp-contributions-blocklog' => 'Registro de bloqueios',
+'sp-contributions-blocklog' => 'registro de bloqueios',
 'sp-contributions-deleted' => 'contribuições eliminadas',
 'sp-contributions-uploads' => 'envios',
 'sp-contributions-logs' => 'registros',
@@ -2632,7 +2638,7 @@ Segue, para referência, a entrada mais recente no registro de bloqueios:',
 'whatlinkshere-title' => 'Páginas que têm links para "$1"',
 'whatlinkshere-page' => 'Página:',
 'linkshere' => "As seguintes páginas possuem links para '''[[:$1]]''':",
-'nolinkshere' => "Não há links para '''[[:$1]]'''.",
+'nolinkshere' => "Não há afluentes para '''[[:$1]]''' com as condições especificadas.",
 'nolinkshere-ns' => "Não há links para '''[[:$1]]''' no espaço nominal selecionado.",
 'isredirect' => 'página de redirecionamento',
 'istemplate' => 'transclusão',
@@ -2718,7 +2724,7 @@ Consulte a [[Special:BlockList|lista de bloqueios]].',
 'expiringblock' => 'expira em $1 às $2',
 'anononlyblock' => 'anôn. apenas',
 'noautoblockblock' => 'bloqueio automático desabilitado',
-'createaccountblock' => 'criação de conta de usuário bloqueada',
+'createaccountblock' => 'criação de conta bloqueada',
 'emailblock' => 'impedido de enviar e-mail',
 'blocklist-nousertalk' => 'impossibilitado de editar a própria página de discussão',
 'ipblocklist-empty' => 'A lista de bloqueios encontra-se vazia.',
@@ -2743,7 +2749,7 @@ Consulte a [[Special:BlockList|lista de bloqueios]] para obter a lista de bloque
 'block-log-flags-anononly' => 'apenas usuários anônimos',
 'block-log-flags-nocreate' => 'criação de contas desabilitada',
 'block-log-flags-noautoblock' => 'bloqueio automático desabilitado',
-'block-log-flags-noemail' => 'impedido de enviar e-mail',
+'block-log-flags-noemail' => 'e-mail bloqueado',
 'block-log-flags-nousertalk' => 'impossibilitado de editar a própria página de discussão',
 'block-log-flags-angry-autoblock' => 'autobloqueio melhorado ativado',
 'block-log-flags-hiddenname' => 'nome de usuário oculto',
@@ -2795,14 +2801,18 @@ Por favor, confirme que realmente pretende fazer isso.',
 # Move page
 'move-page' => 'Mover $1',
 'move-page-legend' => 'Mover página',
-'movepagetext' => "Utilizando o seguinte formulário você poderá renomear uma página, movendo todo o histórico para o novo título. O título anterior será transformado em um redirecionamento para o novo.
-
-Links para as páginas antigas não serão mudados; certifique-se de verificar por redirecionamentos quebrados ou duplos. Você é responsável por certificar-se que os links continuam apontando para onde eles deveriam apontar.
-
-Note que a página '''não''' será movida se já existir uma página com o novo título, a não ser que ele esteja vazio ou seja um redirecionamento e não tenha histórico de edições. Isto significa que pode renomear uma página de volta para o nome que tinha anteriormente se cometer algum engano e que não pode sobrescrever uma página.
-
-<b>CUIDADO!</b>
-Isto pode ser uma mudança drástica e inesperada para uma página popular; por favor, tenha certeza de que compreende as consequências da mudança antes de prosseguir.",
+'movepagetext' => "Utilizando o formulário a seguir você poderá renomear uma página, movendo todo o histórico para o novo título.
+O título anterior será transformado em um redirecionamento para o novo.
+Você poderá optar em atualizar automaticamente os redirecionamentos que se destinem ao título original.
+Caso escolha pela não-atualização, se certifique de verificar por redirecionamentos [[Special:DoubleRedirects|duplos]] ou [[Special:BrokenRedirects|quebrados]].
+É de sua responsabilidade que os links continuem direcionando para onde eles devem.
+
+Note que a página '''não''' será movida se já existir uma página com o novo título, a não ser que ele seja um redirecionamento e não tenha histórico de edições.
+Isto significa que você pode renomear uma página de volta para o seu nome anterior se cometer algum engano e que não poderá sobrescrever uma página existente.
+
+'''CUIDADO!'''
+Esta pode ser uma mudança drástica e inesperada para uma página popular;
+tenha certeza de que compreende as consequências da mudança antes de prosseguir.",
 'movepagetext-noredirectfixer' => "Usando o formulário abaixo, você irá alterar o nome de uma página e moverá todo o histórico desta para o nome novo.
 A página antiga será transformada numa página de redirecionamento para a nova.
 Verifique a existência de [[Special:DoubleRedirects|redirecionamentos duplos]] ou [[Special:BrokenRedirects|quebrados]].
@@ -3093,7 +3103,7 @@ Permite colocar uma justificativa no sumário da edição.',
 'anonymous' => '{{PLURAL:$1|Usuário anônimo|Usuários anônimos}} da {{SITENAME}}',
 'siteuser' => '{{GENDER:$2|um utilizador|uma utilizadora|um utilizador}} da {{SITENAME}} ($1)',
 'anonuser' => 'usuário anônimo $1 da {{SITENAME}}',
-'lastmodifiedatby' => 'Esta página foi modificada pela última vez às $2 de $1 por $3.',
+'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 usuário|$2 usuários}} da {{SITENAME}} ($1)',
@@ -3128,9 +3138,9 @@ Tal bloqueio foi provavelmente causado por uma ligação para um ''website'' ext
 'pageinfo-robot-noindex' => 'Não indexável',
 'pageinfo-views' => 'Número de visitas',
 'pageinfo-watchers' => 'Número de vigilantes da página',
-'pageinfo-redirects-name' => 'Redireciona para esta página',
+'pageinfo-redirects-name' => 'Redirecionamentos para esta página',
 'pageinfo-subpages-name' => 'Subpáginas desta página',
-'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecionamento|redirecionamentos}}; $3 {{PLURAL:$3|não-redirecionamento|não-redirecionamentos}})',
+'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecionamento|redirecionamentos}}; $3 {{PLURAL:$3|não redirecionamento|não redirecionamentos}})',
 'pageinfo-firstuser' => 'Criador da página',
 'pageinfo-firsttime' => 'Data de criação da página',
 'pageinfo-lastuser' => 'Último editor',
@@ -3142,14 +3152,19 @@ Tal bloqueio foi provavelmente causado por uma ligação para um ''website'' ext
 'pageinfo-magic-words' => '{{PLURAL:$1|Palavra mágica|Palavras mágicas}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoria oculta|Categorias ocultas}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Predefinição transcluída|Predefinições transcluídas ($1)}}',
+'pageinfo-transclusions' => '{{PLURAL:$1|Página em que é transcluída|Páginas em que é transcluída ($1)}}',
 'pageinfo-toolboxlink' => 'Informações da página',
-'pageinfo-redirectsto' => 'Redirecionar para',
+'pageinfo-redirectsto' => 'Redireciona para',
 'pageinfo-redirectsto-info' => 'informações',
 'pageinfo-contentpage' => 'Contado como uma página de conteúdo',
 'pageinfo-contentpage-yes' => 'Sim',
 'pageinfo-protect-cascading' => 'Proteção em cascata ativada',
 'pageinfo-protect-cascading-yes' => 'Sim',
 'pageinfo-protect-cascading-from' => 'Proteções herdadas 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 arquivos',
 
 # Skin names
 'skinname-standard' => 'Clássico',
@@ -3236,6 +3251,8 @@ Executá-lo poderá comprometer a segurança do seu sistema.",
 'minutes' => '{{PLURAL:$1|um minuto|$1 minutos}}',
 'hours' => '{{PLURAL:$1|uma hora|$1 horas}}',
 'days' => '{{PLURAL:$1|um dia|$1 dias}}',
+'months' => '{{PLURAL:$1|$1 mês|$1 meses}}',
+'years' => '{{PLURAL:$1|$1 ano|$1 anos}}',
 'ago' => '$1 atrás',
 'just-now' => 'agora mesmo',
 
@@ -3896,7 +3913,7 @@ As imagens serão exibidas em sua resolução máxima, outros tipos de arquivos
 'specialpages-group-highuse' => 'Páginas muito usadas',
 'specialpages-group-pages' => 'Listas de páginas',
 'specialpages-group-pagetools' => 'Ferramentas de páginas',
-'specialpages-group-wiki' => 'Dados e ferramentas sobre este wiki',
+'specialpages-group-wiki' => 'Dados e ferramentas',
 'specialpages-group-redirects' => 'Páginas especiais redirecionadas',
 'specialpages-group-spam' => 'Ferramentas anti-spam',
 
@@ -3968,7 +3985,7 @@ As imagens serão exibidas em sua resolução máxima, outros tipos de arquivos
 'logentry-delete-delete' => '$1 apagou a página $3',
 'logentry-delete-restore' => '$1 restaurou a página $3',
 'logentry-delete-event' => '$1 alterou a visibilidade {{PLURAL:$5|de uma entrada|de $5 entradas}} do registro $3: $4',
-'logentry-delete-revision' => '$1 alterou a visibilidade {{PLURAL:$5|de uma revisão|das $5 revisões}} em $3: $4',
+'logentry-delete-revision' => '$1 alterou a visibilidade de {{PLURAL:$5|uma revisão|$5 revisões}} em $3: $4',
 'logentry-delete-event-legacy' => '$1 alterou a visibilidade de uma entrada em $3',
 'logentry-delete-revision-legacy' => '$1 alterou a visibilidade de uma revisão em $3',
 'logentry-suppress-delete' => '$1 suprimiu a página $3',
@@ -3979,9 +3996,9 @@ As imagens serão exibidas em sua resolução máxima, outros tipos de arquivos
 'revdelete-content-hid' => 'conteúdo oculto',
 'revdelete-summary-hid' => 'sumário de edição oculto',
 'revdelete-uname-hid' => 'nome de usuário oculto',
-'revdelete-content-unhid' => 'conteúdo não oculto',
-'revdelete-summary-unhid' => 'sumário de edição não oculto',
-'revdelete-uname-unhid' => 'nome de usuário não oculto',
+'revdelete-content-unhid' => 'conteúdo desocultado',
+'revdelete-summary-unhid' => 'sumário de edição desocultado',
+'revdelete-uname-unhid' => 'nome de usuário desocultado',
 'revdelete-restricted' => 'restrições a administradores aplicadas',
 'revdelete-unrestricted' => 'restrições a administradores removidas',
 'logentry-move-move' => '$1 moveu a página $3 para $4',
@@ -3993,8 +4010,8 @@ As imagens serão exibidas em sua resolução máxima, outros tipos de arquivos
 'logentry-newusers-newusers' => 'A conta de usuário $1 foi criada',
 'logentry-newusers-create' => 'A conta de usuário $1 foi criada',
 'logentry-newusers-create2' => 'A conta de usuário $3 foi criada por $1',
+'logentry-newusers-byemail' => 'A conta de usuário $3 foi criada por $1, com a senha sendo enviada por e-mail',
 'logentry-newusers-autocreate' => 'A conta $1 foi criada automaticamente',
-'newuserlog-byemail' => 'senha enviada por correio-eletrônico',
 'logentry-rights-rights' => '$1 alterou os grupos de usuário de $3 de $4 para $5',
 'logentry-rights-rights-legacy' => '$1 alterou os grupos de $3',
 'logentry-rights-autopromote' => '$1 foi promovido automaticamente de $4 a $5',
index 769b137..287ccda 100644 (file)
@@ -92,6 +92,7 @@
  * @author Octahedron80
  * @author Od1n
  * @author Onecountry
+ * @author Opraco
  * @author OsamaK
  * @author PhiLiP
  * @author Piangpha
@@ -308,7 +309,8 @@ This option means "underline links as in your user skin or your browser", there
 # Categories related messages
 'pagecategories' => 'Used in the categories section of pages. Is followed by a colon and a list of categories.',
 'category_header' => 'In category description page',
-'subcategories' => 'Used as a header on category pages that have subcategories.',
+'subcategories' => 'Used as a header on category pages that have subcategories.
+{{Identical|Subcategory}}',
 'category-media-header' => 'In category description page',
 'category-empty' => 'The text displayed in category page when that category is empty',
 'hidden-categories' => 'Used in the categories section of pages. Is followed by a colon and a list of categories.',
@@ -330,8 +332,8 @@ This option means "underline links as in your user skin or your browser", there
 * $1: number of files shown',
 'listingcontinuesabbrev' => 'Shown in contiuation of each first letter group.
 See http://test.wikipedia.org/wiki/Category:Test_ko?uselang={{SUBPAGENAME}}, for example.',
-'index-category' => 'Name of the [[mw:Help:Tracking categories|tracking category]] where pages with the <nowiki>__INDEX__</nowiki> behaviour switch are listed. For description of this behaviour switch see [//www.mediawiki.org/wiki/Help:Magic_words#Behavior_switches mediawiki].',
-'noindex-category' => 'Name of the [[mw:Help:Tracking categories|tracking category]] where pages with the <nowiki>__NOINDEX__</nowiki> behaviour switch are listed. For description of this behaviour switch see [//www.mediawiki.org/wiki/Help:Magic_words#Behavior_switches mediawiki].',
+'index-category' => 'Name of the [[mw:Help:Tracking categories|tracking category]] where pages with the <nowiki>__INDEX__</nowiki> behaviour switch are listed. For description of this behaviour switch see [[mw:Help:Magic_words#Behavior_switches|MediaWiki]].',
+'noindex-category' => 'Name of the [[mw:Help:Tracking categories|tracking category]] where pages with the <nowiki>__NOINDEX__</nowiki> behaviour switch are listed. For description of this behaviour switch see [[mw:Help:Magic_words#Behavior_switches|MediaWiki]].',
 'broken-file-category' => 'Name of [[mw:Help:Tracking categories|tracking category]] where pages that embed files that do not exist ("broken images") are listed.',
 'categoryviewer-pagedlinks' => '{{Optional}}
 The pagination links in category viewer. Parameters:
@@ -341,7 +343,7 @@ The pagination links in category viewer. Parameters:
 'linkprefix' => '{{optional}}',
 
 'about' => '{{Identical|About}}',
-'article' => "A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [//www.mediawiki.org/wiki/Manual:Using_custom_namespaces#Content_namespaces Mediawiki].
+'article' => "A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].
 
 Possible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.
 
@@ -380,8 +382,7 @@ See also:
 {{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 "&". <nowiki>&#32;</nowiki> is a blank space, one character long. Please leave it as it is.
 
-This can also appear in the credits page if the credits feature is enabled,for example [http://translatewiki.net/wiki/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.)
-
+This 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.)
 {{Identical|And}}',
 
 # Cologne Blue skin
@@ -391,18 +392,18 @@ This can also appear in the credits page if the credits feature is enabled,for e
 'qbedit' => '{{Identical|Edit}}',
 'qbmyoptions' => 'Heading in the Cologne Blue skin user menu containing links to user (talk) page, preferences, watchlist, etc.
 {{Identical|My pages}}',
-'qbspecialpages' => '{{Identical|Special pages}}',
+'qbspecialpages' => '{{Identical|Special page}}',
 'faq' => "FAQ is short for ''frequently asked questions''.",
 'faqpage' => "FAQ is short for ''frequently asked questions''. This page is only linked on some of the old skins, not in Monobook or Modern.
 
 {{doc-important|Do not translate <tt>Project:</tt> part.}}",
 
 # Vector skin
-'vector-action-addsection' => 'Used in the Vector skin. See for example http://translatewiki.net/wiki/Talk:Main_Page?useskin=vector',
-'vector-action-delete' => 'Used in the Vector skin, as the name of a tab at the top of the page. See for example http://translatewiki.net/wiki/Main_Page?useskin=vector
+'vector-action-addsection' => 'Used in the Vector skin. See for example {{canonicalurl:Talk:Main_Page|useskin=vector}}',
+'vector-action-delete' => 'Used in the Vector skin, as the name of a tab at the top of the page. See for example {{canonicalurl:Main_Page|useskin=vector}}
 
 {{Identical|Delete}}',
-'vector-action-move' => 'Used in the Vector skin, on the tabs at the top of the page. See for example http://translatewiki.net/wiki/Talk:Main_Page?useskin=vector
+'vector-action-move' => 'Used in the Vector skin, on the tabs at the top of the page. See for example {{canonicalurl:Talk:Main_Page|useskin=vector}}
 
 {{Identical|Move}}',
 'vector-action-protect' => 'Tab at top of page, in vector skin
@@ -414,13 +415,13 @@ This can also appear in the credits page if the credits feature is enabled,for e
 
 {{Identical|Unprotect}}',
 'vector-simplesearch-preference' => 'Preference for enhanced search suggestion in the Vector skin.',
-'vector-view-create' => 'Tab label in the Vector skin. See for example http://translatewiki.net/wiki/Foo?useskin=vector
+'vector-view-create' => 'Tab label in the Vector skin. See for example {{canonicalurl:Foo|useskin=vector}}
 {{Identical|Create}}',
-'vector-view-edit' => 'Tab label in the Vector skin. See for example http://translatewiki.net/wiki/Main_Page?useskin=vector
+'vector-view-edit' => 'Tab label in the Vector skin. See for example {{canonicalurl:Main_Page|useskin=vector}}
 {{Identical|Edit}}',
-'vector-view-history' => 'Tab label in the Vector skin. See for example http://translatewiki.net/wiki/Main_Page?useskin=vector
+'vector-view-history' => 'Tab label in the Vector skin. See for example {{canonicalurl:Main_Page|useskin=vector}}
 {{Identical|View history}}',
-'vector-view-view' => 'Tab label in the Vector skin (verb). See for example http://translatewiki.net/w/i.php?title=Main_Page&useskin=vector',
+'vector-view-view' => 'Tab label in the Vector skin (verb). See for example {{canonicalurl:Main_Page|useskin=vector}}',
 'vector-view-viewsource' => 'Tab label in the Vector skin.
 {{Identical|View source}}',
 'actions' => '{{Identical|Action}}',
@@ -432,7 +433,8 @@ This can also appear in the credits page if the credits feature is enabled,for e
 
 {{Identical|Error}}',
 'returnto' => '{{Identical|Return to $1}}',
-'tagline' => 'Used to identify the source of copied information. Do not change <nowiki>{{SITENAME}}</nowiki>.',
+'tagline' => '{{doc-important|Do not change <code><nowiki>{{SITENAME}}</nowiki></code>.}}
+Used to identify the source of copied information.',
 'help' => 'General text (noun) used in the sidebar (by default).
 
 See also [[MediaWiki:Helppage/{{SUBPAGENAME}}|{{int:helppage}}]] and [[MediaWiki:Edithelp/{{SUBPAGENAME}}|{{int:edithelp}}]].
@@ -462,6 +464,7 @@ See also:
 'searcharticle' => 'Button description in the search menu displayed on every page. The "Search" button is [[MediaWiki:Searchbutton/{{SUBPAGENAME}}]].
 
 {{Identical|Go}}',
+'history' => '{{Identical|Page history}}',
 'history_short' => 'Text used on the history tab.
 
 {{Identical|History}}',
@@ -471,13 +474,15 @@ See also:
 See also:
 * {{msg-mw|Printableversion}}
 * {{msg-mw|Accesskey-t-print}}
-* {{msg-mw|Tooltip-t-print}}',
+* {{msg-mw|Tooltip-t-print}}
+{{Identical|Printable version}}',
 'permalink' => 'Display name for a permanent link to the current revision of a page. When the page is edited, permalink will still link to this revision. Example: Last menu link on [[{{MediaWiki:Mainpage}}]]
 
 See also:
 * {{msg-mw|Permalink}}
 * {{msg-mw|Accesskey-t-permalink}}
-* {{msg-mw|Tooltip-t-permalink}}',
+* {{msg-mw|Tooltip-t-permalink}}
+{{Identical|Permalink}}',
 'print' => '{{Identical|Print}}',
 'view' => 'The default text of the "View" or "Read" (Vector) views tab which represents the basic view for the page. Should be in the infinitive mood.
 
@@ -531,8 +536,8 @@ See also:
 'talkpagelinktext' => 'Used as name of links going to talk page in some places, like in [[Special:RecentChanges]], [[Special:Allmessages]], [[Special:Logs]], and [[Special:Watchlist/edit]].
 
 {{Identical|Talk}}',
-'specialpage' => '{{Identical|Special pages}}',
-'personaltools' => 'Heading for a group of links to your user page, talk page, preferences, watchlist, and contributions. This heading is visible in the sidebar in some skins. For an example, see [http://translatewiki.net/wiki/Main_Page?useskin=simple Main Page using simple skin].',
+'specialpage' => '{{Identical|Special page}}',
+'personaltools' => 'Heading for a group of links to your user page, talk page, preferences, watchlist, and contributions. This heading is visible in the sidebar in some skins. For an example, see [{{canonicalurl:Main_Page|useskin=simple}} Main Page using simple skin].',
 'articlepage' => "'Content page' is used for NS_MAIN and any other non-standard namespace and this message is only used in skins Nostalgia, Cologneblue and Standard in the bottomLinks part.
 
 {{Identical|Content page}}",
@@ -543,11 +548,12 @@ See also:
 * {{msg-mw|Accesskey-ca-talk}}
 * {{msg-mw|Tooltip-ca-talk}}
 {{Identical|Discussion}}',
-'views' => 'Subtitle for the list of available views, for the current page. In "monobook" skin the list of views are shown as tabs, so this sub-title is not shown. For an example, see [http://translatewiki.net/wiki/Main_Page?useskin=simple Main Page using simple skin].
+'views' => 'Subtitle for the list of available views, for the current page. In "monobook" skin the list of views are shown as tabs, so this sub-title is not shown. For an example, see [{{canonicalurl:Main_Page|useskin=simple}} Main Page using simple skin].
 
 \'\'\'Note:\'\'\' This is "views" as in "appearances"/"representations", \'\'\'not\'\'\' as in "visits"/"accesses".
 {{Identical|View}}',
-'toolbox' => 'The title of the toolbox below the search menu.',
+'toolbox' => 'The title of the toolbox below the search menu.
+{{Identical|Toolbox}}',
 'userpage' => '',
 'projectpage' => 'Used as link text in Talk page of project page.',
 'imagepage' => 'Used as link text in Talk page of file page.',
@@ -582,7 +588,7 @@ This message is the title for the message {{msg-mw|protectedpagetext}}.",
 'view-pool-error' => 'Error message. $1 is probably unused.',
 'pool-timeout' => "Part of {{msg-mw|view-pool-error}}.
 
-For explanation of 'lock' see [http://en.wikipedia.org/wiki/Lock_%28computer_science%29 wikipedia].",
+For explanation of 'lock' see [[w:Lock_(computer_science)|wikipedia]].",
 'pool-queuefull' => 'Part of {{msg-mw|view-pool-error}}
 
 "Pool" refers to a pool of processes.',
@@ -652,7 +658,8 @@ See also:
 * {{msg-mw|Portal-url}}
 * {{msg-mw|Accesskey-n-portal}}
 * {{msg-mw|Tooltip-n-portal}}',
-'privacy' => 'Used as page name and link at the bottom of each wiki page. The page contains a legal notice providing information about the use of personal information by the website owner.of the site. Example: [[Privacy policy]].',
+'privacy' => 'Used as page name and link at the bottom of each wiki page. The page contains a legal notice providing information about the use of personal information by the website owner.of the site. Example: [[Privacy policy]].
+{{Identical|Privacy policy}}',
 'privacypage' => 'Used as page for that contains the privacy policy. Used at the bottom of every page on the wiki. Example: [[{{MediaWiki:Privacypage}}|{{MediaWiki:Privacy}}]].
 {{doc-important|Do not change the "<tt>Project:</tt>" part.}}',
 
@@ -682,7 +689,10 @@ The format is: "{{int:youhavenewmessages| [[MediaWiki:Newmessageslink/{{SUBPAGEN
 Used in message {{msg-mw|youhavenewmessages}} (as parameter $1).
 
 {{Identical|New messages}}',
-'newmessagesdifflink' => 'This is the second link displayed in an orange rectangle when a user gets a message on his talk page. Used in message {{msg-mw|youhavenewmessages}} (as parameter $2).',
+'newmessagesdifflink' => 'This is the second link displayed in an orange rectangle when a user gets a message on his talk page. Used in message {{msg-mw|youhavenewmessages}} (as parameter $2).
+
+See also:
+* {{msg-mw|Newmessagesdifflinkplural}}',
 'youhavenewmessagesfromusers' => 'New talk indicator message: the message appearing when someone edited your user talk page.
 The message takes three parameters;
 *$1 {{msg-mw|newmessageslinkplural}},
@@ -694,8 +704,11 @@ The message takes three parameters;
 'newmessageslinkplural' => 'Like {{msg-mw|newmessageslink}} but supporting pluralization. Used in message {{msg-mw|youhavenewmessagesfromusers}} (as parameter $1).
 This message itself takes one parameter, $1, which is 1 if there was one new edit, or 2 if there was more than one new edit
 since the last time the user has seen his or her talk page.',
-'newmessagesdifflinkplural' => 'Like {{msg-mw|newmessagesdifflink}} but supporting pluralization. Used in message {{msg-mw|youhavenewmessagesfromusers}} (as parameter $2).
-This message itself takes one parameter, $1, which is the number of new edits since the last time the user has seen his or her talk page.',
+'newmessagesdifflinkplural' => 'This message itself takes one parameter, $1, which is the number of new edits since the last time the user has seen his or her talk page: it should be used only for correct [[plural]] as in the source text, as the exact number is not relevant.
+
+Like {{msg-mw|newmessagesdifflink}} but supporting pluralization.
+
+Used in message {{msg-mw|youhavenewmessagesfromusers}} (as parameter $2).',
 'youhavenewmessagesmulti' => 'The alternative of {{msg|youhavenewmessages}} as used on wikis with a special setup so they can receive the "new message" notice on other wikis as well. Used on [http://www.wikia.com/ Wikia].
 The format is: "{{int:youhavenewmessagesmulti| [[MediaWiki:Newmessageslink/{{SUBPAGENAME}}|{{int:newmessageslink}}]]}}"',
 'editsection' => 'Display name of link to edit a section on a content page. Example: [{{MediaWiki:Editsection}}].
@@ -711,9 +724,8 @@ The format is: "{{int:youhavenewmessagesmulti| [[MediaWiki:Newmessageslink/{{SUB
 
 {{Identical|View source}}',
 'editsectionhint' => "Tool tip shown when hovering the mouse over the link to '[{{MediaWiki:Editsection}}]' a section. Example: Edit section: Heading name",
-'toc' => 'This is the title of the table of contents displayed in pages with more than 3 sections
-
-{{Identical|Contents}}',
+'toc' => 'This is the title of the table of contents displayed in pages with more than 3 sections.
+{{Identical|Content}}',
 'showtoc' => 'This is the link used to show the table of contents
 
 {{Identical|Show}}',
@@ -733,8 +745,14 @@ See also:
 
 See the following example:
 {{Identical|Expand}}',
-'thisisdeleted' => 'Message shown on a deleted page when the user has the undelete right. $1 is a link to [[Special:Undelete]], with {{msg-mw|restorelink}} as the text. See also {{msg-mw|viewdeleted}}.',
-'viewdeleted' => 'Message shown on a deleted page when the user does not have the undelete right (but has the deletedhistory right). $1 is a link to [[Special:Undelete]], with {{msg-mw|restorelink}} as the text. See also {{msg-mw|thisisdeleted}}.',
+'thisisdeleted' => 'Message shown on a deleted page when the user has the undelete right. Parameters:
+* $1 - a link to [[Special:Undelete]], with {{msg-mw|restorelink}} as the text
+See also:
+* {{msg-mw|viewdeleted}}',
+'viewdeleted' => 'Message shown on a deleted page when the user does not have the undelete right (but has the deletedhistory right). Parameters:
+* $1 - a link to [[Special:Undelete]], with {{msg-mw|restorelink}} as the text
+See also:
+* {{msg-mw|thisisdeleted}}',
 'restorelink' => "This text is always displayed in conjunction with the {{msg-mw|thisisdeleted}} message (View or restore $1?). The user will see
 View or restore <nowiki>{{PLURAL:$1|one deleted edit|$1 deleted edits}}</nowiki>?    i.e ''View or restore one deleted edit?''     or
 ''View or restore n deleted edits?''",
@@ -790,7 +808,7 @@ See also:
 See also:
 * {{msg-mw|Nstab-special}}
 * {{msg-mw|Tooltip-ca-nstab-special}}
-{{Identical|Special pages}}',
+{{Identical|Special page}}',
 'nstab-project' => 'The name for the tab of the project namespace. Example: [[Project:Example]]
 
 See also:
@@ -835,8 +853,8 @@ See also:
 # Main script and global functions
 'nosuchaction' => 'The title of the error you get when trying to open a page with invalid "action" parameter. The text of the warning is the message {{msg-mw|nosuchactiontext}}.
 
-See example [//translatewiki.net/wiki/Main_page?action=x action=x].',
-'nosuchactiontext' => 'This error is shown when trying to open a page with invalid "action" parameter, e.g. [//translatewiki.net/wiki/Main_page?action=x action=x].
+See example [{{canonicalurl:Main_page|action=x}} action=x].',
+'nosuchactiontext' => 'This error is shown when trying to open a page with invalid "action" parameter, e.g. [{{canonicalurl:Main_page|action=x}} action=x].
 * The title of this error is the message {{msg-mw|nosuchaction}}.',
 'nosuchspecialpage' => 'The title of the error you get when trying to open a special page which does not exist. The text of the warning is the message {{msg-mw|nospecialpagetext}}. Example: [[Special:Nosuchpage]]',
 'nospecialpagetext' => '{{doc-important|Link <code><nowiki>[[Special:SpecialPages|{{int:specialpages}}]]</nowiki></code> should remain untranslated.}}
@@ -864,8 +882,8 @@ This error is shown when trying to open a special page which does not exist, e.g
 'readonlytext' => 'Used as error message when the database is locked.',
 'missing-article' => "This message is shown when a revision does not exist, either as permalink or as diff. Examples:
 
-# [http://translatewiki.net/w/i.php?title=Project:News&oldid=9999999 Permalink with invalid revision#]
-# [http://translatewiki.net/w/i.php?title=Project:News&diff=426850&oldid=99999999 Diff with invalid revision#]
+# [{{canonicalurl:Project:News|oldid=9999999}} Permalink with invalid revision#]
+# [{{canonicalurl:Project:News|diff=426850&oldid=99999999}} Diff with invalid revision#]
 
 '''Parameters'''
 * $1: Pagename
@@ -876,17 +894,17 @@ This error is shown when trying to open a special page which does not exist, e.g
 
 * $1: revision# of the requested id
 
-[http://translatewiki.net/w/i.php?title=Translating:Tasks&oldid=371789000 Click here] to see an example of such an error message.',
+[{{canonicalurl:Translating:Tasks|oldid=371789000}} Click here] to see an example of such an error message.',
 'missingarticle-diff' => 'Parameter $2 of {{msg-mw|Missing-article}}: It is shown after the articlename.
 
 * $1: revision# of the old id
 * $2: revision# of the id build the diff with.
 
-[http://translatewiki.net/w/i.php?title=Translating:Tasks&diff=372398&oldid=371789000 Click here] to see an example of such an error message.',
+[{{canonicalurl:Translating:Tasks|diff=372398&oldid=371789000}} Click here] to see an example of such an error message.',
 'readonly_lag' => 'Error message displayed when the database is locked.',
 'internalerror' => '{{Identical|Internal error}}',
 'internalerror_info' => '* $1 - error message',
-'fileappenderrorread' => '"Append" is a computer procedure, explained on [http://en.wikipedia.org/wiki/Append Wikipedia].
+'fileappenderrorread' => '"Append" is a computer procedure, explained on [[w:Append|Wikipedia]].
 
 $1 is a filename, I think.',
 'fileappenderror' => 'Parameters:
@@ -1035,7 +1053,7 @@ See also:
 'nologin' => 'A message shown in the log in form. $1 is a link to the account creation form, and the text of it is "[[MediaWiki:Nologinlink/{{SUBPAGENAME}}|{{int:nologinlink}}]]".',
 'nologinlink' => 'Text of the link to the account creation form. Before that link, the message [[MediaWiki:Nologin/{{SUBPAGENAME}}]] appears.
 {{Identical|Create an account}}',
-'createaccount' => 'The title of Special:CreateAccount, where users can register a new account. Used on Special:SpecialPages and on the submit button in the form where you register a new account.
+'createaccount' => 'The title of [[Special:CreateAccount]], where users can register a new account. Used on [[Special:SpecialPages]] and on the submit button in the form where you register a new account.
 
 It is also used on the top of the page for logged out users, where it appears next to {{msg-mw|login}}, so consider making them similar.
 {{Identical|Create account}}',
@@ -1060,7 +1078,8 @@ This message is displayed when someone tried to login and the CSRF failed (most
 
 Defaults to '''nocookieslogin''' ({{int:nocookieslogin}})",
 'noname' => 'Error message.',
-'loginsuccesstitle' => 'The title of the page saying that you are logged in. The content of the page is the message "[[MediaWiki:Loginsuccess/{{SUBPAGENAME}}]]".',
+'loginsuccesstitle' => 'The title of the page saying that you are logged in. The content of the page is the message {{msg-mw|Loginsuccess}}.
+{{Identical|Login successful}}',
 'loginsuccess' => 'The content of the page saying that you are logged in. The title of the page is "[[MediaWiki:Loginsuccesstitle/{{SUBPAGENAME}}|{{int:loginsuccesstitle}}]]". $1 is the name of the logged in user.
 
 <nowiki>{{</nowiki>[[Gender|GENDER]]<nowiki>}}</nowiki> is supported.',
@@ -1086,7 +1105,7 @@ $1 is the minimum number of characters in the password.',
 * $3 is a password. Example: er##@fdas!
 * $4 is a URL. Example: http://wiki.example.com
 * $5 is a number of days in which the temporary password will expire',
-'noemail' => 'Shown as error message when trying to register a user sending password to e-mail adress and no e-mail address has been given. Registering users and sending a password to an e-mail address may require non-standard user rights ([http://translatewiki.net/w/i.php?title=Special:UserLogin&action=submitlogin&type=signup register user link]).
+'noemail' => 'Shown as error message when trying to register a user sending password to e-mail adress and no e-mail address has been given. Registering users and sending a password to an e-mail address may require non-standard user rights ([{{canonicalurl:Special:UserLogin|action=submitlogin&type=signup}} register user link]).
 
 Parameters:
 * $1 is a user name. This parameter can be used with GENDER.',
@@ -1303,7 +1322,8 @@ See also:
 See also:
 * {{msg-mw|Showpreview}}
 * {{msg-mw|Accesskey-preview}}
-* {{msg-mw|Tooltip-preview}}',
+* {{msg-mw|Tooltip-preview}}
+{{Identical|Show preview}}',
 'showlivepreview' => 'An edit preview without needing to reload the edit form.',
 'showdiff' => 'Button below the edit page. See also {{msg|showpreview}} and {{msg|savearticle}} for the other buttons.
 
@@ -1366,7 +1386,8 @@ See also:
 'loginreqtitle' => 'Used as title of error message.
 
 See also:
-* {{msg-mw|permissionserrors}}',
+* {{msg-mw|permissionserrors}}
+{{Identical|Login required}}',
 'loginreqlink' => 'Take a look on inflection. Used as parameter in {{msg-mw|loginreqpagetext}}, {{msg-mw|whitelistedittext}}, {{msg-mw|watchlistanontext‎}} and {{msg-mw|Confirmemail needlogin}}.
 
 {{Identical|Log in}}',
@@ -1389,12 +1410,12 @@ See also {{msg-mw|Noarticletext-nopermission}}.',
 'noarticletext-nopermission' => 'See also {{msg-mw|Noarticletext}}.',
 'missing-revision' => 'Text displayed when the requested revision does not exist using a permalink.
 
-Example: [http://translatewiki.net/w/i.php?title=Project:News&oldid=9999999 Permalink with invalid revision#]
+Example: [{{canonicalurl:Project:News|oldid=9999999}} Permalink with invalid revision#]
 
 * $1 is the ID of the missing revision',
 'userpage-userdoesnotexist' => 'Error message displayed when trying to edit or create a page or a subpage that belongs to a user who is not registered on the wiki. Parameters:
 * $1 is a possible username that has not been registered.',
-'userpage-userdoesnotexist-view' => 'Shown in user pages of non existing users. See for example [http://translatewiki.net/wiki/User:Foo User:Foo]. Parameters:
+'userpage-userdoesnotexist-view' => 'Shown in user pages of non existing users. See for example [{{canonicalurl:User:Foo}} User:Foo]. Parameters:
 * $1 is a username.',
 'blocked-notice-logextract' => 'Parameters:
 * $1 is the name of the blocked user (optional). Can be used for GENDER.',
@@ -1485,8 +1506,8 @@ See also:
 
 See also:
 * {{msg-mw|Nocreatetext}}',
-'sectioneditnotsupported-title' => 'Page title of special page, which presumably appears when someone tries to edit a section, and section editing is disabled. Explanation of section editing on [http://meta.wikimedia.org/wiki/Help:Section_editing#Section_editing meta].',
-'sectioneditnotsupported-text' => 'I think this is the text of an error message, which presumably appears when someone tries to edit a section, and section editing is disabled. Explanation of section editing on [http://meta.wikimedia.org/wiki/Help:Section_editing#Section_editing meta].',
+'sectioneditnotsupported-title' => 'Page title of special page, which presumably appears when someone tries to edit a section, and section editing is disabled. Explanation of section editing on [[meta:Help:Section_editing#Section_editing|meta]].',
+'sectioneditnotsupported-text' => 'I think this is the text of an error message, which presumably appears when someone tries to edit a section, and section editing is disabled. Explanation of section editing on [[meta:Help:Section_editing#Section_editing|meta]].',
 'permissionserrors' => 'Used as title of error message.
 
 See also:
@@ -1500,7 +1521,7 @@ See also:
 
 Please report at [[Support]] if you are unable to properly translate this message. Also see [[bugzilla:14246]]',
 'recreate-moveddeleted-warn' => 'Warning shown when creating a page which has already been deleted. See for example [[Test]].',
-'moveddeleted-notice' => 'Shown on top of a deleted page in normal view modus ([http://translatewiki.net/wiki/Test example]).',
+'moveddeleted-notice' => 'Shown on top of a deleted page in normal view modus ([{{canonicalurl:Test}} example]).',
 'log-fulllog' => 'Used as link text.',
 'edit-hook-aborted' => 'Used as error message.
 
@@ -1609,23 +1630,35 @@ See also:
 
 * <tt>$1</tt> is the value of the node-count limit
 * <tt>$2</tt> is the value of the max node-count limit',
-'expansion-depth-exceeded-category' => 'This message is used as a category name for a [[mw:Help:Tracking categories|tracking category]] where pages are placed automatically if the [http://meta.wikimedia.org/wiki/Help:Expansion_depth expansion depth] of the preprocessor exceeds the limit.',
-'expansion-depth-exceeded-warning' => 'Error message shown when a page exceeded the [http://meta.wikimedia.org/wiki/Help:Expansion_depth expansion depth limit] of the preprocessor
+'expansion-depth-exceeded-category' => 'This message is used as a category name for a [[mw:Help:Tracking categories|tracking category]] where pages are placed automatically if the [[meta:Help:Expansion_depth|expansion depth]] of the preprocessor exceeds the limit.',
+'expansion-depth-exceeded-warning' => 'Error message shown when a page exceeded the [[meta:Help:Expansion_depth|expansion depth limit]] of the preprocessor.
 
+Parameters:
 * <tt>$1</tt> is the value of the depth limit
 * <tt>$2</tt> is the value of the max depth limit',
-'parser-unstrip-loop-warning' => 'This error is shown when a parser extension tag such as &lt;pre> includes a reference to itself in its own output.
+'parser-unstrip-loop-warning' => '{{Doc-important|Do not translate function name "<code>unstrip</code>".}}
+This error is shown when a parser extension tag such as &lt;pre> includes a reference to itself in its own output.
+
 The reference must be to the exact same invocation of the tag at the same location in the source, merely writing &lt;pre>&lt;pre>&lt;/pre>&lt;/pre> will not do it.
+
 This is usually impossible and unlikely to happen by accident, so translation is not essential.
-"Unstrip" refers to the internal function of the parser, called \'unstrip\', which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above. See also:
+
+"Unstrip" refers to the internal function of the parser, called \'unstrip\', which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.
+
+See also:
 *{{msg-mw|Parser-unstrip-recursion-limit}}',
-'parser-unstrip-recursion-limit' => 'This message is shown when the recursion limit for nested parser extension tags is exceeded.
+'parser-unstrip-recursion-limit' => '{{doc-important|Do not translate function name "<code>unstrip</code>".}}
+This message is shown when the recursion limit for nested parser extension tags is exceeded.
+
 This warning may be encountered due to input text like &lt;ref>&lt;ref>&lt;ref>...&lt;/ref>&lt;/ref>&lt;/ref>.
 
-* <tt>$1</tt> is the depth limit
+Parameters:
+* $1 - the depth limit
+
+"Unstrip" refers to the internal function of the parser, called \'unstrip\', which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.
 
-"Unstrip" refers to the internal function of the parser, called \'unstrip\', which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above. See also:
-*{{msg-mw|Parser-unstrip-loop-warning}}',
+See also:
+* {{msg-mw|Parser-unstrip-loop-warning}}',
 'converter-manual-rule-error' => "This message is shown when a manual conversion rule for the language converter has errors. For example it's not using the correct syntax, or not supplying text in all variants.",
 
 # "Undo" feature
@@ -1870,10 +1903,10 @@ Possible alternative message - 'Restrictions could not be set on the visibility
 'revdel-restore-deleted' => '{{RevisionDelete}}',
 'revdel-restore-visible' => '{{RevisionDelete}}',
 'pagehist' => '{{RevisionDelete}}
-
-Links to page history at Special:RevisionDelete header together with links to the logs and Special:Undelete.',
+Links to page history at Special:RevisionDelete header together with links to the logs and [[Special:Undelete]].
+{{Identical|Page history}}',
 'deletedhist' => '{{RevisionDelete}}
-Links to Special:Undelete at Special:RevisionDelete header together with links to the logs and page history.',
+Links to [[Special:Undelete]] at [[Special:RevisionDelete]] header together with links to the logs and page history.',
 'revdelete-hide-current' => '{{RevisionDelete}}
 Parameters:
 * $1 is a date
@@ -2057,7 +2090,7 @@ The log and its associated special page 'MergeHistory' is not enabled by default
 
 Please note that the parameters in a log entry will appear in the log only in the default language of the wiki. View [[Special:Log]] for examples on translatewiki.net with English default language.",
 'revertmerge' => 'Used as link text',
-'mergelogpagetext' => 'Description of the [http://translatewiki.net/w/i.php?title=Special%3ALog&type=merge&user=&page=&year=&month=-1 merge log], on the log. The associated [[Special:MergeHistory|Merge]] special page is not enabled by default.',
+'mergelogpagetext' => 'Description of the [{{canonicalurl:Special:Log|type=merge&user=&page=&year=&month=-1}} merge log], on the log. The associated [[Special:MergeHistory|Merge]] special page is not enabled by default.',
 
 # Diffs
 'history-title' => 'Displayed as page title when you click on the "history" tab. The parameter $1 is the normal page title.',
@@ -2074,9 +2107,9 @@ See also:
 * {{msg-mw|Tooltip-compareselectedversions}}',
 'showhideselectedversions' => 'Text of the button which brings up the [[mw:RevisionDelete|RevisionDelete]] menu on history pages.',
 'editundo' => 'Undo link when viewing diffs
-{{Identical|Undo}}
 
-This message has sometimes a tooltip {{msg-mw|tooltip-undo}}',
+This message has sometimes a tooltip {{msg-mw|tooltip-undo}}
+{{Identical|Undo}}',
 'diff-multi' => "This message appears in the revision history of a page when comparing two versions which aren't consecutive.
 
 *Parameter $1 is the number of revisions
@@ -2086,7 +2119,7 @@ This message has sometimes a tooltip {{msg-mw|tooltip-undo}}',
 * $2 is the number of users that were found, which was limited at 100.",
 'difference-missing-revision' => 'Text displayed when the requested revision does not exist using a diff link.
 
-Example: [http://translatewiki.net/w/i.php?title=Project:News&diff=426850&oldid=99999999 Diff with invalid revision#]
+Example: [{{canonicalurl:Project:News|diff=426850&oldid=99999999}} Diff with invalid revision#]
 
 * $1 is the list of missing revisions IDs
 * $2 is the number of items in $1 (one or two)',
@@ -2148,7 +2181,7 @@ Parameters:
 * $1 - prefix string',
 'searchprofile-articles' => "A quick link in the advanced search box on [[Special:Search]]. Clicking on this link starts a search in the content pages of the wiki.
 
-A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [//www.mediawiki.org/wiki/Manual:Using_custom_namespaces#Content_namespaces Mediawiki].
+A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].
 
 Possible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.
 
@@ -2248,10 +2281,10 @@ See also:
 'powersearch-ns' => 'Used in the extended search form at [[Special:Search]]',
 'powersearch-redir' => 'Used in the extended search form at [[Special:Search]]',
 'powersearch-field' => 'Used in the extended search form at [[Special:Search]]',
-'powersearch-togglelabel' => 'Used in [http://translatewiki.net/w/i.php?title=Special:Search&advanced=1 Advanced search]. Synonym: "Select" as verb.',
-'powersearch-toggleall' => '"All" refers to namespaces. It is used in Advanced search: http://translatewiki.net/w/i.php?title=Special:Search&advanced=1
+'powersearch-togglelabel' => 'Used in [{{canonicalurl:Special:Search|advanced=1}} Advanced search]. Synonym: "Select" as verb.',
+'powersearch-toggleall' => '"All" refers to namespaces. It is used in Advanced search: {{canonicalurl:Special:Search|advanced=1}}
 {{Identical|All}}',
-'powersearch-togglenone' => '"None" refers to namespaces. It is used in Advanced search: http://translatewiki.net/w/i.php?title=Special:Search&advanced=1
+'powersearch-togglenone' => '"None" refers to namespaces. It is used in Advanced search: {{canonicalurl:Special:Search|advanced=1}}
 {{Identical|None}}',
 'search-external' => 'Legend of the fieldset for the input form when the internal search is disabled. Inside the fieldset [[MediaWiki:Searchdisabled]] and [[MediaWiki:Googlesearch]] is shown.',
 'searchdisabled' => '{{doc-singularthey}}
@@ -2269,10 +2302,9 @@ Shown on [[Special:Search]] when the internal search is disabled.',
 'qbsettings-directionality' => '"Fixed", as in the position "fixed left or right". For left-to-right languages, the quickbar will be positioned at the left, for right-to-left languages at the right.',
 
 # Preferences page
-'preferences' => 'Title of the Special:Preferences page.
-
+'preferences' => 'Title of the [[Special:Preferences]] page.
 {{Identical|Preferences}}',
-'mypreferences' => 'Action link label that leads to Special:Preferences; appears in the top menu (e.g. "Username Talk Preferences Watchlist Contributions Log out").
+'mypreferences' => 'Action link label that leads to [[Special:Preferences]]; appears in the top menu (e.g. "Username Talk Preferences Watchlist Contributions Log out").
 
 See also:
 * {{msg-mw|Mypreferences}}
@@ -2388,15 +2420,15 @@ This option lets your time zone setting use the one that is used on the wiki (of
 Shown as legend of the second fieldset of the tab 'Search' in [[Special:Preferences]]",
 'defaultns' => 'Used in [[Special:Preferences]], tab "Search".',
 'default' => '{{Identical|Default}}',
-'prefs-files' => 'Title of a tab in [[Special:Preferences]].',
+'prefs-files' => 'Title of a tab in [[Special:Preferences]].
+{{Identical|File}}',
 'prefs-custom-css' => 'visible on [[Special:Preferences]] -[Skins].',
 'prefs-custom-js' => 'visible on [[Special:Preferences]] -[Skins].',
 'prefs-common-css-js' => 'Used as label in [[Special:Preferences#mw-prefsection-rendering|preferences]], tab "Appearance", section "Skin".',
 'prefs-reset-intro' => 'Used in [[Special:Preferences/reset]].',
 'prefs-emailconfirm-label' => 'Sub-heading in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}.',
 'prefs-textboxsize' => "Header for the box specifying the size of the editing window, displayed on the 'editing' tab of the [[Special:Preferences|user preferences]] special page.",
-'youremail' => 'Label of the e-mail text box of the "E-mail options" section of "Special:Preferences".
-
+'youremail' => 'Label of the e-mail text box of the "E-mail options" section of [[Special:Preferences]].
 {{Identical|E-mail}}',
 'username' => 'Username field in [[Special:Preferences]]. $1 is the current user name for GENDER distinction (depends on sex setting).
 
@@ -2459,10 +2491,12 @@ See also:
 * {{msg-mw|prefs-help-email-others|help}}
 * {{msg-mw|prefs-changeemail|link title}}
 * {{msg-mw|prefs-setemail|link title}}',
-'prefs-info' => "Header for the box giving basic information on the user account, displayed on the 'user profile' tab of the [[Special:Preferences|user preferences]] special page.",
+'prefs-info' => "Header for the box giving basic information on the user account, displayed on the 'user profile' tab of the [[Special:Preferences|user preferences]] special page.
+{{Identical|Basic information}}",
 'prefs-i18n' => 'Field set legend for user preferences regarding the interface language',
 'prefs-signature' => '{{Identical|Signature}}',
-'prefs-dateformat' => 'Used in [[Special:Preferences#mw-prefsection-datetime|Special:Preferences]], tab "Date and time".',
+'prefs-dateformat' => 'Used in [[Special:Preferences#mw-prefsection-datetime|Special:Preferences]], tab "Date and time".
+{{Identical|Date format}}',
 'prefs-timeoffset' => 'Used in [[Special:Preferences]], tab "Date and time".',
 'prefs-advancedediting' => 'Used in [[Special:Preferences]], tab "Editing".
 {{Identical|Advanced options}}',
@@ -2530,7 +2564,7 @@ Parameters:
 {{Identical|Reason}}',
 'userrights-no-interwiki' => 'Error message when editing user groups',
 'userrights-nodatabase' => 'Error message when editing user groups. "Local" means databases/wikis of the same farm/cluster; that is, meta, enwiki, dewiki, commons, etc are all local databases of the Wikimedia Foundation.
-See http://meta.wikimedia.org/w/index.php?title=Special%3ALog&type=rights for a usage of local databases: username@barwiki',
+See [{{canonicalurl:meta:Special:Log|type=rights}} meta:Special:Log?type=rights] for a usage of local databases: username@barwiki',
 'userrights-nologin' => "Error displayed on [[Special:UserRights]] when you aren't logged in. If you are logged in, but don't have the correct permission, you see {{msg|userrights-notallowed|pl=yes}}.",
 'userrights-notallowed' => "Error displayed on [[Special:UserRights]] when you don't have the permission.",
 'userrights-changeable-col' => 'Used when editing user groups in [[Special:Userrights]]. The message is the head of a column of group assignements.
@@ -2599,7 +2633,8 @@ The right to move any page that is not protected from moving.
 'right-movefile' => '{{doc-right|movefile}}',
 'right-suppressredirect' => '{{doc-right|suppressredirect}}',
 'right-upload' => '{{doc-right|upload}}
-The right to [[Special:Upload|upload]] a file (this includes images, media, audio, ...).',
+The right to [[Special:Upload|upload]] a file (this includes images, media, audio, ...).
+{{Identical|Upload file}}',
 'right-reupload' => '{{doc-right|reupload}}
 The right to upload a file under a file name that already exists.
 
@@ -2742,7 +2777,7 @@ In [[Special:Log]]',
 'action-upload_by_url' => '{{Doc-action|upload by url}}',
 'action-writeapi' => '{{Doc-action|writeapi}}
 
-API is an abbreviation for [http://en.wikipedia.org/wiki/API application programming interface].',
+API is an abbreviation for [[w:API|application programming interface]].',
 'action-delete' => '{{Doc-action|delete}}',
 'action-deleterevision' => '{{Doc-action|deleterevision}}',
 'action-deletedhistory' => '{{Doc-action|deletedhistory}}',
@@ -2777,7 +2812,7 @@ See also:
 {{Identical|Recent changes}}',
 'recentchanges-legend' => 'Legend of the fieldset of [[Special:RecentChanges]]',
 'recentchanges-summary' => 'Summary of [[Special:RecentChanges]].',
-'recentchanges-feed-description' => 'Used in feed of RecentChanges. See example [http://translatewiki.net/w/i.php?title=Special:RecentChanges&feed=atom feed].',
+'recentchanges-feed-description' => 'Used in feed of RecentChanges. See example [{{canonicalurl:Special:RecentChanges|feed=atom}} feed].',
 'recentchanges-label-newpage' => 'Tooltip for {{msg-mw|newpageletter}}',
 'recentchanges-label-minor' => 'Tooltip for {{msg-mw|minoreditletter}}',
 'recentchanges-label-bot' => 'Tooltip for {{msg-mw|boteditletter}}',
@@ -2806,7 +2841,8 @@ Similar to {{msg-mw|wlnote}} which is used on [[Special:Watchlist]].
 {{Identical|$1 bots}}",
 'rcshowhideliu' => 'Option text in [[Special:RecentChanges]]',
 'rcshowhideanons' => "Option text in [[Special:RecentChanges]]. Parameters:
-* $1 is the 'show/hide' command, with the text taken from either {{msg-mw|show}} or {{msg-mw|hide}}.",
+* $1 is the 'show/hide' command, with the text taken from either {{msg-mw|show}} or {{msg-mw|hide}}.
+{{Identical|Anonymous user}}",
 'rcshowhidepatr' => "Option text in [[Special:RecentChanges]]. Parameters:
 * $1 is the 'show/hide' command, with the text taken from either {{msg-mw|show}} or {{msg-mw|hide}}.",
 'rcshowhidemine' => "Option text in [[Special:RecentChanges]]. Parameters:
@@ -2927,7 +2963,7 @@ See also:
 * {{msg-mw|Filesource}}
 {{Identical|Summary}}',
 'fileuploadsummary' => '{{Identical|Summary}}',
-'filereuploadsummary' => 'Label of textearea in Special:Upload when uploading a new version of existing file.',
+'filereuploadsummary' => 'Label of textearea in [[Special:Upload]] when uploading a new version of existing file.',
 'filestatus' => 'Used as section header in [[Special:Upload]].
 
 See also:
@@ -3144,15 +3180,29 @@ See also:
 * {{msg-mw|hookaborted}}
 * {{msg-mw|filename-toolong}}
 * {{msg-mw|unknown-error}}',
-'fileexists' => "{{doc-important|''thumb'' is a magic word. Leave it untranslated!}}",
+'fileexists' => "{{doc-important|''thumb'' is a magic word. Leave it untranslated!}}
+Parameters:
+* $1 - name of the existing file",
 'filepageexists' => "{{doc-important|''thumb'' is a magic word. Leave it untranslated!}}
-Shown on [[Special:Upload]], $1 is link to the page. This message is displayed if a description page exists, but a file with the same name does not yet exists, and a user tries to upload a file with that name. In that case the description page is not changed, even if the uploading user specifies a description with the upload.",
-'fileexists-extension' => "{{doc-important|''thumb'' is a magic word. Leave it untranslated!}}",
-'fileexists-thumbnail-yes' => "{{doc-important|''thumb'' is a magic word. Leave it untranslated!}}",
-'file-thumbnail-no' => 'Error message at [[Special:Upload]]',
-'fileexists-forbidden' => "{{doc-important|''thumb'' and ''center'' are magic words. Leave it untranslated!}}",
+Shown on [[Special:Upload]]. Parameters:
+* $1 - link to the page
+This message is displayed if a description page exists, but a file with the same name does not yet exists, and a user tries to upload a file with that name. In that case the description page is not changed, even if the uploading user specifies a description with the upload.",
+'fileexists-extension' => "{{doc-important|''thumb'' is a magic word. Leave it untranslated!}}
+Parameters:
+* $1 - name of the uploading file
+* $2 - name of the existing file",
+'fileexists-thumbnail-yes' => "{{doc-important|''thumb'' is a magic word. Leave it untranslated!}}
+Parameters:
+* $1 - name of thumbnail file",
+'file-thumbnail-no' => 'Error message at [[Special:Upload]]. Parameters:
+* $1 - String (e.g. "180px-")',
+'fileexists-forbidden' => "{{doc-important|''thumb'' and ''center'' are magic words. Leave it untranslated!}}
+Parameters:
+* $1 - name of the existing file",
 'fileexists-shared-forbidden' => "{{doc-important|''thumb'' and ''center'' are magic words. Leave it untranslated!}}
-Error message at [[Special:Upload]]",
+Error message at [[Special:Upload]].
+Parameters:
+* $1 - name of the existing file",
 'file-exists-duplicate' => 'Used as warning in [[Special:Upload]].
 This message is followed by the gallery of the duplicate files.
 
@@ -3165,13 +3215,13 @@ Parameters:
 'savefile' => 'When uploading a file',
 'uploadedimage' => 'This is the text of an entry in the [[Special:Log|upload log]] (and Recent Changes), after hour (and date, only in the Upload log) and user name. $1 is the name of the file uploaded.',
 'overwroteimage' => 'This is the text of an entry in the [[Special:Log|upload log]] (and Recent Changes), after hour (and date, only in the Upload log) and user name. $1 is the name of the file uploaded.',
-'uploaddisabled' => 'Title of the Special:Upload page when upload is disabled.
+'uploaddisabled' => 'Title of the [[Special:Upload]] page when upload is disabled.
 
 See also:
 * {{msg-mw|Copyuploaddisabled}}',
 'copyuploaddisabled' => 'See also:
 * {{msg-mw|Uploaddisabled}}',
-'uploaddisabledtext' => 'This message can have parameter $1, which contains the name of the target file. See r22243 and [https://bugzilla.wikimedia.org/show_bug.cgi?id=8818 bug 8818].',
+'uploaddisabledtext' => 'This message can have parameter $1, which contains the name of the target file. See r22243 and [[bugzilla:8818|bug 8818]].',
 'php-uploaddisabledtext' => 'This means that file uploading is disabled in PHP, not upload of PHP-files.',
 'uploadscripted' => 'Used as error message when uploading a file.
 
@@ -3278,7 +3328,7 @@ See also:
 'upload-proto-error' => 'See also:
 * {{msg-mw|Upload-proto-error|title}}
 * {{msg-mw|Upload-proto-error-text|text}}',
-'upload-proto-error-text' => '"Remote upload" is explained on [http://en.wikipedia.org/wiki/Uploading_and_downloading#Remote_upload Wikipedia].
+'upload-proto-error-text' => '"Remote upload" is explained on [[w:Uploading_and_downloading#Remote_upload|Wikipedia]].
 
 See also:
 * {{msg-mw|Upload-proto-error|title}}
@@ -3375,17 +3425,17 @@ A "[[:wikipedia:Front and back ends|backend]]" is a system or component that ord
 'lockmanager-fail-closelock' => 'Parameters:
 * $1 is a resource path (e.g. "mwstore://media-public/a/ab/file.jpg").
 
-A "[http://en.wikipedia.org/wiki/File_locking#Lock_files lock file]" signals by its presence that some resource is locked.',
+A "[[w:File_locking#Lock_files|lock file]]" signals by its presence that some resource is locked.',
 'lockmanager-fail-deletelock' => 'Parameters:
 * $1 is a resource path (e.g. "mwstore://media-public/a/ab/file.jpg").
 
-A "[http://en.wikipedia.org/wiki/File_locking#Lock_files lock file]" signals by its presence that some resource is locked.',
+A "[[w:File_locking#Lock_files|lock file]]" signals by its presence that some resource is locked.',
 'lockmanager-fail-acquirelock' => 'Parameters:
 * $1 is a resource path (e.g. "mwstore://media-public/a/ab/file.jpg").',
 'lockmanager-fail-openlock' => 'Parameters:
 * $1 is a resource path (e.g. "mwstore://media-public/a/ab/file.jpg").
 
-A "[http://en.wikipedia.org/wiki/File_locking#Lock_files lock file]" signals by its presence that some resource is locked.',
+A "[[w:File_locking#Lock_files|lock file]]" signals by its presence that some resource is locked.',
 'lockmanager-fail-releaselock' => 'Parameters:
 * $1 is a resource path (e.g. "mwstore://media-public/a/ab/file.jpg").',
 'lockmanager-fail-db-bucket' => 'The databases store what is locked by who. Parameters:
@@ -3490,7 +3540,9 @@ See also:
 * {{msg-mw|Http-request-error}}
 * {{msg-mw|Http-read-error}}
 * {{msg-mw|Http-timed-out|28}}',
-'http-bad-status' => '$1 is an HTTP error code (e.g. 404), $2 is the HTTP error message (e.g. File Not Found)',
+'http-bad-status' => 'Parameters:
+* $1 - an HTTP error code (e.g. 404)
+* $2 - the HTTP error message (e.g. File Not Found)',
 
 # Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
 'upload-curl-error6' => 'See also:
@@ -3547,7 +3599,8 @@ See also:
 {{Identical|Size}}',
 'listfiles_description' => 'Column header for the result table displayed on [[Special:ListFiles]].
 {{Identical|Description}}',
-'listfiles_count' => 'One of the table column headers in [[Special:Listfiles]] denoting the amount of saved versions of that file.',
+'listfiles_count' => 'One of the table column headers in [[Special:Listfiles]] denoting the amount of saved versions of that file.
+{{Identical|Version}}',
 
 # File description page
 'file-anchor-link' => '{{Identical|File}}',
@@ -3604,7 +3657,7 @@ Parameters:
 
 * $1: Number of identical files
 * $2: Name of the shown file to link to the special page "FileDuplicateSearch"',
-'sharedupload' => 'Shown on an image description page when it is used in a central repository (i.e. [http://commons.wikimedia.org/ Commons] for Wikimedia wikis).
+'sharedupload' => 'Shown on an image description page when it is used in a central repository (i.e. [[commons:|Commons]] for Wikimedia wikis).
 
 * $1 is the name of the shared repository. On Wikimedia sites, $1 is {{msg-mw|shared-repo-name-shared}}. The default value for $1 is {{msg-mw|shared-repo}}.
 
@@ -3652,7 +3705,8 @@ $1 is the name of the shared repository. On wikimedia sites, $1 is {{msg-mw|shar
 'shared-repo' => 'This message can be used as parameter $1 in the following messages:
 * {{msg-mw|shared-repo-from}}
 * {{msg-mw|sharedupload}}, {{msg-mw|sharedupload-desc-here}}, {{msg-mw|sharedupload-desc-there}}',
-'shared-repo-name-wikimediacommons' => '{{optional}}',
+'shared-repo-name-wikimediacommons' => '{{optional}}
+{{Identical|Wikimedia Commons}}',
 'filepage.css' => '{{Optional}}',
 'upload-disallowed-here' => 'This message appears on an image page in place of the normal reupload link if they cannot upload - e.g. if the image page is upload protected and they do not have the right priviledge.',
 
@@ -3762,11 +3816,12 @@ See also:
 'statistics-header-pages' => 'Used in [[Special:Statistics]]',
 'statistics-header-edits' => 'Used in [[Special:Statistics]]',
 'statistics-header-views' => 'Used in [[Special:Statistics]]',
-'statistics-header-users' => 'Used in [[Special:Statistics]]',
+'statistics-header-users' => 'Used in [[Special:Statistics]].
+{{Identical|User statistics}}',
 'statistics-header-hooks' => 'Header of a section on [[Special:Statistics]] containing data provided by MediaWiki extensions',
 'statistics-articles' => "Used in [[Special:Statistics]].
 
-A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [//www.mediawiki.org/wiki/Manual:Using_custom_namespaces#Content_namespaces Mediawiki].
+A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].
 
 Possible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.
 
@@ -3779,7 +3834,8 @@ Possible alternatives to the word 'content' are 'subject matter' or 'wiki subjec
 'statistics-edits-average' => 'Used in [[Special:Statistics]]',
 'statistics-views-total' => 'Used in [[Special:Statistics]]',
 'statistics-views-peredit' => 'Used in [[Special:Statistics]]',
-'statistics-users' => 'Used in [[Special:Statistics]]. Do not change "Special:ListUsers"!',
+'statistics-users' => '{{doc-important|Do not translate "Special:ListUsers"}}
+Used in [[Special:Statistics]].',
 'statistics-users-active' => 'Used in [[Special:Statistics]]',
 'statistics-users-active-desc' => "Description shown beneath ''Active users'' in [[Special:Statistics]]
 
@@ -3790,11 +3846,10 @@ Possible alternatives to the word 'content' are 'subject matter' or 'wiki subjec
 'disambiguationspage' => 'This message is the name of the template used for marking disambiguation pages. It is used by [[Special:Disambiguations]] to find all pages which link to disambiguation pages.
 
 {{doc-important|Don\'t translate the "Template:" part!}}',
-'disambiguations-text' => "This block of text is shown on [[:Special:Disambiguations]].
+'disambiguations-text' => '{{doc-important|Do not change the link "<code><nowiki>[[MediaWiki:Disambiguationspage]]</nowiki></code>", even because it is listed as problematic. Be sure the "D" is in uppercase, so not "d".}}
+This block of text is shown on [[:Special:Disambiguations]].
 
-* '''Note:''' Do not change the link [[MediaWiki:Disambiguationspage]], even because it is listed as problematic. Be sure the \"D\" is in uppercase, so not \"d\".
-
-* '''Background information:''' Beyond telling about links going to disambiguation pages, that they are generally bad, it should explain which pages in the article namespace are seen as disambiguations: [[MediaWiki:Disambiguationspage]] usually holds a list of disambiguation templates of the local wiki. Pages linking to one of them (by transclusion) will count as disambiguation pages. Pages linking to these disambiguation pages, instead to the disambiguated article itself, are listed on [[:Special:Disambiguations]].",
+\'\'\'Background information:\'\'\' Beyond telling about links going to disambiguation pages, that they are generally bad, it should explain which pages in the article namespace are seen as disambiguations: [[MediaWiki:Disambiguationspage]] usually holds a list of disambiguation templates of the local wiki. Pages linking to one of them (by transclusion) will count as disambiguation pages. Pages linking to these disambiguation pages, instead to the disambiguated article itself, are listed on [[:Special:Disambiguations]].',
 
 'doubleredirects' => 'Name of [[Special:DoubleRedirects]] displayed in [[Special:SpecialPages]]',
 'doubleredirectstext' => 'Shown on top of [[Special:Doubleredirects]]',
@@ -3866,8 +3921,8 @@ $1 is a page title",
 'protectedpages-cascade' => 'Option in [[Special:ProtectedPages]]',
 'protectedpagestext' => 'Shown on top of [[Special:ProtectedPages]]',
 'protectedtitles' => 'Name of special page displayed in [[Special:SpecialPages]]',
-'protectedtitlestext' => 'Shown on top of list of titles on [[Special:ProtectedTitles]]. If the list is empty the message [[MediaWiki:Protectedtitlesempty]] appears instead of this. See the [//www.mediawiki.org/wiki/Project:Protected_titles help page on Mediawiki] for more information.',
-'protectedtitlesempty' => 'Used on [[Special:ProtectedTitles]]. This text appears if the list of protected titles is empty. See the [//www.mediawiki.org/wiki/Project:Protected_titles help page on Mediawiki] for more information.',
+'protectedtitlestext' => 'Shown on top of list of titles on [[Special:ProtectedTitles]]. If the list is empty the message [[MediaWiki:Protectedtitlesempty]] appears instead of this. See the [[mw:Project:Protected_titles|help page on MediaWiki]] for more information.',
+'protectedtitlesempty' => 'Used on [[Special:ProtectedTitles]]. This text appears if the list of protected titles is empty. See the [[mw:Project:Protected_titles|help page on MediaWiki]] for more information.',
 'listusers' => 'Name of special page displayed in [[Special:SpecialPages]]',
 'listusers-editsonly' => 'Option in [[Special:ListUsers]].',
 'listusers-creationsort' => 'Option in [[Special:ListUsers]].',
@@ -3994,7 +4049,10 @@ Title of [[Special:Log]].',
 'categories' => 'The page name of [[Special:Categories]].
 
 {{Identical|Categories}}',
-'categoriespagetext' => "Text displayed in [[Special:Categories]]. Do not translate or change links. In order to translate ''Unused categories'' and ''wanted categories'' see {{msg|unusedcategories}} and {{msg|wantedcategories}}.",
+'categoriespagetext' => "{{doc-important|Do not translate or change links.}}
+Text displayed in [[Special:Categories]].
+
+In order to translate ''Unused categories'' and ''wanted categories'' see {{msg|unusedcategories}} and {{msg|wantedcategories}}.",
 'special-categories-sort-count' => 'This message is used on [[Special:Categories]] to sort the list by the number of members in the categories.',
 
 # Special:DeletedContributions
@@ -4004,7 +4062,8 @@ Title of [[Special:Log]].',
 'deletedcontributions-title' => 'Title of [[Special:DeletedContributions]] (extension), a special page with a list of edits to pages which were deleted. Only viewable by sysops.
 
 {{Identical|Deleted user contributions}}',
-'sp-deletedcontributions-contribs' => 'Link to user’s contributions on [[Special:DeletedContributions]]',
+'sp-deletedcontributions-contribs' => 'Link to user’s contributions on [[Special:DeletedContributions]].
+{{Identical|Contribution}}',
 
 # Special:LinkSearch
 'linksearch' => 'Title of [[Special:LinkSearch|special page]] and legend of fieldset on that page.
@@ -4041,8 +4100,8 @@ You can apparently use 'URL' instead of 'hostname'.",
 'activeusers' => 'Title of [[Special:ActiveUsers]]',
 'activeusers-intro' => 'Used as introduction in [[Special:ActiveUsers]]. Parameters:
 * $1 - number of days (<code>$wgActiveUserDays</code>)',
-'activeusers-count' => "Used in [[Special:ActiveUsers]] to show the active user's recent edit count in brackets ([]).
-* $1 is the number of recent edits
+'activeusers-count' => "Used in [[Special:ActiveUsers]] to show the active user's recent action count in brackets ([]).
+* $1 is the number of recent actions
 * $2 is the user's name for use with GENDER (optional)
 * $3 is the maximum number of days of the RecentChangesList",
 'activeusers-from' => 'Used as label for checkbox in the form on [[Special:ActiveUsers]].
@@ -4133,7 +4192,7 @@ Special:EmailUser appears when you click on the link "E-mail this user" in the s
 'usermaildisabledtext' => 'Used as error message in [[Special:EmailUser]].
 
 The title for this error message is {{msg-mw|Usermaildisabled}}.',
-'noemailtitle' => 'The title of the message that appears instead of Special:EmailUser after clicking the "E-mail this user" link in the sidebar, if no e-mail can be sent to the user.',
+'noemailtitle' => 'The title of the message that appears instead of [[Special:EmailUser]] after clicking the "E-mail this user" link in the sidebar, if no e-mail can be sent to the user.',
 'noemailtext' => 'The text of the message that appears in [[Special:EmailUser]] after clicking the "E-mail this user" link in the sidebar, if no e-mail can be sent to the user because he has not specified or not confirmed an e-mail address.',
 'nowikiemailtext' => 'This is an error message used in [[Special:Emailuser]] when called with a target user not consenting to be an e-mail recipient.',
 'emailnotarget' => 'This is an error message that may be used in [[Special:Emailuser]] when called without a (valid) target user for the e-mail.',
@@ -4160,8 +4219,8 @@ This is a button text used in [[Special:Emailuser]] when called without a (valid
 {{Identical|Send}}',
 'emailccme' => 'Used at [[Special:Preferences]] > E-mail',
 'emailccsubject' => 'Subject of the carbon-copied  email for the sender sent through MediaWiki.',
-'emailsent' => 'Title of Special:Emailuser when it says you it sent an email',
-'emailsenttext' => 'When you send an e-mail, Special:Emailuser says you this (Your email has been sent).',
+'emailsent' => 'Title of [[Special:EmailUser]] when it says you it sent an email',
+'emailsenttext' => 'When you send an e-mail, [[Special:EmailUser]] says you this (Your email has been sent).',
 'emailuserfooter' => 'This message is appended to every email sent through the "Email user" function.
 
 * $1: username of the sender
@@ -4169,7 +4228,7 @@ This is a button text used in [[Special:Emailuser]] when called without a (valid
 
 # User Messenger
 'usermessage-summary' => 'This message is used as an edit summary for any message that is posted because of a system event. Translate "leaving a message" in the sense of: to give a message to someone; to deliver a message somewhere; to deposit.',
-'usermessage-editor' => 'The user name for the user that is the editor of system messages. See [http://translatewiki.net/wiki/Thread:Support/Message_info_please discussion on Support].',
+'usermessage-editor' => 'The user name for the user that is the editor of system messages. See [{{canonicalurl:Thread:Support/Message_info_please}} discussion on Support].',
 'usermessage-template' => '{{optional}}',
 
 # Watchlist
@@ -4219,7 +4278,7 @@ See also:
 See also:
 * {{msg-mw|Watchthispage|link text}}
 * {{msg-mw|Notanarticle|error message}}',
-'notanarticle' => "A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [//www.mediawiki.org/wiki/Manual:Using_custom_namespaces#Content_namespaces Mediawiki].
+'notanarticle' => "A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].
 
 Possible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.
 
@@ -4331,7 +4390,7 @@ See also:
 **{{msg-mw|enotif body intro deleted}}
 **{{msg-mw|enotif body intro created}}
 **{{msg-mw|enotif body intro moved}}
-**{{msg-mw|enotif body intro restored}} 
+**{{msg-mw|enotif body intro restored}}
 **{{msg-mw|enotif body intro changed}} (for all the other cases).
 *$NEWPAGE consists of either
 **if the page is new (in older releases), {{msg-mw|enotif newpagetext}}
@@ -4419,7 +4478,7 @@ See also:
 'rollback' => '{{Identical|Rollback}}',
 'rollback_short' => '{{Identical|Rollback}}',
 'rollbacklink' => '{{Identical|Rollback}}
-This link text appears on the recent changes page to users who have the "rollback" right.  
+This link text appears on the recent changes page to users who have the "rollback" right.
 This message has a tooltip {{msg-mw|tooltip-rollback}}
 
 {{Doc-actionlink}}',
@@ -4507,10 +4566,10 @@ This message was something like "unlock move protection" in the past.',
 'protect-fallback' => 'This message is used as an option in the protection form on wikis were extra protection levels have been configured.',
 'protect-level-autoconfirmed' => 'Used as protect level.
 
-See example: [http://translatewiki.net/w/i.php?title=Main_Page&action=info]',
+See example: {{canonicalurl:Main_Page|action=info}}',
 'protect-level-sysop' => 'Used as protect level.
 
-See example: [http://translatewiki.net/w/i.php?title=Main_Page&action=info]',
+See example: {{canonicalurl:Main_Page|action=info}}',
 'protect-summary-desc' => '{{Optional}}
 Used in edit summary for description of a protecting restriction.
 * $1 is action, taken from restriction-*
@@ -4534,7 +4593,7 @@ See also:
 {{Identical|Other time}}',
 'protect-othertime-op' => 'Used on the page protection form in the drop down menu
 {{Identical|Other time}}',
-'protect-existing-expiry' => 'Shows the existing expiry time in the drop down menu of the protection form ([http://translatewiki.net/w/i.php?title=User:Raymond/test&action=unprotect example])
+'protect-existing-expiry' => 'Shows the existing expiry time in the drop down menu of the protection form ([{{canonicalurl:User:Raymond/test|action=unprotect}} example])
 
 * $1: date and time of the existing expiry time (kept for backward compatibility purposes)
 * $2: date of the existing expiry time
@@ -4555,11 +4614,12 @@ See also:
 'protect-expiry-options' => "{{Identical|Infinite}}{{doc-important|Be careful: '''1 translation:1 english''', so the first part is the translation and the second part should stay in English.}}
 
 Options for the duration of the page protection. Example: See e.g. [[MediaWiki:Protect-expiry-options/nl]] if you still don't know how to do it.",
-'restriction-type' => 'Used on [[Special:ProtectedPages]]. The text next to a drop-down box. See [[mw:Manual:Administrators|MediaWiki Manual]] for more information on protection.',
-'restriction-level' => 'Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. The text next to a drop-down box. See the [//www.mediawiki.org/wiki/Project:Protected_titles help page on Mediawiki] and on [http://meta.wikimedia.org/wiki/Protect Meta] for more information.',
+'restriction-type' => 'Used on [[Special:ProtectedPages]]. The text next to a drop-down box. See [[mw:Manual:Administrators|MediaWiki Manual]] for more information on protection.
+{{Identical|Permission}}',
+'restriction-level' => 'Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. The text next to a drop-down box. See the [[mw:Project:Protected_titles|help page on MediaWiki]] and on [[meta:Protect|Meta]] for more information.',
 'minimum-size' => 'Used in [[Special:Protectedpages]] as a pair of radio buttons, with {{msg-mw|Maximum-size}}. There is an input box to specify the minimum bites of the projected pages listed.',
 'maximum-size' => 'Used in [[Special:Protectedpages]] as a pair of radio buttons, with {{msg-mw|Minimum-size}}. There is an input box to specify the maximum bites of the projected pages listed.',
-'pagesize' => 'Used on [[Special:ProtectedPages]]. See the help page on [http://meta.wikimedia.org/wiki/Protect Meta] for more information on protection.',
+'pagesize' => 'Used on [[Special:ProtectedPages]]. See the help page on [[meta:Protect|Meta]] for more information on protection.',
 
 # Restrictions (nouns)
 'restriction-edit' => "Used on [[Special:ProtectedPages]]. Option in the 'permission' drop-down box.
@@ -4568,23 +4628,22 @@ Options for the duration of the page protection. Example: See e.g. [[MediaWiki:P
 'restriction-move' => "Used on [[Special:ProtectedPages]]. Option in the 'permission' drop-down box.
 
 {{Identical|Move}}",
-'restriction-create' => 'Used on [[Special:ProtectedPages]]. An option in a drop-down box. See the help pages on [//www.mediawiki.org/wiki/Project:Protected_titles MediaWiki] and [http://meta.wikimedia.org/wiki/Protect Meta] for more information on protection.
-
+'restriction-create' => 'Used on [[Special:ProtectedPages]]. An option in a drop-down box. See the help pages on [[mw:Project:Protected_titles|MediaWiki]] and [[meta:Protect|Meta]] for more information on protection.
 {{Identical|Create}}',
 'restriction-upload' => '{{Identical|Upload}}',
 
 # Restriction levels
-'restriction-level-sysop' => "Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. An option in the drop-down box 'Restriction level' and in brackets after each page name entry. See the [//www.mediawiki.org/wiki/Project:Protected_titles help page on Mediawiki] and on [http://meta.wikimedia.org/wiki/Protect Meta] for more information.
+'restriction-level-sysop' => "Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. An option in the drop-down box 'Restriction level' and in brackets after each page name entry. See the [[mw:Project:Protected_titles|help page on MediaWiki]] and on [[meta:Protect|Meta]] for more information.
 
 See also:
 *{{msg-mw|Restriction-level-autoconfirmed}}
 *{{msg-mw|Restriction-level-all}}",
-'restriction-level-autoconfirmed' => "Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. An option in the drop-down box 'Restriction level', and in brackets after each page name entry. See the [//www.mediawiki.org/wiki/Project:Protected_titles help page on Mediawiki] and on [http://meta.wikimedia.org/wiki/Protect Meta] for more information.
+'restriction-level-autoconfirmed' => "Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. An option in the drop-down box 'Restriction level', and in brackets after each page name entry. See the [[mw:Project:Protected_titles|help page on MediaWiki]] and on [[meta:Protect|Meta]] for more information.
 
 See also:
 *{{msg-mw|Restriction-level-sysop}}
 *{{msg-mw|Restriction-level-all}}",
-'restriction-level-all' => "Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. An option in the drop-down box 'Restriction level'. See the [//www.mediawiki.org/wiki/Project:Protected_titles help page on Mediawiki] and on [http://meta.wikimedia.org/wiki/Protect Meta] for more information.
+'restriction-level-all' => "Used on [[Special:ProtectedPages]] and [[Special:ProtectedTitles]]. An option in the drop-down box 'Restriction level'. See the [[mw:Project:Protected_titles|help page on MediaWiki]] and on [[meta:Protect|Meta]] for more information.
 
 See also:
 *{{msg-mw|Restriction-level-sysop}}
@@ -4701,11 +4760,10 @@ See also:
 'undelete-error-long' => 'Used as error message. See also:
 * {{msg-mw|Undelete-error-short}}
 * {{msg-mw|Undelete-error-long}}',
-'undelete-show-file-confirm' => 'A confirmation message shown on Special:Undelete when the request does not contain a valid token (e.g. when a user clicks a link received in mail).
+'undelete-show-file-confirm' => 'A confirmation message shown on [[Special:Undelete]] when the request does not contain a valid token (e.g. when a user clicks a link received in mail).
 * <code>$1</code> is the name of the file being undeleted.
 * <code>$2</code> is the date of the displayed revision.
 * <code>$3</code> is the time of the displayed revision.
-
 {{identical|Are you sure you want to view the deleted revision of the file...}}',
 'undelete-show-file-submit' => '{{Identical|Yes}}',
 'undelete-revisionrow' => "{{Optional}}
@@ -4749,7 +4807,8 @@ See also:
 See also:
 * {{msg-mw|Mycontris}}
 * {{msg-mw|Accesskey-pt-mycontris}}
-* {{msg-mw|Tooltip-pt-mycontris}}',
+* {{msg-mw|Tooltip-pt-mycontris}}
+{{Identical|Contribution}}',
 'contribsub2' => 'Contributions for "user" (links)
 {{Identical|For $1}}',
 'nocontribs' => 'Optional parameter: $1 is the user name',
@@ -4867,11 +4926,11 @@ See also:
 
 Parameter $1 is a page title.',
 'nolinkshere-ns' => '* $1 - page title',
-'isredirect' => 'Displayed in Special:WhatLinksHere (see [{{fullurl:Special:WhatLinksHere/Project:Translator|hidelinks=1}} Special:WhatLinksHere/Project:Translator] for example).
+'isredirect' => 'Displayed in [[Special:WhatLinksHere]] (see [{{fullurl:Special:WhatLinksHere/Project:Translator|hidelinks=1}} Special:WhatLinksHere/Project:Translator] for example).
 
 {{Identical|Redirect page}}',
 'istemplate' => 'Means that a page (a template, specifically) is used as <code><nowiki>{{Page name}}</nowiki></code>.
-Displayed in Special:WhatLinksHere (see [[Special:WhatLinksHere/Template:New portal]] for example).',
+Displayed in [[Special:WhatLinksHere]] (see [[Special:WhatLinksHere/Template:New portal]] for example).',
 'isimage' => 'This message is displayed on [[Special:WhatLinksHere]] for images. It means that the image is used on the page (as opposed to just being linked to like an non-image page).',
 'whatlinkshere-prev' => 'This is part of the navigation message on the top and bottom of Whatlinkshere pages, where it is used as the first argument of {{msg-mw|Viewprevnext}}.
 $1 is the number of items shown per page. It is not used when $1 is zero; not sure what happens when $1 is one.
@@ -4887,8 +4946,7 @@ Special pages use {{msg-mw|Nextn}} instead (still as an argument to {{msg-mw|Vie
 
 Example line:
 * [[Main Page]] ([[Special:WhatLinksHere/Main Page|{{int:whatlinkshere-links}}]])
-
-{{Identical|Links}}',
+{{Identical|Link}}',
 'whatlinkshere-hideredirs' => 'Filter option in [[Special:WhatLinksHere]]. Parameters:
 * $1 is the {{msg-mw|hide}} or {{msg-mw|show}}',
 'whatlinkshere-hidetrans' => 'First filter option in [[Special:WhatLinksHere]]. Parameters:
@@ -5007,7 +5065,7 @@ See also:
 * $1 - target username',
 'unblockip' => 'Used as legend for the form in [[Special:Unblock]].',
 'unblockiptext' => 'Used in the {{msg-mw|Unblockip}} form on [[Special:Unblock]].',
-'ipusubmit' => 'Used as button text on Special:BlockList?action=unblock. To see the message:
+'ipusubmit' => 'Used as button text on [{{canonicalurl:Special:BlockList|action=unblock}} Special:BlockList?action=unblock]. To see the message:
 * Go to [[Special:BlockList]]
 * Click "unblock" for any block (but you can only see "unblock" if you have administrator rights)
 * It is now the button below the form',
@@ -5041,7 +5099,7 @@ See also:
 {{Related|Blocklist-blocks}}',
 'blocklist-rangeblocks' => 'Used as the label for the multi-select checkbox in the form on [[Special:BlockList]].
 
-For an explanation of "range blocks", see http://www.mediawiki.org/wiki/Help:Range_blocks
+For an explanation of "range blocks", see [[mw:Help:Range_blocks]]
 {{Related|Blocklist-blocks}}',
 'blocklist-timestamp' => 'This is a column header for dates and times in the table on the page [[Special:BlockList]].
 {{Identical|Timestamp}}',
@@ -5125,7 +5183,8 @@ See also:
 * {{msg-mw|Sp-contributions-uploads}}
 * {{msg-mw|Sp-contributions-logs}}
 * {{msg-mw|Sp-contributions-deleted}}
-* {{msg-mw|Sp-contributions-userrights}}",
+* {{msg-mw|Sp-contributions-userrights}}
+{{Identical|Block}}",
 'unblocklink' => 'Used as link title in [[Special:Contributions]] and in [[Special:DeletedContributions]].
 
 See also:
@@ -5137,7 +5196,7 @@ See also:
 * {{msg-mw|sp-contributions-logs}}
 * {{msg-mw|sp-contributions-deleted}}
 * {{msg-mw|sp-contributions-userrights}}',
-'change-blocklink' => 'Used to name the link on Special:Log.
+'change-blocklink' => 'Used to name the link on [[Special:Log]].
 
 Also used as link title in [[Special:Contributions]] and in [[Special:DeletedContributions]].
 
@@ -5267,7 +5326,7 @@ See also:
 See also:
 * {{msg-mw|Sorbsreason}}
 * {{msg-mw|Sorbs create account_reason}}',
-'cant-see-hidden-user' => 'Used as (red) error message on Special:Block when you try to change (as sysop w/o the hideuser right) the block of a hidden user.',
+'cant-see-hidden-user' => 'Used as (red) error message on [[Special:Block]] when you try to change (as sysop without the hideuser right) the block of a hidden user.',
 'ipbblocked' => 'Error message shown when a user tries to alter block settings when they are themselves blocked.',
 'ipbnounblockself' => 'Error message shown when a user without the <tt>unblockself</tt> right tries to unblock themselves.',
 
@@ -5664,7 +5723,8 @@ See also:
 
 # Export
 'export' => 'Page title of [[Special:Export]], a page where a user can export pages from a wiki to a file.',
-'exporttext' => 'Main text on [[Special:Export]]. Leave the line <tt><nowiki>[[{{#Special:Export}}/{{MediaWiki:Mainpage}}]]</nowiki></tt> exactly as it is!',
+'exporttext' => '{{doc-important|Leave the line <code><nowiki>[[{{#Special:Export}}/{{MediaWiki:Mainpage}}]]</nowiki></code> exactly as it is!}}
+Main text on [[Special:Export]].',
 'exportall' => 'A label of checkbox option in [[Special:Export]]',
 'exportcuronly' => 'A label of checkbox option in [[Special:Export]]',
 'exportnohistory' => 'Used in [[Special:Export]].',
@@ -5834,7 +5894,8 @@ See also:
 * {{msg-mw|Import-interwiki-templates}}
 * {{msg-mw|Import-interwiki-namespace}}
 * {{msg-mw|Import-interwiki-rootpage}}
-* {{msg-mw|Import-interwiki-submit}}',
+* {{msg-mw|Import-interwiki-submit}}
+{{Identical|Comment}}',
 'importtext' => 'Used in the Import form on [[Special:Import]].',
 'importstart' => 'Used in [[Special:Import]].
 
@@ -5945,7 +6006,7 @@ This may happen if the content got corrupted or the serialization format is mis-
 
 # Import log
 'importlogpage' => '{{doc-logpage}}',
-'importlogpagetext' => 'This text appears at the top of the [//translatewiki.net/w/i.php?title=Special:Log&type=import import log] special page.',
+'importlogpagetext' => 'This text appears at the top of the [{{canonicalurl:Special:Log|type=import}} import log] special page.',
 'import-logentry-upload' => 'This is the text of an entry in the Import log (and Recent Changes), after hour (and date, only in the Import log) and sysop name:
 * $1 is the name of the imported file',
 'import-logentry-upload-detail' => '* $1 - number of revisions, success count',
@@ -6033,7 +6094,7 @@ See also:
 {{Identical|Log out}}',
 'tooltip-ca-talk' => "Tooltip shown when hovering over the {{msg-mw|Talk}} tab.
 
-A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For a technical definition of 'content namespaces' see [//www.mediawiki.org/wiki/Manual:Using_custom_namespaces#Content_namespaces Mediawiki].
+A 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For a technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].
 
 Possible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.
 
@@ -6212,7 +6273,8 @@ See also:
 See also:
 * {{msg-mw|Upload}}
 * {{msg-mw|Accesskey-t-upload}}
-* {{msg-mw|Tooltip-t-upload}}',
+* {{msg-mw|Tooltip-t-upload}}
+{{Identical|Upload file}}',
 'tooltip-t-specialpages' => 'The tooltip when hovering over the link "[[MediaWiki:Specialpages/{{SUBPAGENAME}}|{{int:specialpages}}]]" going to a list of all special pages available in the wiki.
 
 See also:
@@ -6231,7 +6293,7 @@ See also:
 * {{msg-mw|Permalink}}
 * {{msg-mw|Accesskey-t-permalink}}
 * {{msg-mw|Tooltip-t-permalink}}',
-'tooltip-ca-nstab-main' => 'A "content page" is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons "content pages" include pages in the file and category namespaces. On Wikinews "content pages" include pages in the Portal namespace. For technical definition of "content namespaces" see [//www.mediawiki.org/wiki/Manual:Using_custom_namespaces#Content_namespaces Mediawiki].
+'tooltip-ca-nstab-main' => 'A "content page" is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons "content pages" include pages in the file and category namespaces. On Wikinews "content pages" include pages in the Portal namespace. For technical definition of "content namespaces" see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].
 
 Possible alternatives to the word \'content\' are \'subject matter\' or \'wiki subject\' or \'wiki purpose\'.
 
@@ -6432,7 +6494,7 @@ Parameters:
 This message is the variable $3 in the message {{msg-mw|lastmodifiedatby}}. This message only appears if the user is anonymous. The variable $1 in this message is a link to the user's contributions.
 
 See also {{msg-mw|Anonusers}} and {{msg-mw|Siteuser}}.",
-'lastmodifiedatby' => "This message is shown when viewing the credits of a page (example: {{fullurl:Main Page|action=credits}}). Note that this action is disabled by default (currently enabled on translatewiki.net).
+'lastmodifiedatby' => "This message is shown when viewing the credits of a page (example: [{{fullurl:Main Page|action=credits}}]). Note that this action is disabled by default (currently enabled on translatewiki.net).
 * $1: date
 * $2: time
 * $3: if the user has entered his 'real name' in his preferences then this variable is his 'real name'. If the user has not entered his 'real name' in his preferences then this variable is the message [[Mediawiki:siteuser/{{SUBPAGENAME}}]], which includes his username.
@@ -6444,7 +6506,8 @@ See also [[MediaWiki:Lastmodifiedat/{{SUBPAGENAME}}]].",
 * $2: optional, the count of names in $1',
 'others' => 'The following explanation is guesswork. This message is shown when viewing the credits of a page (example: {{fullurl:Main Page|action=credits}}). Note that this action is disabled by default (currently enabled on translatewiki.net - to use type <nowiki>&action=credits</nowiki> at the end of any URL in the address bar).
 
-The message appears at the end of the list of credits given in the message [[Mediawiki:Othercontribs/{{SUBPAGENAME}}]] if the number of contributors is above a certain level.',
+The message appears at the end of the list of credits given in the message [[Mediawiki:Othercontribs/{{SUBPAGENAME}}]] if the number of contributors is above a certain level.
+{{Identical|Other}}',
 'siteusers' => 'This message is shown when viewing the credits of a page (example: {{fullurl:Main Page|action=credits}}). Note that this action is disabled by default (currently enabled on translatewiki.net).
 It should be in a form that fits with [[MediaWiki:Othercontribs/{{SUBPAGENAME}}|othercontribs]].
 
@@ -6499,7 +6562,8 @@ See also:
 'pageinfo-title' => 'Page title for action=info. Parameters:
 * $1 is the page name',
 'pageinfo-not-current' => 'Error message displayed when information for an old revision is requested. Example: [{{fullurl:Project:News|oldid=4266597&action=info}}]',
-'pageinfo-header-basic' => 'Table section header in action=info.',
+'pageinfo-header-basic' => 'Table section header in action=info. See [{{canonicalurl:MediaWiki:Pageinfo-header-basic/en|action=info}} example].
+{{Identical|Basic information}}',
 'pageinfo-header-edits' => 'Table section header in action=info.',
 'pageinfo-header-restrictions' => 'Table section header in action=info.',
 'pageinfo-header-properties' => 'Table section header in action=info.',
@@ -6515,6 +6579,7 @@ See also:
 'pageinfo-robot-noindex' => 'An indication that the page is not indexable (that is, is not listed on the results page of a search engine).',
 'pageinfo-views' => 'The number of times the page has been viewed.',
 'pageinfo-watchers' => 'The number of users watching the page.',
+'pageinfo-few-watchers' => 'Message displayed when there are fewer than $wgUnwatchedPageThreshold watchers. $1 is the value of $wgUnwatchedPageThreshold.',
 'pageinfo-redirects-name' => "The number of redirects to the page.
 
 Used as link text, linked to '{{int:Whatlinkshere-title}}' page ([[Special:WhatLinksHere]]).",
@@ -6549,7 +6614,7 @@ See also:
 See also:
 * {{msg-mw|Pageinfo-templates}}',
 'pageinfo-toolboxlink' => "Information link for the page (like 'What links here', but to action=info for the current page instead)",
-'pageinfo-redirectsto' => 'Key for the row shown if this page is a redirect. Verb. See [http://en.wikipedia.org/w/index.php?title=Main_page&action=info example].',
+'pageinfo-redirectsto' => 'Key for the row shown if this page is a redirect. Verb. See [{{canonicalurl:w:Main_page|action=info}} example].',
 'pageinfo-redirectsto-info' => 'Text to put in parentheses for the link to the action=info of the redirect target.
 {{Identical|Info}}',
 'pageinfo-contentpage' => 'Key for the row shown on [{{fullurl:News|action=info}} action=info] if this page is [[mw:Manual:Article count|counted as a content page]]',
@@ -6661,7 +6726,7 @@ See also:
 
 # Media information
 'mediawarning' => 'Shows up on file description pages if the file type is not listed in [[mw:Manual:$wgTrustedMediaFormats|Manual:$wgTrustedMediaFormats]].',
-'imagemaxsize' => 'This is used in Special:Preferences, under Files.
+'imagemaxsize' => 'This is used in [[Special:Preferences]], under Files.
 
 See also:
 * {{msg-mw|Thumbsize}}',
@@ -6713,11 +6778,11 @@ See also:
 Parameters:
 * $1 is the width of the image(s) in pixels.
 * $2 is the height of the image(s) in pixels.',
-'file-info-gif-looped' => 'Part of the information provided about a [http://en.wikipedia.org/wiki/Gif .gif file] on its file description page. Looped means repeating in the context of an animated gif. It is a sequence of images, each displayed after the other, and the first one displayed after the last, in a never ending loop. For example of message in use see [[:File:Mouse10.gif]].',
-'file-info-gif-frames' => 'Part of the information provided about a [http://en.wikipedia.org/wiki/Gif .gif file] on its file description page.',
-'file-info-png-looped' => 'Part of the information provided about a [http://en.wikipedia.org/wiki/APNG .apng file] on its file description page. Looped means repeating indefinetly in the context of an animated png. It is a sequence of images, each displayed after the other, and the first one displayed after the last, in a never ending loop.',
-'file-info-png-repeat' => 'Part of the information provided about a [http://en.wikipedia.org/wiki/APNG .apng file] on its file description page. The sequence of images is repeating a limited amount of time. It is a sequence of images, each displayed after the other, and the first one displayed after the last, for $1 times.',
-'file-info-png-frames' => 'Part of the information provided about a [http://en.wikipedia.org/wiki/APNG .apng file] on its file description page.
+'file-info-gif-looped' => 'Part of the information provided about a [[w:Gif|.gif file]] on its file description page. Looped means repeating in the context of an animated gif. It is a sequence of images, each displayed after the other, and the first one displayed after the last, in a never ending loop. For example of message in use see [[:File:Mouse10.gif]].',
+'file-info-gif-frames' => 'Part of the information provided about a [[w:Gif|.gif file]] on its file description page.',
+'file-info-png-looped' => 'Part of the information provided about a [[w:APNG|.apng file]] on its file description page. Looped means repeating indefinetly in the context of an animated png. It is a sequence of images, each displayed after the other, and the first one displayed after the last, in a never ending loop.',
+'file-info-png-repeat' => 'Part of the information provided about a [[w:APNG|.apng file]] on its file description page. The sequence of images is repeating a limited amount of time. It is a sequence of images, each displayed after the other, and the first one displayed after the last, for $1 times.',
+'file-info-png-frames' => 'Part of the information provided about a [[w:APNG|.apng file]] on its file description page.
 
 The variable $1 is the number of individual frames in an animated gif file.
 
@@ -6775,7 +6840,8 @@ Part of variable $1 in {{msg-mw|Ago}}',
 
 See also {{msg-mw|Minutes-abbrev}}
 
-Part of variable $1 in {{msg-mw|Ago}}',
+Part of variable $1 in {{msg-mw|Ago}}.
+{{Identical|Minute}}',
 'hours' => 'Full word for "hours". $1 is the number of hours.
 
 See also {{msg-mw|Hours-abbrev}}
@@ -6898,14 +6964,12 @@ Varient Option for wikis with variants conversion enabled.',
 'variantname-shi' => '{{optional}}',
 
 # Metadata
-'metadata' => 'The title of a section on an image description page, with information and data about the image. For example of message in use see [http://commons.wikimedia.org/wiki/File:Titan-crystal_bar.JPG Commons].
-
+'metadata' => 'The title of a section on an image description page, with information and data about the image. For example of message in use see [[commons:File:Titan-crystal_bar.JPG|Commons]].
 {{Identical|Metadata}}',
 'metadata-expand' => 'On an image description page, there is mostly a table containing data (metadata) about the image. The most important data are shown, but if you click on this link, you can see more data and information. For the link to hide back the less important data, see "[[MediaWiki:Metadata-collapse/{{SUBPAGENAME}}|{{int:metadata-collapse}}]]".',
 'metadata-collapse' => 'On an image description page, there is mostly a table containing data (metadata) about the image. The most important data are shown, but if you click on the link "[[MediaWiki:Metadata-expand/{{SUBPAGENAME}}|{{int:metadata-expand}}]]", you can see more data and information. This message is for the link to hide back the less important data.',
-'metadata-fields' => "'''Warning:''' Do not translate list items, only translate the text! So leave \"<tt>* make</tt>\" and the other items exactly as they are.
-
-The sentences are for explanation only and are not shown to the user.",
+'metadata-fields' => '{{doc-important|Do not translate list items, only translate the text! So leave "<code>* make</code>" and the other items exactly as they are.}}
+The sentences are for explanation only and are not shown to the user.',
 'metadata-langitem' => '{{optional}}
 This is used for constructing the list of translations when a metadata property is translated into multiple languages.
 
@@ -6914,89 +6978,86 @@ $1 is the value of the property (in one language), $2 is the language name that
 Similar to "metadata-langitem" but for the case where a multilingual property has a default specified that does not specify what language the default is in. $1 is the value of the property.',
 
 # EXIF tags
-'exif-imagewidth' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
-
+'exif-imagewidth' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 {{Identical|Width}}',
-'exif-imagelength' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
-
+'exif-imagelength' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 {{Identical|Height}}',
-'exif-bitspersample' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-compression' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-bitspersample' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-compression' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-This field labels what the compression of the image is. It is commonly seen in Tiff images. It uses messages like {{msg-mw|exif-compression-1}} for the value. http://en.wikipedia.org/wiki/TIFF#TIFF_Compression_Tag has information about this field.
+This field labels what the compression of the image is. It is commonly seen in Tiff images. It uses messages like {{msg-mw|exif-compression-1}} for the value. [[w:TIFF#TIFF_Compression_Tag]] has information about this field.
 {{Related|Exif-compression}}',
-'exif-photometricinterpretation' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-orientation' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-photometricinterpretation' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-orientation' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 For specific information on the orientation tag, see http://sylvana.net/jpegcrop/exif_orientation.html
 {{Related|Exif-orientation}}',
-'exif-samplesperpixel' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-planarconfiguration' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-samplesperpixel' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-planarconfiguration' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 See also:
 * {{msg-mw|Exif-planarconfiguration}}
 * {{msg-mw|Exif-planarconfiguration-1}}
 * {{msg-mw|Exif-planarconfiguration-2}}',
-'exif-ycbcrsubsampling' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-ycbcrpositioning' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-ycbcrsubsampling' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-ycbcrpositioning' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 {{Related|Exif-ycbcrpositioning}}',
-'exif-xresolution' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-xresolution' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This is the horizontal resolution in either dots/inch or dots/cm.',
-'exif-yresolution' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-yresolution' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This is the vertical resolution in either dots/inch or dots/cm.',
-'exif-stripoffsets' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-rowsperstrip' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-stripbytecounts' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-jpeginterchangeformat' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-jpeginterchangeformatlength' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-whitepoint' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-stripoffsets' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-rowsperstrip' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-stripbytecounts' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-jpeginterchangeformat' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-jpeginterchangeformatlength' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-whitepoint' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
 'exif-primarychromaticities' => 'The chromaticity of the three primary colours of the image. Normally this tag is not necessary, since colour space is specified in the colour space information tag. This should probably be translated it as "Chromaticity of primary colours".
 
-Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-ycbcrcoefficients' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-referenceblackwhite' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-datetime' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-ycbcrcoefficients' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-referenceblackwhite' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-datetime' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Note, this message is also used for the XMP:ModifyDate property in XMP metadata. See page 35 of http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf
 
 Datetime is the time that the digital file was last changed.',
-'exif-imagedescription' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-imagedescription' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This property is the description or caption of the image. It is used for the exif ImageDescription property, the dc:description property in XMP (see http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf ), and the iptc-iim 2:120 caption/abstract property ( http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf ).
 
 When an image has multiple differing descriptions, mediawiki follows the MWG guidelines when deciding which to show (Which typically means Exif takes precedence).',
-'exif-make' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-make' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The Manufacturer of the digital camera (or scanner) that took the photo.',
-'exif-model' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-model' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The model of camera (or scanner) used to take the picture.',
 'exif-software' => 'Short for "The software which was used to create or modify this image".
 
 The property can come from the Exif Software tag, PNG software chunk, iptc-iim 2:65 Software field, or XMP\'s xmp:CreatorTool field.
 
-Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-artist' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-artist' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This message labels the author or artist of the work. Usually this means who took the photograph, or who drew the picture. The corresponding value field most commonly contains a single author, however it can contain an ordered (or unordered depending on which metadata standard is used to store the information) list of authors. Sometimes the persons position is prefixed before their name such as \"Photographer, John Smith\". The exif standard recommends multiple authors be specified by \"position, Author 1; position for author 2, Author 2's name\" however this doesn't seem to happen in practise very often. If multiple authors are specified using a non-exif standard, then a billeted (or numbered) list is used.
 
 This property can be specified by exif Artist tag, XMP's tiff:Artist, XMP's dc:creator, iptc-iim's 2:80 byline, PNG's author textual chunk, PNG's (unofficial) artist textual chunk. XMP's photoshop:AuthorsPosition and iptc 2:85 byline-title can also affect display of this property.
-
 {{Identical|Author}}",
-'exif-copyright' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-copyright' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Label for information contained in exif Copyright tag, XMP dc:rights, IPTC-iim 2:116, or PNG copyright textual chunk.
 
 Typically the copyright statement for the photograph/drawing/video (such as ''(c) 2010 John Smith. Released under GFDL''). Sometimes contains license information. See also {{msg-mw|exif-copyrightowner}}",
-'exif-exifversion' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-exifversion' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Version of exif standard photo uses. Typically this is 2.22',
-'exif-flashpixversion' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-flashpixversion' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Version of flashpix used. Flashpix is a format used for storing some types of metadata in image. It is not as commonly used as EXIF, and mediawiki currently cannot read Flashpix data.',
-'exif-colorspace' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-colorspace' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The colorspace of the photo. This tells the computer how to make the colours in the photo be more true to the original photo. Typical values for this are sRGB or uncalibrated. This only gives information on colour information given in the exif-colorspace property. However, colour information is often stored elsewhere in the photo.
 
@@ -7004,159 +7065,159 @@ See also:
 * {{msg-mw|Exif-colorspace}}
 * {{msg-mw|Exif-colorspace-1|optional}}
 * {{msg-mw|Exif-colorspace-65535}}',
-'exif-componentsconfiguration' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-componentsconfiguration' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This contains how the information in the picture is stored. This is most commonly Y, Cr, Cb to specify luma, red, blue. RGB is also possible to specify Red, Green, Blue.
 {{Related|Exif-componentsconfiguration}}',
-'exif-compressedbitsperpixel' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-pixelydimension' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-pixelxdimension' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-usercomment' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-compressedbitsperpixel' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-pixelydimension' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-pixelxdimension' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-usercomment' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Comments by user. Sometimes used like ImageDescription when the ImageDescription contained non-ascii characters. (Technically ImageDescription is supposed to contain ascii characters. In practise utf-8 is used in ImageDescription, so this field isn't used too much.)",
-'exif-relatedsoundfile' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-relatedsoundfile' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Some cameras offer the option to record an audio "memo" for the photo they just took. If the user did that, the name of the file is labelled with this message.',
-'exif-datetimeoriginal' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-datetimeoriginal' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The date and time when the original image data was generated. For example if it was a painting from 1773, scanned in to a computer in 2007, the datetimeoriginal would be 1773 and {{msg-mw|exif-datetimedigitized}} would have the 2007 date.',
-'exif-datetimedigitized' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-datetimedigitized' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The date and time when the image was stored as digital data.',
-'exif-subsectime' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-subsectime' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 'DateTime subseconds' shows the detail of the fraction of a second (1/100s) at which the file was changed, when the tag {{msg-mw|Exif-datetime}} is recorded to the whole second.",
-'exif-subsectimeoriginal' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-subsectimeoriginal' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This tag shows the detail of the fraction of a second (1/100s) at which the file data was originally generated, when the tag {{msg-mw|Exif-datetimeoriginal}} is recorded to the whole second.',
-'exif-subsectimedigitized' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-subsectimedigitized' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This tag shows the detail of the fraction of a second (1/100s) at which the file was stored as digital data, when the tag {{msg-mw|Exif-datetimedigitized}} is recorded to the whole second.',
-'exif-exposuretime' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-exposuretime' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The exposure time. Number of (or fraction of) seconds the film was exposed to light. The value for this property is formatted using {{msg-mw|exif-exposuretime-format}}',
-'exif-exposuretime-format' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-exposuretime-format' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 *$1 is the exposure time written as a fraction of a second, for example 1/640 of a second.
 *$2 is the exposure time written as a decimal, for example 0.0015625.
 *'sec' is the abbreviation used in English for the unit of time 'second'.",
-'exif-fnumber' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-fnumber' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-The [http://en.wikipedia.org/wiki/F_number F number] is the relative aperture of the camera.',
+The [[w:F_number|F number]] is the relative aperture of the camera.',
 'exif-fnumber-format' => "{{optional}}
 Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 *$1 is a number
 *f is the abbreviation used in English for 'f-number'.",
-'exif-exposureprogram' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-exposureprogram' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 How the camera figured out what exposure to use. (If it was manually set, if its optimizing for fast shutter speed, etc).
 {{Related|Exif-exposureprogram}}',
-'exif-spectralsensitivity' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-spectralsensitivity' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 How sensitive each channel (colour) of the photo is to light. This tag is almost never used.',
-'exif-isospeedratings' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-isospeedratings' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The iso speed of the film used in the camera. This is basically a measure of how sensitive the film in the camera is to light.',
-'exif-shutterspeedvalue' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-shutterspeedvalue' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-[http://en.wikipedia.org/wiki/Shutter_speed Shutter speed] is the time that the camera shutter is open.
+[[w:Shutter_speed|Shutter speed]] is the time that the camera shutter is open.
 
 This is the shutter speed measured in APEX units (negative base 2 log of shutter speed in seconds). See {{msg-mw|exif-exposuretime}} for this property in more traditional units of seconds.',
-'exif-aperturevalue' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-aperturevalue' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-The [http://en.wikipedia.org/wiki/Aperture aperture] of a camera is the hole through which light shines. This message can be translated 'Aperture width'. Note, this is measured in APEX units which is 2*log<sub>2</sub>(f-number) . See {{msg-mw|exif-fnumber}} for this value in more traditional units.",
-'exif-brightnessvalue' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+The [[w:Aperture|aperture]] of a camera is the hole through which light shines. This message can be translated 'Aperture width'. Note, this is measured in APEX units which is 2*log<sub>2</sub>(f-number) . See {{msg-mw|exif-fnumber}} for this value in more traditional units.",
+'exif-brightnessvalue' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 How intense the illumination of the scene photographed is. Measured in APEX brightness units. See Annex C of Exif standard for details on the measurement system in use.',
-'exif-exposurebiasvalue' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-exposurebiasvalue' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-Another term for [http://en.wikipedia.org/wiki/Exposure_bias 'exposure bias'] is 'exposure compensation'.",
-'exif-maxaperturevalue' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+Another term for [[w:Exposure_bias|'exposure bias']] is 'exposure compensation'.",
+'exif-maxaperturevalue' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The 'land' in a camera refers possibly to the inner surface of the barrel of the lens. An alternative phrasing for this message could perhaps be 'maximum width of the land aperture'.",
-'exif-subjectdistance' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-subjectdistance' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 The subject of a photograph is the person or thing on which the camera focuses. 'Subject distance' is the distance to the subject given in meters.",
-'exif-meteringmode' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-meteringmode' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See [http://en.wikipedia.org/wiki/Metering_mode Wikipedia article] on metering mode.
+See [[w:Metering_mode|Wikipedia article]] on metering mode.
 {{Related|Exif-meteringmode}}',
-'exif-lightsource' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-lightsource' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 {{Related|Exif-lightsource}}',
-'exif-flash' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-flash' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See this [http://en.wikipedia.org/wiki/Flash_(photography) Wikipedia article] for an explanation of the term.
+See this [[w:en:Flash_(photography)|Wikipedia article]] for an explanation of the term.
 
 See also:
 * {{msg-mw|Exif-flash}}
 * {{msg-mw|Exif-flash-fired-0}}
 * {{msg-mw|Exif-flash-fired-1}}
 {{Identical|Flash}}',
-'exif-focallength' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-focallength' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See this [http://en.wikipedia.org/wiki/Focal_length_(photography) Wikipedia article] for an explanation of the term.',
+See this [[w:en:Focal_length_(photography)|Wikipedia article]] for an explanation of the term.',
 'exif-focallength-format' => "{{optional}}
 Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 *$1 is a number
 *mm is the abbreviation used in English for the unit of measurement of length 'millimetre'.",
-'exif-subjectarea' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-subjectarea' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 This exif property contains the position of the main subject. The first two numbers is the position of the subject in the picture in pixels from the upper left corner. If a third number is specified, it is a circle centred at the first two numbers. If four numbers are specified, the first two are coordinates of the centre of the subject as before, the third is the width of the rectangle, and the fourth is the height of the rectangle. It is rare for a photo to use this tag.',
-'exif-flashenergy' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-flashenergy' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 How bright the flash is in beam candle power seconds.',
-'exif-focalplanexresolution' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-focalplanexresolution' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Indicates the number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane.',
-'exif-focalplaneyresolution' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-focalplaneresolutionunit' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-focalplaneyresolution' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-focalplaneresolutionunit' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 See also:
 * {{msg-mw|Exif-focalplaneresolutionunit-2}}',
-'exif-subjectlocation' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-subjectlocation' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Same as {{msg-mw|exif-subjectarea}} but only ever has two numbers as a value.',
-'exif-exposureindex' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-sensingmethod' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-exposureindex' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-sensingmethod' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 {{Related|Exif-sensingmethod}}',
-'exif-filesource' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-filesource' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 Determines if the image was recorded by a digital camera adhering to DSC standard (which is almost all digital cameras).',
-'exif-scenetype' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-scenetype' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 If the image is directly photographed (taken by a digital camera).
 
 See also:
 * {{msg-mw|Exif-scenetype}}
 * {{msg-mw|Exif-scenetype-1}}',
-'exif-customrendered' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-customrendered' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See also Wikipedia on [http://en.wikipedia.org/wiki/Image_processing image processing].
+See also Wikipedia on [[w:Image_processing|image processing]].
 
 See also:
 * {{msg-mw|Exif-customrendered}}
 * {{msg-mw|Exif-customrendered-0}}
 * {{msg-mw|Exif-customrendered-1}}',
-'exif-exposuremode' => "Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-exposuremode' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See also Wikipedia on [http://en.wikipedia.org/wiki/Exposure_(photography) exposure in photography]. This tag shows if the photo's exposure was manually set or automatically determined.
+See also Wikipedia on [[w:en:Exposure_(photography)|exposure in photography]]. This tag shows if the photo's exposure was manually set or automatically determined.
 {{Related|Exif-exposuremode}}",
-'exif-whitebalance' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-whitebalance' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See also Wikipedia on [http://en.wikipedia.org/wiki/Color_balance color balance].
+See also Wikipedia on [[w:Color_balance|color balance]].
 
 See also:
 * {{msg-mw|Exif-whitebalance}}
 * {{msg-mw|Exif-whitebalance-0}}
 * {{msg-mw|Exif-whitebalance-1}}',
-'exif-digitalzoomratio' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-digitalzoomratio' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See also Wikipedia on [http://en.wikipedia.org/wiki/Digital_zoom digital zoom].',
-'exif-focallengthin35mmfilm' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+See also Wikipedia on [[w:Digital_zoom|digital zoom]].',
+'exif-focallengthin35mmfilm' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
-See also Wikipedia on [http://en.wikipedia.org/wiki/Focal_length#In_photography focal length].',
+See also Wikipedia on [[w:Focal_length#In_photography|focal length]].',
 'exif-scenecapturetype' => '{{Related|Exif-scenecapturetype}}',
 'exif-gaincontrol' => 'Gain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.
 {{Related|Exif-gaincontrol}}',
@@ -7439,20 +7500,21 @@ See also:
 {{Related|Exif-componentsconfiguration}}',
 
 'exif-exposureprogram-0' => '{{Related|Exif-exposureprogram}}',
-'exif-exposureprogram-1' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[http://en.wikipedia.org/wiki/Mode_dial Mode dial]' for an explanation.
+'exif-exposureprogram-1' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.
 {{Related|Exif-exposureprogram}}",
-'exif-exposureprogram-2' => '{{Related|Exif-exposureprogram}}',
-'exif-exposureprogram-3' => 'One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [http://en.wikipedia.org/wiki/Aperture_priority aperture priority].
+'exif-exposureprogram-2' => 'One of the exposure program types in the table of metadata on image description pages.
 {{Related|Exif-exposureprogram}}',
-'exif-exposureprogram-4' => 'One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [http://en.wikipedia.org/wiki/Shutter_priority shutter priority].
+'exif-exposureprogram-3' => 'One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [[w:Aperture_priority|aperture priority]].
 {{Related|Exif-exposureprogram}}',
-'exif-exposureprogram-5' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[http://en.wikipedia.org/wiki/Mode_dial Mode dial]' for an explanation.
+'exif-exposureprogram-4' => 'One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [[w:Shutter_priority|shutter priority]].
+{{Related|Exif-exposureprogram}}',
+'exif-exposureprogram-5' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.
 {{Related|Exif-exposureprogram}}",
-'exif-exposureprogram-6' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[http://en.wikipedia.org/wiki/Mode_dial Mode dial]' for an explanation.
+'exif-exposureprogram-6' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.
 {{Related|Exif-exposureprogram}}",
-'exif-exposureprogram-7' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[http://en.wikipedia.org/wiki/Mode_dial Mode dial]' for an explanation.
+'exif-exposureprogram-7' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.
 {{Related|Exif-exposureprogram}}",
-'exif-exposureprogram-8' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[http://en.wikipedia.org/wiki/Mode_dial Mode dial]' for an explanation.
+'exif-exposureprogram-8' => "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.
 {{Related|Exif-exposureprogram}}",
 
 'exif-subjectdistance-value' => '$1 is a distance measured in metres. The value can, and usually does, include decimal places.',
@@ -7505,7 +7567,7 @@ See also:
 * {{msg-mw|Exif-flash}}
 * {{msg-mw|Exif-flash-fired-0}}
 * {{msg-mw|Exif-flash-fired-1}}',
-'exif-flash-return-0' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-flash-return-0' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 "Strobe" and "flash" mean the same here.
 
@@ -7513,7 +7575,7 @@ See also:
 * {{msg-mw|Exif-flash-return-0}}
 * {{msg-mw|Exif-flash-return-2}}
 * {{msg-mw|Exif-flash-return-3}}',
-'exif-flash-return-2' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-flash-return-2' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 "Strobe" and "flash" mean the same here.
 
@@ -7521,7 +7583,7 @@ See also:
 * {{msg-mw|Exif-flash-return-0}}
 * {{msg-mw|Exif-flash-return-2}}
 * {{msg-mw|Exif-flash-return-3}}',
-'exif-flash-return-3' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+'exif-flash-return-3' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
 
 "Strobe" and "flash" mean the same here.
 
@@ -7545,7 +7607,7 @@ See also:
 * {{msg-mw|Exif-flash-mode-1}}
 * {{msg-mw|Exif-flash-mode-2}}
 * {{msg-mw|Exif-flash-mode-3}}',
-'exif-flash-function-1' => 'Exif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-flash-function-1' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
 
 'exif-focalplaneresolutionunit-2' => 'See also:
 * {{msg-mw|Exif-focalplaneresolutionunit}}',
@@ -7577,7 +7639,7 @@ See also:
 
 'exif-exposuremode-0' => '{{Related|Exif-exposuremode}}',
 'exif-exposuremode-1' => '{{Related|Exif-exposuremode}}',
-'exif-exposuremode-2' => "A type of exposure mode shown as part of the metadata on image description pages. The Wikipedia article on [http://en.wikipedia.org/wiki/Bracketing#Exposure_bracketing bracketing] says that 'auto bracket' is a camera exposure setting which automatically takes a series of pictures at slightly different light exposures.
+'exif-exposuremode-2' => "A type of exposure mode shown as part of the metadata on image description pages. The Wikipedia article on [[w:Bracketing#Exposure_bracketing|bracketing]] says that 'auto bracket' is a camera exposure setting which automatically takes a series of pictures at slightly different light exposures.
 {{Related|Exif-exposuremode}}",
 
 'exif-whitebalance-0' => 'See also:
@@ -7629,7 +7691,8 @@ See also:
 
 'exif-subjectdistancerange-0' => '{{Related|Exif-subjectdistancerange}}
 {{Identical|Unknown}}',
-'exif-subjectdistancerange-1' => 'Macro view is close-up photography. See [http://en.wikipedia.org/wiki/Macro_photography Wikipedia].
+'exif-subjectdistancerange-1' => 'Macro view is close-up photography. See [[w:Macro_photography|Wikipedia]].
+{{Identical|Macro}}
 {{Related|Exif-subjectdistancerange}}',
 'exif-subjectdistancerange-2' => '{{Related|Exif-subjectdistancerange}}',
 'exif-subjectdistancerange-3' => '{{Related|Exif-subjectdistancerange}}',
@@ -7732,7 +7795,8 @@ See also:
 See: http://www.awaresystems.be/imaging/tiff/tifftags/ycbcrpositioning.html
 {{Related|Exif-ycbcrpositioning}}',
 
-'exif-dc-contributor' => 'People who helped make the resource, but are secondary in contribution to the author.',
+'exif-dc-contributor' => 'People who helped make the resource, but are secondary in contribution to the author.
+{{Identical|Contributor}}',
 'exif-dc-coverage' => '"The extent or scope of the resource" see dc:coverage in http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf',
 'exif-dc-date' => 'One or more dates associated with the image. How they are associated is not really defined. From the dc:date XMP property.',
 'exif-dc-publisher' => 'One or more publisher of resource.
@@ -7766,7 +7830,8 @@ $1 is maxaperture in APEX units (APEX aperture units = 2log<sub>2</sub>(f-number
 'exif-iimcategory-rel' => 'Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}',
 'exif-iimcategory-sci' => 'Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}',
 'exif-iimcategory-soi' => 'Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}',
-'exif-iimcategory-spo' => 'Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}',
+'exif-iimcategory-spo' => 'Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}.
+{{Identical|Sport}}',
 'exif-iimcategory-war' => 'Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}',
 'exif-iimcategory-wea' => 'Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}',
 
@@ -7785,9 +7850,8 @@ $1 is maxaperture in APEX units (APEX aperture units = 2log<sub>2</sub>(f-number
 
 # External editor support
 'edit-externally' => 'Displayed on image description pages. See for example [[:Image:Yes.png#filehistory]].',
-'edit-externally-help' => 'Displayed on image description pages. See for example [[:Image:Yes.png#filehistory]].
-
-Please leave the link http://www.mediawiki.org/wiki/Manual:External_editors exactly as it is.',
+'edit-externally-help' => '{{doc-important|Please leave the link "<code>http://www.mediawiki.org/wiki/Manual:External_editors</code>" exactly as it is.}}
+Displayed on image description pages. See for example [[:Image:Yes.png#filehistory]].',
 
 # 'all' in various places, this might be different for inflected languages
 'watchlistall2' => 'Appears on [[Special:Watchlist]].
@@ -8196,7 +8260,7 @@ Use your language default parentheses ({{msg-mw|parentheses}}), but not use the
 # Core parser functions
 'unknown_extension_tag' => '* Description: This is an error shown when you use an unknown extension tag name. This feature allows tags like <tt><nowiki><pre></nowiki></tt> to be called with a parser like <tt><nowiki>{{#tag:pre}}</nowiki></tt>.
 * Parameter $1: This is the unknown extension tag name.',
-'duplicate-defaultsort' => 'See definition of [http://en.wikipedia.org/wiki/Sorting sort key] on Wikipedia.',
+'duplicate-defaultsort' => 'See definition of [[w:Sorting|sort key]] on Wikipedia.',
 
 # Special:Version
 'version' => 'Name of special page displayed in [[Special:SpecialPages]]
@@ -8204,8 +8268,7 @@ Use your language default parentheses ({{msg-mw|parentheses}}), but not use the
 {{Identical|Version}}',
 'version-extensions' => 'Header on [[Special:Version]].',
 'version-specialpages' => 'Part of [[Special:Version]].
-
-{{Identical|Special pages}}',
+{{Identical|Special page}}',
 'version-parserhooks' => 'This message is a heading at [[Special:Version]] for extensions that modifies the parser of wikitext.',
 'version-variables' => '{{Identical|Variable}}',
 'version-antispam' => 'Part of [[Special:Version]].
@@ -8290,7 +8353,7 @@ See also:
 * {{msg-mw|Specialpages}}
 * {{msg-mw|Accesskey-t-specialpages}}
 * {{msg-mw|Tooltip-t-specialpages}}
-{{Identical|Special pages}}',
+{{Identical|Special page}}',
 'specialpages-note' => 'Footer note for the [[Special:SpecialPages]] page',
 'specialpages-group-maintenance' => 'Section heading in the list of [[Special:SpecialPages|Special pages]].',
 'specialpages-group-other' => 'Section heading in the list of [[Special:SpecialPages|Special pages]].',
@@ -8318,10 +8381,10 @@ See also:
 # External image whitelist
 'external_image_whitelist' => "As usual please leave all the wiki markup, including the spaces, as they are. You can translate the text, including 'Leave this line exactly as it is'. The first line of this messages has one (1) leading space.
 
-See definition of [http://en.wikipedia.org/wiki/Regular_expression regular expression] on Wikipedia.",
+See definition of [[w:Regular_expression|regular expression]] on Wikipedia.",
 
 # Special:Tags
-'tags' => "Shown on [[Special:Specialpages]] for page listing the tags that the software may mark an edit with, and their meaning. For more information on tags see [//www.mediawiki.org/wiki/Manual:Tags Mediawiki].
+'tags' => "Shown on [[Special:Specialpages]] for page listing the tags that the software may mark an edit with, and their meaning. For more information on tags see [[mw:Manual:Tags|MediaWiki]].
 
 It appears that the word 'valid' describes 'tags', not 'change'. It also appears that you could use the term 'defined' instead of 'valid', or perhaps use a phrase meaning 'Change tags in use'.",
 'tag-filter' => 'Caption of a filter shown on lists of changes (e.g. [[Special:Log]], [[Special:Contributions]], [[Special:Newpages]], [[Special:Recentchanges]], [[Special:Recentchangeslinked]], page histories)',
@@ -8329,14 +8392,14 @@ It appears that the word 'valid' describes 'tags', not 'change'. It also appears
 
 {{Identical|Filter}}',
 'tags-title' => 'The title of [[Special:Tags]]',
-'tags-intro' => 'Explanation on top of [[Special:Tags]]. For more information on tags see [//www.mediawiki.org/wiki/Manual:Tags Mediawiki].',
-'tags-tag' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [//www.mediawiki.org/wiki/Manual:Tags Mediawiki].',
-'tags-display-header' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [//www.mediawiki.org/wiki/Manual:Tags Mediawiki].',
-'tags-description-header' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [//www.mediawiki.org/wiki/Manual:Tags Mediawiki].',
-'tags-hitcount-header' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [//www.mediawiki.org/wiki/Manual:Tags Mediawiki].',
+'tags-intro' => 'Explanation on top of [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].',
+'tags-tag' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].',
+'tags-display-header' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].',
+'tags-description-header' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].',
+'tags-hitcount-header' => 'Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].',
 'tags-edit' => '{{Identical|Edit}}
 Used on [[Special:Tags]]. Verb. Used as display text on a link to create/edit a description.',
-'tags-hitcount' => 'Shown in the "{{msg-mw|Tags-hitcount-header}}" column in [[Special:Tags]]. For more information on tags see [//www.mediawiki.org/wiki/Manual:Tags Mediawiki].
+'tags-hitcount' => 'Shown in the "{{msg-mw|Tags-hitcount-header}}" column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].
 
 * <code>$1</code> is the number of changes marked with the tag',
 
@@ -8437,8 +8500,12 @@ See also:
 {{Identical|Other}}',
 
 # SQLite database support
-'sqlite-has-fts' => 'Shown on Special:Version, $1 is version',
-'sqlite-no-fts' => 'Shown on Special:Version, $1 is version',
+'sqlite-has-fts' => 'Shown on [[Special:Version]].
+Parameters:
+* $1 - version',
+'sqlite-no-fts' => 'Shown on [[Special:Version]].
+Parameters:
+* $1 - version',
 
 # New logging system
 'logentry-delete-delete' => '{{Logentry}}',
@@ -8524,11 +8591,13 @@ Parameter $4, the target page, is also not visible to parser functions.',
 $4 is the gender of the target user.',
 'logentry-newusers-create2' => '{{Logentry}}
 
-$4 is the name of the target user.',
+$4 is the name of the user that was created.',
+'logentry-newusers-byemail' => '{{Logentry}}
+
+$4 is the name of the user that was created.',
 'logentry-newusers-autocreate' => '{{Logentry}}
 
 $4 is the gender of the target user.',
-'newuserlog-byemail' => 'Used as reason in [[Special:Log/newusers]].',
 'logentry-rights-rights' => '*$1 - username
 *$2 - (see below)
 *$3 - username
@@ -8556,7 +8625,8 @@ $4 is the gender of the target user.',
 'feedback-bugornote' => 'When feedback dialog box is opened, this introductory message in small print explains the options to report a bug or add simple feedback. We expect that people in a hurry will not read this.',
 'feedback-subject' => 'Label for a text input
 {{Identical|Subject}}',
-'feedback-message' => 'Label for a textarea; signature referrs to a Wikitext signature.',
+'feedback-message' => 'Label for a textarea; signature referrs to a Wikitext signature.
+{{Identical|Message}}',
 'feedback-cancel' => 'Button label
 {{Identical|Cancel}}',
 'feedback-submit' => 'Button label
@@ -8619,6 +8689,7 @@ $4 is the gender of the target user.',
 'api-error-ok-but-empty' => 'API error message that can be used for client side localisation of API errors.',
 'api-error-overwrite' => 'API error message that can be used for client side localisation of API errors.',
 'api-error-stashfailed' => 'API error message that can be used for client side localisation of API errors.',
+'api-error-publishfailed' => 'API error message that can be used for client side localisation of API errors.',
 'api-error-timeout' => 'API error message that can be used for client side localisation of API errors.',
 'api-error-unclassified' => 'API error message that can be used for client side localisation of API errors.',
 'api-error-unknown-code' => 'API error message that can be used for client side localisation of API errors. Parameters:
@@ -8633,7 +8704,8 @@ $4 is the gender of the target user.',
 
 # Durations
 'duration-seconds' => '{{Related|Duration}}',
-'duration-minutes' => '{{Related|Duration}}',
+'duration-minutes' => '{{Related|Duration}}
+{{Identical|Minute}}',
 'duration-hours' => '{{Related|Duration}}',
 'duration-days' => '{{Related|Duration}}',
 'duration-weeks' => '{{Related|Duration}}',
index 3c2be5f..ac35dad 100644 (file)
@@ -3805,7 +3805,6 @@ Rikchakunatataq hunt'a ch'irkukupim rikunki. Huk willañiqi llayakunaqa tantapus
 'logentry-newusers-create' => '$1 sutiyuq rakiquna kamarisqañam',
 'logentry-newusers-create2' => '$1 sutiyuq ruraqqa $3 sutiyuq rakiqunatam kamarirqanñam',
 'logentry-newusers-autocreate' => '$1 sutiyuq rakiqunaqa kikinmanta kamarisqam',
-'newuserlog-byemail' => 'e-chaskiwan kachasqa yaykuna rima',
 'rightsnone' => '(-)',
 
 # Feedback
index d9b8e65..efab7a9 100644 (file)
@@ -3726,7 +3726,6 @@ Questa pagina ha actualmain difficultads tecnicas.',
 'logentry-newusers-create' => 'Il conto $1 è vegnì creà',
 'logentry-newusers-create2' => 'Il conto $3 è vegnì creà da $1',
 'logentry-newusers-autocreate' => 'Il conto $1 è vegnì creà automaticamain',
-'newuserlog-byemail' => 'tramess il pled-clav per e-mail',
 'logentry-rights-rights' => '$1 ha midà la commembranza da gruppas per $3 da $4 a $5',
 'logentry-rights-rights-legacy' => '$1 ha midà la commembranza da gruppas per $3',
 'logentry-rights-autopromote' => '$1 è vegnì promovì automaticamain da $4 a $5',
index 78120ca..fd1c171 100644 (file)
@@ -208,7 +208,7 @@ $specialPageAliases = array(
        'Contributions'             => array( 'Contribuții' ),
        'CreateAccount'             => array( 'Înregistrare' ),
        'Deadendpages'              => array( 'Pagini_fără_legături' ),
-       'DeletedContributions'      => array( 'Contibuții_șterse' ),
+       'DeletedContributions'      => array( 'Contribuții_șterse' ),
        'Disambiguations'           => array( 'Dezambiguizări' ),
        'DoubleRedirects'           => array( 'Redirectări_duble' ),
        'Emailuser'                 => array( 'Email_utilizator' ),
@@ -665,9 +665,8 @@ S-ar putea ca acesta să fi fost deja șters de altcineva.',
 'delete-hook-aborted' => 'Ștergerea a fost abandonată din cauza unui hook.
 Nicio explicație furnizată.',
 'badtitle' => 'Titlu incorect',
-'badtitletext' => 'Titlul căutat a fost invalid, gol sau o legătură invalidă inter-linguală sau inter-wiki.
-
-Poate conține unul sau mai multe caractere ce nu poate fi folosit în titluri.',
+'badtitletext' => 'Titlul paginii căutate este incorect, gol sau este o legătură interlinguală sau interwiki incorectă.
+Poate conține unul sau mai multe caractere ce nu pot fi folosite în titluri.',
 'perfcached' => 'Datele următoare au fost păstrate în cache și s-ar putea să nu fie actualizate. Un maxim de {{PLURAL:$1|un rezultat este disponibil|$1 rezultate sunt disponibile}} în cache.',
 'perfcachedts' => 'Informațiile de mai jos provin din cache, ultima actualizare efectuându-se la $1. Un maxim de {{PLURAL:$4|un rezultat este disponibil|$4 rezultate sunt disponibile}} în cache.',
 'querypage-no-updates' => 'Actualizările acestei pagini sunt momentan dezactivate. Informațiile de aici nu sunt împrospătate.',
@@ -739,7 +738,7 @@ Nu uitați să vă modificați [[Special:Preferences|preferințele]] pentru {{SI
 'gotaccount' => "Aveți deja un cont de utilizator? '''$1'''.",
 'gotaccountlink' => 'Autentificați-vă',
 'userlogin-resetlink' => 'Ați uitat datele de autentificare?',
-'createaccountmail' => 'după e-mail',
+'createaccountmail' => 'Utilizează o parolă temporară aleasă la întâmplare și o trimite la adresa de e-mail specificată mai jos',
 'createaccountreason' => 'Motiv:',
 'badretype' => 'Parolele pe care le-ați introdus diferă.',
 'userexists' => 'Numele de utilizator pe care l-ați introdus este deja folosit.
@@ -1342,7 +1341,7 @@ Detalii se pot găsi în [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE
 'search-interwiki-default' => '$1 rezultate:',
 'search-interwiki-more' => '(mai mult)',
 'search-relatedarticle' => 'Relaționat',
-'mwsuggest-disable' => 'Dezactivează sugestiile AJAX',
+'mwsuggest-disable' => 'Dezactivează sugestiile de căutare',
 'searcheverything-enable' => 'Caută în toate spațiile de nume',
 'searchrelated' => 'relaționat',
 'searchall' => 'toate',
@@ -1449,7 +1448,7 @@ Aici se află o combinație generată întâmplător pe care o puteți folosi: $
 Acțiunea nu este reversibilă.',
 'prefs-emailconfirm-label' => 'Confirmare e-mail:',
 'prefs-textboxsize' => 'Mărime căsuță de modificare',
-'youremail' => 'Adresa de e-mail:',
+'youremail' => 'Adresă de e-mail:',
 'username' => '{{GENDER:$1|Nume de utilizator}}:',
 'uid' => 'ID {{GENDER:$1|utilizator|utilizatoare}}:',
 'prefs-memberingroups' => '{{GENDER:$2|Membru|Membră}} în {{PLURAL:$1|grupul|grupurile}}:',
@@ -2249,9 +2248,9 @@ Necesită cel puțin un domeniu de nivel superior, cum ar fi „*.org”.<br />
 'listusers-blocked' => '(blocat{{GENDER:$1||ă|}})',
 
 # Special:ActiveUsers
-'activeusers' => 'Lista de utilizatori activi',
-'activeusers-intro' => 'Aceasta este o listă cu utilizatorii care au avut un fel de activitate în {{PLURAL:$1|ultima zi|ultimele $1 zile}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|modificare recentă|modificări recente}} în {{PLURAL:$3|ultima zi|ultimele $3 zile}}',
+'activeusers' => 'Listă utilizatori activi',
+'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',
@@ -3115,6 +3114,7 @@ Permite adăugarea unui motiv în descrierea modificărilor',
 'pageinfo-robot-noindex' => 'Neindexabilă',
 'pageinfo-views' => 'Număr de vizualizări',
 'pageinfo-watchers' => 'Număr de utilizatori care urmăresc pagina',
+'pageinfo-few-watchers' => 'Mai puțin de {{PLURAL:$1|un urmăritor|$1 urmăritori|$1 de urmăritori}}',
 'pageinfo-redirects-name' => 'Redirecționări către această pagină',
 'pageinfo-subpages-name' => 'Subpagini ale acestei pagini',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecționare|redirecționări|de redirecționări}}; $3 {{PLURAL:$3|non-redirecționare|non-redirecționări|de non-redirecționări}})',
@@ -3883,7 +3883,7 @@ Imaginile sunt afișate la rezoluția lor maximă, în timp ce alte tipuri de fi
 'specialpages-group-highuse' => 'Pagini utilizate intens',
 'specialpages-group-pages' => 'Liste de pagini',
 'specialpages-group-pagetools' => 'Unelte pentru pagini',
-'specialpages-group-wiki' => 'Date și unelte wiki',
+'specialpages-group-wiki' => 'Date și instrumente',
 'specialpages-group-redirects' => 'Pagini speciale de redirecționare',
 'specialpages-group-spam' => 'Unelte spam',
 
@@ -3980,8 +3980,8 @@ Imaginile sunt afișate la rezoluția lor maximă, în timp ce alte tipuri de fi
 'logentry-newusers-newusers' => 'Contul de utilizator $1 a fost creat',
 'logentry-newusers-create' => 'Contul de utilizator $1 a fost creat',
 'logentry-newusers-create2' => 'Contul de utilizator $3 a fost creat de către $1',
+'logentry-newusers-byemail' => 'Contul de utilizator $3 a fost creat de către $1, iar parola a fost trimisă prin e-mail',
 'logentry-newusers-autocreate' => 'Contul $1 a fost creat în mod automat',
-'newuserlog-byemail' => 'parola trimisă prin e-mail',
 'logentry-rights-rights' => '$1 a schimbat apartenența la grup pentru $3 de la $4 la $5',
 'logentry-rights-rights-legacy' => '$1 a schimbat apartenența la grup pentru $3',
 'logentry-rights-autopromote' => '$1 a fost promovat în mod automat de la $4 la $5',
@@ -4039,6 +4039,7 @@ Imaginile sunt afișate la rezoluția lor maximă, în timp ce alte tipuri de fi
 'api-error-ok-but-empty' => 'Eroare internă: niciun răspuns de la server.',
 'api-error-overwrite' => 'Nu este permisă suprascrierea unui fișier existent.',
 'api-error-stashfailed' => 'Eroare internă: serverul nu a putut stoca fișierul temporar.',
+'api-error-publishfailed' => 'Eroare internă: serverul nu a putut publica fișierul temporar.',
 'api-error-timeout' => 'Serverul nu a răspuns în timp util.',
 'api-error-unclassified' => 'A apărut o eroare necunoscută.',
 'api-error-unknown-code' => 'Eroare necunoscută: „$1”',
index 7d35436..80d4285 100644 (file)
@@ -475,7 +475,7 @@ No te sce scurdanne de cangià le [[Special:Preferences|{{SITENAME}} preferenze
 'gotaccount' => "Tine già 'nu cunde? '''$1'''.",
 'gotaccountlink' => 'Tràse',
 'userlogin-resetlink' => "T'è scurdate le dettaglie pe trasè?",
-'createaccountmail' => 'pe e-mail',
+'createaccountmail' => 'Pe e-mail',
 'createaccountreason' => 'Mutive:',
 'badretype' => 'Le passuord ca è scritte non ge sonde uguale.',
 'userexists' => "'U nome de l'utende ca è scritte jè già ausate.
@@ -790,10 +790,10 @@ Tu ne stè promitte ca quidde ca scrive tu, o lè scritte cu 'u penziere tue o l
 '''NO REGGISTRA' FATIJE CUPERTE DA 'U COPYRIGHT SENZA PERMESSE! NO FA STUDECARIE!'''",
 'longpageerror' => "'''ERRORE: 'U teste ca tu vuè ccu reggistre è luenghe {{PLURAL:$1|'nu kilobyte|$1 kilobyte}}, invece 'u limite massime jè de {{PLURAL:$2|'nu kilobyte|$2 kilobyte}}.'''
 Non ge puè reggistrà sta pàggene.",
-'readonlywarning' => "'''FA ATTENZIO': 'U database ha state bloccate pe manutenziona, e allore tu non ge puè reggistrà le cangiaminde ca ste face mò.'''
-Tu puè fa 'na bella cose, tagghie e 'nzicche le cangiaminde jndr'à 'nu file de teste sus a 'u combiuter tue e pò cchiù tarde le reggistre sus 'a Uicchi.
+'readonlywarning' => "'''FA ATTENZIO': 'U database ha state bloccate pe manutenzione, e allore tu non ge puè reggistrà le cangiaminde ca ste face mò.'''
+Tu puè fa 'na bella cose, tagghie e 'nzicche le cangiaminde jndr'à 'nu file de teste sus a 'u combiuter tune e pò cchiù tarde le reggistre sus 'a Uicchi.
 
-L'amministratore ca ha bloccate 'u database ha scritte stu mutive: $1",
+L'amministratore ca ha bloccate 'u database ha date stu mutive: $1",
 'protectedpagewarning' => "'''ATTENZIO': Sta pàgene ha state bloccate e allore sulamende le utinde cu le privilegge de ''sysop'' ponne cangiarle.'''
 L'urteme archivie de le trasute ha state previste aqquà sotte pe referimende:",
 'semiprotectedpagewarning' => "'''Fà attenzione:''' Sta pàgene ha state bloccate accussì sulamende l'utinde reggistrete ponne fà cangiaminde.
@@ -2031,7 +2031,7 @@ Onne abbesogne almene de \'nu dominie de levèlle ierte, pe esembie "*.org". <br
 # Special:ActiveUsers
 'activeusers' => "Liste de l'utinde attive",
 '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|$3 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',
@@ -2097,7 +2097,7 @@ L'indirizze e-mail ca tu è 'nzerite jndr'à le [[Special:Preferences|preferenze
 'usermessage-template' => 'MediaWiki:UserMessage',
 
 # Watchlist
-'watchlist' => 'Pàggene condrollete',
+'watchlist' => 'Pàggene condrollate',
 'mywatchlist' => 'Pàggene condrollate',
 'watchlistfor2' => 'Pe $1 $2',
 'nowatchlist' => "Non ge tine pàggene jndr'à liste de le pàggene condrollete.",
@@ -2580,7 +2580,7 @@ Tu puè aggiornà 'u ridirezionamende ca apponde a 'u titole origgenale automati
 Ce tu no ste scacchie, sta secure de condrollà [[Special:DoubleRedirects|doppie ridirezionaminde]] o [[Special:BrokenRedirects|ridirezionaminde scuasciate]].
 Tu si 'u responsabbile de quidde ca cumbine, assicurate ca 'u collegamende condinue a appondà addò avessa scè.
 
-Vide Bbuene ca 'a pàgene '''non''' g'avene spustate ce esiste n'otra pàgene cu 'u titole nuéve, a mene ca jè vacande o jè 'na pàgene de ridirezionamende senza storie.
+Vide Bbuene ca 'a pàgene '''non''' g'avène spustate ce esiste n'otra pàgene cu 'u titole nuéve, a mene ca jè vacande o jè 'na pàgene de ridirezionamende senza storie.
 Quieste significhe ca tu puè fà turnà 'u vecchie nome 'a pàgene ce jedde ha state renomenate e t'è rese conde ca è fatte 'na studecarije sovrascrevènne 'na pàgene esistende.
 
 '''ATTENZIONE!'''
@@ -2938,6 +2938,7 @@ Stu fatte ha state causate da 'nu collegamende a 'nu site esterne ca appartene a
 'pageinfo-robot-noindex' => 'None indicizzabbele',
 'pageinfo-views' => 'Numere de visite',
 'pageinfo-watchers' => "Numere de visitature d'a pàgene",
+'pageinfo-few-watchers' => 'Mene de $1 {{PLURAL:$1|visitatore|visitature}}',
 'pageinfo-redirects-name' => 'Redirezionaminde a sta pàgene',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Sottopàggene de sta pàgene',
@@ -3911,7 +3912,7 @@ Le immaggine sonde fatte vedè jndr'à resoluziona megghie, otre tipe de file re
 'specialpages-group-highuse' => 'Pàggene ausete assaje proprie',
 'specialpages-group-pages' => 'Liste de le pàggene',
 'specialpages-group-pagetools' => 'Pàgene de le struminde',
-'specialpages-group-wiki' => 'Date e struminde de Uicchi',
+'specialpages-group-wiki' => 'Date e struminde',
 'specialpages-group-redirects' => 'Redirezionaminde de le pàggene speciele',
 'specialpages-group-spam' => "Struminde p'u spam",
 
@@ -4008,8 +4009,8 @@ Le immaggine sonde fatte vedè jndr'à resoluziona megghie, otre tipe de file re
 'logentry-newusers-newusers' => "'U cunde utende $1 ha state ccrejate",
 'logentry-newusers-create' => "'U cunde utende $1 ha state ccrejate",
 'logentry-newusers-create2' => "$1 {{GENDER:$2|ccrejate}} {{GENDER:$4|'nu cunde utende}} $3",
+'logentry-newusers-byemail' => "'U cunde utende $3 ha state ccrejate da $1 e 'a passuord ha state mannate pe e-mail",
 'logentry-newusers-autocreate' => "'U cunde utende $1 ha state ccrejate automaticamende",
-'newuserlog-byemail' => 'password mannete pe e-mail',
 'logentry-rights-rights' => "$1 membre d'u gruppe cangiate pe $3 da $4 a $5",
 'logentry-rights-rights-legacy' => "$1 ave cangiate 'u membre d'u gruppe pe $3",
 'logentry-rights-autopromote' => '$1 ha state promosse automaticamende da $4 a $5',
@@ -4067,6 +4068,7 @@ Ce nò, tu puè ausà 'u module facile aqquà sotte. 'U commende tune avène agg
 'api-error-ok-but-empty' => "Errore inderne: Nisciune resposte da 'u server.",
 'api-error-overwrite' => "'A sovrascritture de 'nu file ca esiste non ge se pò fà.",
 'api-error-stashfailed' => "Errore inderne: 'U server ha fallite 'a reggistrazione de le file temboranèe.",
+'api-error-publishfailed' => "Errore inderne: 'U server ha fallite 'a pubblecazione d'u file temboranèe.",
 'api-error-timeout' => "'U server non g'ave resposte jndr'à 'u tiembe ca 'u spettave.",
 'api-error-unclassified' => "'N'errore scanusciute s'a verificate",
 'api-error-unknown-code' => 'Errore scanusciute: "$1"',
index e75dc71..fc02919 100644 (file)
@@ -20,6 +20,7 @@
  * @author Anonim.one
  * @author Askarmuk
  * @author Assele
+ * @author Biathlon
  * @author Bouron
  * @author Chilin
  * @author Claymore
@@ -521,7 +522,7 @@ $messages = array(
 'hidden-category-category' => 'Скрытые категории',
 'category-subcat-count' => '{{PLURAL:$2|Эта категория содержит только следующую подкатегорию.|Эта категория содержит $1 {{PLURAL:$1|подкатегорию|подкатегории}} из $2 всего.}}',
 'category-subcat-count-limited' => 'В этой категории {{PLURAL:$1|$1 подкатегория|$1 подкатегории|$1 подкатегорий}}.',
-'category-article-count' => '{{PLURAL:$2|Эта категория содержит только одну страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страницы|Показано $1 страниц}} из $2 {{PLURAL:$2|имеющейся|имеющихся}}.}}',
+'category-article-count' => '{{PLURAL:$2|Эта категория содержит только одну страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страницы|Показано $1 страниц}} из $2.}}',
 'category-article-count-limited' => 'В этой категории {{PLURAL:$1|$1 страница|$1 страницы|$1 страниц}}.',
 'category-file-count' => '{{PLURAL:$2|Эта категория содержит только один файл.|В этой категории {{PLURAL:$1|показан $1 файл|показано $1 файла|показано $1 файлов}} из $2 {{PLURAL:$2|имеющейся|имеющихся}}.}}',
 'category-file-count-limited' => 'В этой категории {{PLURAL:$1|$1 файл|$1 файла|$1 файлов}}.',
@@ -579,7 +580,7 @@ $messages = array(
 'go' => 'Перейти',
 'searcharticle' => 'Перейти',
 'history' => 'История',
-'history_short' => 'история',
+'history_short' => 'Ð\98стория',
 'updatedmarker' => 'обновлено после моего последнего посещения',
 'printableversion' => 'Версия для печати',
 'permalink' => 'Постоянная ссылка',
@@ -838,7 +839,7 @@ $2',
 'gotaccount' => "Вы уже зарегистрированы? '''$1'''.",
 'gotaccountlink' => 'Представьтесь',
 'userlogin-resetlink' => 'Забыли данные для входа?',
-'createaccountmail' => 'Ð\92Ñ\8bÑ\81лаÑ\82Ñ\8c Ð¿Ð°Ñ\80олÑ\8c Ð¿Ð¾ Ñ\8dл. Ð¿Ð¾Ñ\87Ñ\82е',
+'createaccountmail' => 'Ð\98Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ñ\81генеÑ\80иÑ\80ованнÑ\8bй Ñ\81лÑ\83Ñ\87айнÑ\8bм Ð¾Ð±Ñ\80азом Ð²Ñ\80еменнÑ\8bй Ð¿Ð°Ñ\80олÑ\8c Ð¸ Ð²Ñ\8bÑ\81лаÑ\82Ñ\8c Ð¼Ð½Ðµ ÐµÐ³Ð¾ Ð½Ð° Ñ\83казаннÑ\8bй Ð½Ð¸Ð¶Ðµ Ð°Ð´Ñ\80еÑ\81 Ñ\8dлекÑ\82Ñ\80онной Ð¿Ð¾Ñ\87Ñ\82Ñ\8b:',
 'createaccountreason' => 'Причина:',
 'badretype' => 'Введённые вами пароли не совпадают.',
 'userexists' => 'Введённое имя участника уже используется.
@@ -1148,7 +1149,7 @@ $2
 '''НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!'''",
 'longpageerror' => "'''ОШИБКА: записываемый вами текст имеет размер {{PLURAL:$1|$1 килобайт|$1 килобайта|$1 килобайт}}, что больше, чем установленный предел в {{PLURAL:$2|$2 килобайт|$2 килобайта|$2 килобайт}}. Страница не может быть сохранена.'''",
 'readonlywarning' => "'''Предупреждение. База данных заблокирована в связи с процедурами обслуживания, поэтому вы не можете записать ваши изменения прямо сейчас.'''
\92озможно, Ð²Ð°Ð¼ Ñ\81ледÑ\83еÑ\82 Ñ\81оÑ\85Ñ\80аниÑ\82Ñ\8c Ñ\82екÑ\81Ñ\82 Ð² Ñ\84айл, Ñ\87Ñ\82обÑ\8b Ð²Ð¾Ñ\81полÑ\8cзоваÑ\82Ñ\8cÑ\81Ñ\8f Ñ\8dÑ\82им Ñ\82екÑ\81Ñ\82ом Ð¿Ð¾Ð·Ð¶е.
\92озможно, Ð²Ð°Ð¼ Ñ\81ледÑ\83еÑ\82 Ñ\81копиÑ\80оваÑ\82Ñ\8c Ñ\8dÑ\82оÑ\82 Ñ\82екÑ\81Ñ\82 Ð² Ñ\82екÑ\81Ñ\82овÑ\8bй Ñ\84айл, Ñ\87Ñ\82обÑ\8b Ñ\81оÑ\85Ñ\80аниÑ\82Ñ\8c ÐµÐ³Ð¾ Ð½Ð° Ð±Ñ\83дÑ\83Ñ\89ее.
 
 Администратор, заблокировавший базу данных, оставил следующее объяснение: $1",
 'protectedpagewarning' => "'''Предупреждение. Эта страница защищена от изменений, её могут редактировать только участники с полномочиями администраторов.'''
@@ -1453,7 +1454,7 @@ $1",
 'search-interwiki-default' => '$1 результ.:',
 'search-interwiki-more' => '(ещё)',
 'search-relatedarticle' => 'Связанный',
-'mwsuggest-disable' => 'Отключить AJAX-подсказки',
+'mwsuggest-disable' => 'Отключить подсказки поиска',
 'searcheverything-enable' => 'Поиск по всем пространствам имён',
 'searchrelated' => 'связанный',
 'searchall' => 'все',
@@ -2359,7 +2360,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Список активных участников',
 'activeusers-intro' => 'Это список участников, совершавших какие-либо действия за {{PLURAL:$1|последний $1 день|последние $1 дня|последние $1 дней}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|правка|правки|правок}} за {{PLURAL:$3|последний $3 день|последние $3 дня|последние $3 дней}}',
+'activeusers-count' => '$1 {{PLURAL:$1|правка|правки|правок}} за {{PLURAL:$3|$3 последний день|последние $3 дня|последние $3 дней}}',
 'activeusers-from' => 'Показать участников, начиная с:',
 'activeusers-hidebots' => 'Скрыть ботов',
 'activeusers-hidesysops' => 'Скрыть администраторов',
@@ -2589,9 +2590,9 @@ $UNWATCHURL
 'protect-locked-access' => "У вашей учётной записи недостаточно прав для изменения уровня защиты страницы. Текущие установки для страницы '''$1''':",
 'protect-cascadeon' => 'Эта страница защищена в связи с тем, что она включена {{PLURAL:$1|в указанную ниже страницу, на которую|в нижеследующие страницы, на которые}} установлена каскадная защита. Вы можете изменить уровень защиты этой страницы, но это не повлияет на каскадную защиту.',
 'protect-default' => 'Без защиты',
-'protect-fallback' => 'ТÑ\80ебÑ\83еÑ\82Ñ\81Ñ\8f Ñ\80азÑ\80еÑ\88ение «$1»',
-'protect-level-autoconfirmed' => 'Ð\97аÑ\89иÑ\82иÑ\82Ñ\8c Ð¾Ñ\82 Ð½Ð¾Ð²Ñ\8bÑ\85 Ð¸ Ð½ÐµÐ·Ð°Ñ\80егиÑ\81Ñ\82Ñ\80иÑ\80ованнÑ\8bÑ\85 Ñ\83Ñ\87аÑ\81Ñ\82ников',
-'protect-level-sysop' => 'ТолÑ\8cко Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\8b',
+'protect-fallback' => 'РазÑ\80еÑ\88ено Ñ\82олÑ\8cко Ñ\83Ñ\87аÑ\81Ñ\82никам Ñ\81 Ð¿Ñ\80авами «$1»',
+'protect-level-autoconfirmed' => 'РазÑ\80еÑ\88ено Ñ\82олÑ\8cко Ð°Ð²Ñ\82оподÑ\82веÑ\80ждÑ\91ннÑ\8bм Ñ\83Ñ\87аÑ\81Ñ\82никам',
+'protect-level-sysop' => 'РазÑ\80еÑ\88ено Ñ\82олÑ\8cко Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80ам',
 'protect-summary-cascade' => 'каскадная',
 'protect-expiring' => 'истекает $1 (UTC)',
 'protect-expiring-local' => 'истекает $1',
@@ -2884,18 +2885,18 @@ $1',
 # Move page
 'move-page' => '$1 — переименование',
 'move-page-legend' => 'Переименование страницы',
-'movepagetext' => "Воспользовавшись формой ниже, вы переименуете страницу, одновременно переместив на новое место её журнал изменений.
-Старое название станет перенаправлением на новое название.
+'movepagetext' => "Воспользовавшись нижеприведённой формой, вы переименуете страницу, одновременно переместив на новое место её журнал изменений.
+Старое название станет перенаправлением на новое.
 Вы можете автоматически обновить перенаправления, которые вели на старое название.
 Если вы этого не сделаете, пожалуйста, проверьте наличие [[Special:DoubleRedirects|двойных]] и [[Special:BrokenRedirects|разорванных перенаправлений]].
-Вы отвечаете за то, что бы ссылки продолжали и далее указывают туда, куда предполагалось.
+Вы отвечаете за то, чтобы ссылки продолжали и далее указывать туда, куда предполагалось.
 
\9eбÑ\80аÑ\82иÑ\82е Ð²Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ, Ñ\87Ñ\82о Ñ\81Ñ\82Ñ\80аниÑ\86а '''не Ð±Ñ\83деÑ\82''' Ð¿ÐµÑ\80еименована, ÐµÑ\81ли Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81 Ð½Ð¾Ð²Ñ\8bм Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼ Ñ\83же Ñ\81Ñ\83Ñ\89еÑ\81Ñ\82вÑ\83еÑ\82, ÐºÑ\80оме Ñ\81лÑ\83Ñ\87аев, ÐµÑ\81ли Ð¾Ð½Ð° Ñ\8fвлÑ\8fеÑ\82Ñ\81Ñ\8f Ð¿ÐµÑ\80енапÑ\80авлением Ð¸Ð»Ð¸ Ð¿Ñ\83Ñ\81Ñ\82а Ð¸ не имеет истории правок.
-ЭÑ\82о Ð¾Ð·Ð½Ð°Ñ\87аеÑ\82, Ñ\87Ñ\82о Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð¿ÐµÑ\80еименоваÑ\82Ñ\8c Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ð¾Ð±Ñ\80аÑ\82но Ð² Ñ\82о Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ, ÐºÐ¾Ñ\82оÑ\80ое Ñ\83 Ð½ÐµÐ³Ð¾ Ñ\82олÑ\8cко Ñ\87Ñ\82о Ð±Ñ\8bло, ÐµÑ\81ли Ð²Ñ\8b Ð¿ÐµÑ\80еименовали Ð¿Ð¾ Ð¾Ñ\88ибке, но вы не можете случайно затереть существующую страницу.
\9eбÑ\80аÑ\82иÑ\82е Ð²Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ, Ñ\87Ñ\82о Ñ\81Ñ\82Ñ\80аниÑ\86а '''не Ð±Ñ\83деÑ\82''' Ð¿ÐµÑ\80еименована, ÐµÑ\81ли Ñ\83же Ñ\81Ñ\83Ñ\89еÑ\81Ñ\82вÑ\83еÑ\82 Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81 Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼, Ð¸Ð´ÐµÐ½Ñ\82иÑ\87нÑ\8bм Ð²Ñ\8bбÑ\80анномÑ\83, ÐºÑ\80оме Ñ\81лÑ\83Ñ\87аев, ÐºÐ¾Ð³Ð´Ð° Ñ\82акаÑ\8f Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\8fвлÑ\8fеÑ\82Ñ\81Ñ\8f Ð¿ÐµÑ\80енапÑ\80авлением Ð¸Ð»Ð¸ Ð¿Ñ\83Ñ\81Ñ\82а, Ð¸ Ð¿Ñ\80и Ñ\8dÑ\82ом не имеет истории правок.
+ЭÑ\82о Ð¾Ð·Ð½Ð°Ñ\87аеÑ\82, Ñ\87Ñ\82о ÐµÑ\81ли Ð²Ñ\8b Ñ\81делали Ð¿Ñ\80еименование Ð¾Ñ\88ибоÑ\87но, Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð¿ÐµÑ\80еименоваÑ\82Ñ\8c Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ð¾Ð±Ñ\80аÑ\82но Ð² Ñ\82о Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ, ÐºÐ¾Ñ\82оÑ\80ое Ñ\83 Ð½ÐµÑ\91 Ñ\82олÑ\8cко Ñ\87Ñ\82о Ð±Ñ\8bло, но вы не можете случайно затереть существующую страницу.
 
-'''ПРЕДУПРЕЖДЕНИЕ!'''
-Переименование может привести к масштабным и неожиданным изменениям для ''популярных'' страниц.
\9fожалÑ\83йÑ\81Ñ\82а, Ð¿Ñ\80ежде Ñ\87ем Ð²Ñ\8b Ð¿Ñ\80одолжиÑ\82е, Ñ\83бедиÑ\82еÑ\81Ñ\8c, Ñ\87Ñ\82о Ð²Ñ\8b понимаете все возможные последствия.",
+'''Предупреждение!'''
+Переименование ''популярных'' страниц может привести к масштабным и неожиданным изменениям.
\9fожалÑ\83йÑ\81Ñ\82а, Ð¿Ñ\80ежде Ñ\87ем Ð¿Ñ\80одолжаÑ\82Ñ\8c, Ñ\83бедиÑ\82еÑ\81Ñ\8c, Ñ\87Ñ\82о понимаете все возможные последствия.",
 'movepagetext-noredirectfixer' => "Воспользовавшись формой ниже, вы переименуете страницу, одновременно переместив на новое место её журнал изменений.
 Старое название станет перенаправлением на новое название.
 Пожалуйста, проверьте наличие [[Special:DoubleRedirects|двойных]] и [[Special:BrokenRedirects|разорванных перенаправлений]].
@@ -3241,6 +3242,7 @@ The wiki server can't provide data in a format your client can read.",
 'pageinfo-robot-noindex' => 'Не индексируется',
 'pageinfo-views' => 'Количество просмотров',
 'pageinfo-watchers' => 'Число наблюдающих',
+'pageinfo-few-watchers' => 'Менее $1 {{PLURAL:$1|следящего|следящих}}',
 'pageinfo-redirects-name' => 'Перенаправления на эту страницу',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Подстраницы данной страницы',
@@ -4103,7 +4105,7 @@ MediaWiki распространяется в надежде, что она бу
 'specialpages-group-highuse' => 'Интенсивно используемые страницы',
 'specialpages-group-pages' => 'Списки страниц',
 'specialpages-group-pagetools' => 'Инструменты для страниц',
-'specialpages-group-wiki' => 'Ð\92ики-данные и инструменты',
+'specialpages-group-wiki' => 'Ð\94анные и инструменты',
 'specialpages-group-redirects' => 'Перенаправляющие служебные страницы',
 'specialpages-group-spam' => 'Инструменты против спама',
 
@@ -4200,8 +4202,8 @@ MediaWiki распространяется в надежде, что она бу
 'logentry-newusers-newusers' => 'Создана учётная запись $1',
 'logentry-newusers-create' => 'Создана учётная запись $1',
 'logentry-newusers-create2' => '$1 {{GENDER:$2|создал|создала}} учётную запись для $3',
+'logentry-newusers-byemail' => 'Учетная запись пользователя $3 была создана $1 и пароль был отправлен по электронной почте',
 'logentry-newusers-autocreate' => 'Автоматически создана учётная запись $1',
-'newuserlog-byemail' => 'пароль отправлен по эл. почте',
 'logentry-rights-rights' => '$1 {{GENDER:$1|изменил|изменила}} членство в группах для $3 с $4 на $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|изменил|изменила}} членство в группах для $3',
 'logentry-rights-autopromote' => 'Учётная запись «$1» была автоматически переведена из $4 в $5',
@@ -4259,6 +4261,7 @@ MediaWiki распространяется в надежде, что она бу
 'api-error-ok-but-empty' => 'Внутренняя ошибка: нет ответа от сервера.',
 'api-error-overwrite' => 'Не допускается замена существующего файла.',
 'api-error-stashfailed' => 'Внутренняя ошибка: сервер не смог сохранить временный файл.',
+'api-error-publishfailed' => 'Внутренняя ошибка: сервер не смог сохранить временный файл.',
 'api-error-timeout' => 'Сервер не отвечает в течение ожидаемого времени.',
 'api-error-unclassified' => 'Произошла неизвестная ошибка',
 'api-error-unknown-code' => 'Неизвестная ошибка: «$1»',
index 535e695..fff9084 100644 (file)
@@ -3701,7 +3701,6 @@ MediaWiki є дістрібуована в надїї, же буде хосно
 'logentry-newusers-create' => 'Створене было хосновательске конто $1',
 'logentry-newusers-create2' => '$1 створив хосновательске конто $3',
 'logentry-newusers-autocreate' => 'Автоматічно было створене конто $1',
-'newuserlog-byemail' => 'гело послане електронічнов поштов',
 'logentry-rights-rights' => '$1 {{GENDER:$1|змінив|змінила}} членство в ґрупах про $3 із $4 на $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|змінив|змінила}} членство в ґрупах про $3',
 'logentry-rights-autopromote' => '$1 было автоматічно переведено із $4 в $5',
index 264720a..67b8110 100644 (file)
@@ -2293,7 +2293,32 @@ See https://www.mediawiki.org/wiki/Manual:Image_Authorization.',
 'enotif_lastvisited' => 'भवतः पूवसन्दर्शनस्य पश्चात् सवृत्तपरिवर्तनार्थं $1 पश्यतु ।',
 'enotif_lastdiff' => 'एतत्परिवर्तनं दृष्टुं $1 पश्यतु ।',
 'enotif_anon_editor' => 'अनामकः योजकः $1',
-'enotif_body' => 'आत्मीय $ अवलोकनबन्धो',
+'enotif_body' => 'Dear $WATCHINGUSERNAME,
+
+$PAGEINTRO $NEWPAGE
+
+Editor\'s summary: $PAGESUMMARY $PAGEMINOREDIT
+
+Contact the editor:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+There will be no other notifications in case of further activity unless you visit this page. You could also reset the notification flags for all your watched pages on your watchlist.
+
+                        Your friendly {{SITENAME}} notification system
+
+--
+To change your e-mail notification settings, visit
+{{canonicalurl:{{#special:Preferences}}}}
+
+To change your watchlist settings, visit
+{{canonicalurl:{{#special:EditWatchlist}}}}
+
+To delete the page from your watchlist, visit
+$UNWATCHURL
+
+Feedback and further assistance:
+{{canonicalurl:{{MediaWiki:Helppage}}}}',
 'created' => 'सृष्टम् ।',
 'changed' => 'परिवर्तितम् ।',
 
@@ -3015,6 +3040,9 @@ $2 इति प्रकारस्य अवरोधं कर्तुं 
 'pageinfo-protect-cascading' => 'अतस्तु संरक्षणविधिः सोपानवत् गच्छति',
 'pageinfo-protect-cascading-yes' => 'आम्',
 'pageinfo-protect-cascading-from' => 'अधोलिखितेभ्यः संरक्षणविधिः सोपानवत् गच्छति',
+'pageinfo-category-info' => 'वर्गविषयकसूचना',
+'pageinfo-category-pages' => 'पृष्ठानां सङ्ख्या',
+'pageinfo-category-subcats' => 'उपवर्गानां सङ्ख्या',
 
 # Skin names
 'skinname-standard' => 'पूर्व',
@@ -3846,7 +3874,6 @@ $1 इत्यनेन $3 इति पृष्ठम् $4 इत्ये
 'logentry-newusers-create' => '$1 योजकलेखाम् असृजत्',
 'logentry-newusers-create2' => '$1,  $3 इति योजकलेखाम् असृजत्',
 'logentry-newusers-autocreate' => '$1 लेखा स्वयमेव सृष्टं जातम्',
-'newuserlog-byemail' => 'कूटशब्दः ईपत्रद्वारा प्रेषितः',
 'logentry-rights-rights' => '$1 इत्ययं $3 इत्यस्य समूहसदस्यतां $4 इत्यतः परिवर्त्य $5 इत्यकरोत्',
 'logentry-rights-rights-legacy' => '$1, $3 इत्यस्मै समूहसदस्यतां पर्यवर्तयत्',
 'logentry-rights-autopromote' => '$1 इत्ययं स्वचालितरूपेण $4 इत्यतः $5 इति यावत् पदोन्नतः',
index eff6726..ab74e45 100644 (file)
@@ -176,6 +176,7 @@ $messages = array(
 'newwindow' => '(атын түннүккэ арыллар)',
 'cancel' => 'Алҕас',
 'moredotdotdot' => 'Өссө...',
+'morenotlisted' => 'Атын суох...',
 'mypage' => 'Сирэй',
 'mytalk' => 'Кэпсэтэр сирим',
 'anontalk' => 'Бу IP-га ырытыы',
@@ -475,7 +476,7 @@ $2',
 'gotaccount' => "Бэлиэтэммитиҥ дуо? '''$1'''.",
 'gotaccountlink' => 'Аатыҥ',
 'userlogin-resetlink' => 'Киирэр тылгын умнубуккун дуо?',
-'createaccountmail' => 'e-mail-ынан',
+'createaccountmail' => 'Быстах киирии тылы туһаныы уонна ону email-ынан ыытыы',
 'createaccountreason' => 'Төрүөтэ:',
 'badretype' => 'Киирии тылларыҥ сөп түбэспэтилэр.',
 'userexists' => 'Суруйбут аатыҥ бэлиэр баар.
@@ -549,6 +550,7 @@ $2',
 # E-mail sending
 'php-mail-error-unknown' => 'mail() PHP-функциятыгар туох эрэ алҕас тахсыбыт',
 'user-mail-no-addy' => 'Сурук аадырыһа суох ыыттылла сатаабыт',
+'user-mail-no-body' => 'Кураанах эбэтэр суолтата суох кылгас тиэкистээх суругу ыыта сатаабыт.',
 
 # Change password dialog
 'resetpass' => 'Киирии тылы уларытыы',
@@ -776,10 +778,10 @@ IP-аадырыһа эрэ көстөр.
 'copyrightwarning2' => "Болҕой, эн суруйбут матырыйаалгын ким баҕарар уларытар уонна суох гынар бырааптаах. Суруйбуккун уларыталларын сөбүлээбэт буоллаххына манна суруйума.<br />
 Эбиитин манна суруйдаххына, уларытыы ааптара мин буолабын, эбэтэр көҥүл туһанары уонна уларытары көҥүллүүр сиртэн ыллым диэн бигэргэтэҕин (маны көр $1).<br /> '''КИМ ЭРЭ БАС БИЛИИТИН МАННА КИНИТТЭН КӨҤҮЛЭ СУОХ УГУМА!'''",
 'longpageerror' => "'''Алҕас: Суруйар кэрчиккит {{PLURAL:$1|биир килобаайт|$1 килобаайт}} ыйааһыннаах, онтуккут көҥүллэммит {{PLURAL:$2|биир килобаайты|$2 килобайты}} килобаайты куоһарар. Онон сирэй бигэргэтиллэр кыаҕа суох.'''",
-'readonlywarning' => "'''СЭРЭТИИ: Сиэрбэргэ техническай үлэ бара турар, онон киллэрбит уларытыыларыҥ тута хаалар кыахтара суох.
\91илигин Ñ\83лаÑ\80Ñ\8bÑ\82Ñ\8bÑ\8bгÑ\8bн Ð±Ñ\8dйÑ\8dÒ¥ Ð´Ð¸Ð¸Ñ\81кÑ\8dÒ\95Ñ\8dÑ\80 Ñ\85ааллаÑ\80ан Ð±Ð°Ñ\80ан, ÐºÑ\8dлин Ð¼Ð°Ð½Ð½Ð° Ñ\83ган Ð±Ð¸Ñ\8dÑ\80иÑ\8dÑ\85Ñ\85ин Ñ\81өп.'''
+'readonlywarning' => "'''Сэрэтии: Сиэрбэргэ техническай үлэ бара турар, онон киллэрбит уларытыыларыҥ тута бигэргэнэр кыахтара суох.'''
\9eнон Ñ\83лаÑ\80Ñ\8bÑ\82Ñ\8bÑ\8bгÑ\8bн Ñ\82иÑ\8dкиÑ\81Ñ\82Ñ\8dÑ\8dÑ\85 Ð±Ð¸Ð»Ñ\8dÒ\95Ñ\8d Ñ\83ган Ð±Ð°Ñ\80ан, ÐºÑ\8dлин Ð¼Ð°Ð½Ð½Ð° ÐºÐ¸Ð»Ð»Ñ\8dÑ\80иÑ\8dÑ\85Ñ\85ин Ñ\81өп.
 
\94Ñ\8cаһабÑ\8bл Ð¼Ð°Ð½Ð½Ñ\8bк Ð±Ñ\8bһаарбыт: $1",
¥Ð°Ð°Ñ\87Ñ\87аÒ\95Ñ\8b Ñ\82Ñ\83Ñ\80Ñ\83оÑ\80бÑ\83Ñ\82 Ð´Ñ\8cаһабÑ\8bл Ð¼Ð°Ð½Ð½Ñ\8bк Ð±Ñ\8bһааÑ\80Ñ\8bÑ\8bнÑ\8b Ñ\85аалларбыт: $1",
 'protectedpagewarning' => "'''Сэрэтии:  Бу сирэй хатанан турар, администратор бырааптаах эрэ кыттааччылар уларытар кыахтаахтар.'''
 Аллара сурунаал бүтэһик суруга көрдөрүлүннэ:",
 'semiprotectedpagewarning' => "'''Биллэрии:''' Бу сирэй хатанан турар; ааттарын билиһиннэрбит эрэ кыттааччылар уларытар кыахтаахтар.
@@ -818,6 +820,7 @@ IP-аадырыһа эрэ көстөр.
 'edit-already-exists' => 'Саҥа сирэйи оҥорор табыллыбат.
 Маннык сирэй баар эбит.',
 'defaultmessagetext' => 'Туспа этиллибэтэҕинэ суруллар тиэкис',
+'content-failed-to-parse' => '$2 иһинээҕитэ $1 көрүҥэр сөп түбэспэт: $3.',
 'invalid-content-data' => 'Алҕастаах дааннайдар',
 'content-not-allowed-here' => '[[$2]] сирэйгэ "$1" туттуллуо суохтаах',
 
@@ -845,6 +848,7 @@ IP-аадырыһа эрэ көстөр.
 'node-count-exceeded-warning' => 'Сирэй түмүгүн ахсаана таһынан барбыт',
 'expansion-depth-exceeded-category' => 'Аһыллыытын дириҥэ куоһарыллыбыт сирэйдэр',
 'expansion-depth-exceeded-warning' => 'Сирэйгэ угуллубут билэлэр аһара элбээбиттэр',
+'parser-unstrip-loop-warning' => 'Сабыллыбатах pre көһүннэ',
 'parser-unstrip-recursion-limit' => 'Рекурсия ахсаана таһынан барбыт ($1)',
 'converter-manual-rule-error' => 'Тылы уларытыы быраабылатын алҕаһа таҕыста',
 
@@ -1985,7 +1989,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Көхтөөх кыттааччылар тиһиктэрэ',
 'activeusers-intro' => 'Бу кэлиҥҥи $1 {{PLURAL:$1|күҥҥэ|күннэргэ}} тугу эмэ гыммыт кыттааччылар тиһиктэрэ.',
-'activeusers-count' => '$1 бүтэһик $3 күҥҥэ саҥа {{PLURAL:$1|көннөрүүлээх|көннөрүүлээх эбит}}',
+'activeusers-count' => 'Кэнники $3 күҥҥэ саҥа $1 көннөрүү киирбит',
 'activeusers-from' => 'Мантан саҕалаан кыттааччылары көрүү:',
 'activeusers-hidebots' => 'Руобаттары көрдөрүмэ',
 'activeusers-hidesysops' => 'Дьаһабыллары көрдөрүмэ',
@@ -2049,7 +2053,7 @@ $1',
 'usermessage-editor' => 'Тиһилик биллэрээччитэ',
 
 # Watchlist
-'watchlist' => 'Ð\9cин ÐºÑ\8dÑ\82Ñ\8dÑ\8dһиним',
+'watchlist' => 'Ð\9aÑ\8dÑ\82Ñ\8dбилим Ñ\82иһигÑ\8d',
 'mywatchlist' => 'Кэтэбил тиһигэ',
 'watchlistfor2' => '$1 $2 аналлаах',
 'nowatchlist' => 'Эн кэтиир сирэйдэриҥ суохтар.',
@@ -2057,8 +2061,8 @@ $1',
 'watchnologin' => 'Бэйэҕин билиһиннэр',
 'watchnologintext' => 'Бэйэҕин [[Special:UserLogin|билиһиннэрдэххинэ]] кэтэбил сирэйгин уларытыаххын сөп.',
 'addwatch' => 'Кэтэбил тиһигэр киллэр',
-'addedwatchtext' => "«[[:$1]]» сирэй [[Special:Watchlist|кэтэбилгэ]] киирдэ.
-Сирэй уларытыылара уонна кинини кытта ситимнээх ырытыы сирэйин уларытыылара бүгүҥҥүттэн онно көстөр буолуохтара. Эбиитин [[Special:RecentChanges|саҥа уларытыы тиһигэр]] '''модьу''' бичигинэн бэлиэтэнэн көстүөхтэрэ.",
+'addedwatchtext' => '«[[:$1]]» сирэй [[Special:Watchlist|кэтэбил тиһигэр]] киирдэ.
+Сирэй уларытыылара уонна кинини кытта ситимнээх ырытыы сирэйин уларытыылара бүгүҥҥүттэн онно көстөр буолуохтара.',
 'removewatch' => 'Кэтэбил тиһигиттэн сот',
 'removedwatchtext' => '[[:$1]]" сирэй [[Special:Watchlist|кэтэбилиҥ тиһигиттэн]] сотулунна.',
 'watch' => 'Кэтээ',
@@ -2200,9 +2204,9 @@ $UNWATCHURL
 '''$1''' сирэй уларыыттын таһыма билиҥҥи туругунан маннык:",
 'protect-cascadeon' => 'Бу сирэй уларытыыттан көмүскэммит {{PLURAL:$1|сирэй бөлөҕөр|сирэйдэр бөлөхтөрүгэр}} (каскааднай көмүскэл) киирэр буолан эмиэ көмүскэммит. Эн көмүскэнии таһымын уларытыаххын сөп, ол каскаднай көмүскэли уларыппат.',
 'protect-default' => 'Барыларыгар көҥүллэнэр',
-'protect-fallback' => '"$1" көҥүллэ көрдөө',
-'protect-level-autoconfirmed' => 'Саҥа Ñ\83онна Ð±Ñ\8dлиÑ\8dÑ\82Ñ\8dммÑ\8dÑ\82Ñ\8dÑ\85 ÐºÑ\8bÑ\82Ñ\82ааÑ\87Ñ\87Ñ\8bлаÑ\80 Ñ\83лаÑ\80Ñ\8bппаÑ\82Ñ\82аÑ\80Ñ\8bн ÐºÑ\83Ñ\80дÑ\83к Ð¾Ò¥Ð¾р',
-'protect-level-sysop' => 'Дьаһабыллар эрэ',
+'protect-fallback' => '"$1" кыттааччылар эрэ маны оҥорор кыахтаахтар',
+'protect-level-autoconfirmed' => 'Ð\90пÑ\82амааÑ\82Ñ\8bнан Ð±Ð¸Ð³Ñ\8dÑ\80гÑ\8dммиÑ\82 ÐºÑ\8bÑ\82Ñ\82ааÑ\87Ñ\87Ñ\8bлаÑ\80га Ñ\8dÑ\80Ñ\8d ÐºÓ©Ò¥Ò¯Ð»Ð»Ñ\8dнÑ\8dр',
+'protect-level-sysop' => 'Дьаһабылларга эрэ көҥүллэнэр',
 'protect-summary-cascade' => 'каскадтаах',
 'protect-expiring' => 'болдьоҕо $1 (UTC)',
 'protect-expiring-local' => 'болдьоҕо баччаҕа бүтэр: $1',
@@ -2498,15 +2502,15 @@ $1',
 'movepagetext' => "Манна баар форманы туһанан сирэй аатын уларытыаххын сөп.
 Бу түбэлтэҕэ уларытыы сурунаала саҥа сиргэ көһөр.
 Урукку аат саҥа сирэйгэ утаарар сирэйгэ кубулуйар.
-Урукку аакка ыйынньыктар уларыйбаттар;
-бука диэн [[Special:DoubleRedirects|хос ыйынньыктар]] уонна [[Special:BrokenRedirects|быстыбыт сигэниилэр]] баалларын-суохтарын көр.
+Урукку аакка ыйынньыктары аптамаатынан уларытыаххын сөп.
\98ннÑ\8cÑ\8d Ð³Ñ\8bммаÑ\82 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна, Ð±Ñ\83ка Ð´Ð¸Ñ\8dн [[Special:DoubleRedirects|Ñ\85оÑ\81 Ñ\8bйÑ\8bннÑ\8cÑ\8bкÑ\82аÑ\80]] Ñ\83онна [[Special:BrokenRedirects|бÑ\8bÑ\81Ñ\82Ñ\8bбÑ\8bÑ\82 Ñ\81игÑ\8dниилÑ\8dÑ\80]] Ð±Ð°Ð°Ð»Ð»Ð°Ñ\80Ñ\8bн-Ñ\81Ñ\83оÑ\85Ñ\82аÑ\80Ñ\8bн ÐºÓ©Ñ\80.
 Сиэр быһыытынан ыйынньыктар сөпкө сигэнэллэрин эн ситиһиэхтээххин.
 
 Өскө маннык ааттаах сирэй номнуо баар буоллаҕына сирэй аата '''уларыйыа суоҕа''', арай ол сирэй кураанах эбэтэр утаарар сирэй буолбатах буоллаҕына.
-Ол аата эн сирэй аатын сыыһа уларыппыт буоллаххына төттөрү урукку аатыгар төннөрүөххүн сөп гынан баран баар сирэйи алҕас сотор кыаҕыҥ суох.
+Ол аата эн сирэй аатын сыыһа уларыппыт буоллаххына төттөрү урукку аатыгар төннөрүөххүн сөп, ол гынан баран баар сирэйи алҕас сотор кыаҕыҥ суох.
 
-'''СЭРЭТИИ!'''
-Сирэй аатын уларытыы улахан уонна эрдэттэн өйдөммөтөх содуллаах буолуон сөп.
+'''Сэрэтии!'''
+Сирэй аатын уларытыы бөдөҥ уонна эрдэттэн өйдөммөтөх содуллаах буолуон сөп.
 Онон, бука диэн салгыаҥ иннинэ үчүгэйдик толкуйдаа.",
 'movepagetext-noredirectfixer' => "Манна баар форманы туһанан сирэй аатын уларытыаххын сөп.
 Бу түбэлтэҕэ уларытыы сурунаала саҥа сиргэ көһөр.
@@ -2841,6 +2845,7 @@ $1',
 'pageinfo-recent-authors' => 'Бу сирэйи уларыппыт киһи ахсаана',
 'pageinfo-magic-words' => 'Аптаах {{PLURAL:$1|тыл|тыллар}} ($1)',
 'pageinfo-hidden-categories' => 'Кистэммит {{PLURAL:$1|категория|категориялар}} ($1)',
+'pageinfo-templates' => '$1 халыыптаах ($1)',
 'pageinfo-contentpage-yes' => 'Сөп',
 'pageinfo-protect-cascading' => 'Каскаадынан көмүскэл мантан',
 'pageinfo-protect-cascading-yes' => 'Сөп',
@@ -3579,7 +3584,7 @@ MediaWiki туһалаах буоллун диэн тарҕатыллар, ол
 'specialpages-group-highuse' => 'Элбэхтик туттуллар сирэйдэр',
 'specialpages-group-pages' => 'Сирэйдэр тиһиктэрэ',
 'specialpages-group-pagetools' => 'Сирэйдэр үнүстүрүмүөннэрэ',
-'specialpages-group-wiki' => 'Wiki дааннайдара уонна үнүстүрүмүөннэр',
+'specialpages-group-wiki' => 'Дааннайдара уонна тэриллэрэ',
 'specialpages-group-redirects' => 'Утаарар аналлаах сирэйдэр',
 'specialpages-group-spam' => 'Спаамы утары үнүстүрүмүөннэр',
 
@@ -3675,9 +3680,8 @@ MediaWiki туһалаах буоллун диэн тарҕатыллар, ол
 'logentry-patrol-patrol-auto' => '$1 $3 сирэй $4 барылын аптамаатынан ботуруулламмыт курдук бэлиэтээбит',
 'logentry-newusers-newusers' => '$1 диэн кыттааччы бэлиэтэннэ',
 'logentry-newusers-create' => '$1 диэн кыттааччы бэлиэтэннэ',
-'logentry-newusers-create2' => '$3 кыттааччыны $1 бэлиэтээбит',
+'logentry-newusers-create2' => '$3 кыттааччы аатын $1 бэлиэтээбит',
 'logentry-newusers-autocreate' => 'Маннык аат $1 аптамаатынан бэлиэтэнилиннэ',
-'newuserlog-byemail' => 'киирии тыл эл. почтаннан ыытылынна',
 'rightsnone' => '(суох)',
 
 # Feedback
index 94897ca..f41597f 100644 (file)
@@ -1549,7 +1549,6 @@ Is acàpius chi sighint in sa matessi lìnia sunt cunsideraus comente eccetzione
 'htmlform-selectorother-other' => 'Àteru',
 
 # New logging system
-'newuserlog-byemail' => 'password imbiada via e-mail',
 'rightsnone' => '(nisciunu)',
 
 # Search suggestions
index 447c5dd..3e1d325 100644 (file)
@@ -51,89 +51,104 @@ $namespaceAliases = array(
 );
 
 $specialPageAliases = array(
-       'Allmessages'               => array( 'Missaggi' ),
-       'Allpages'                  => array( 'TuttiLiPàggini' ),
-       'Ancientpages'              => array( 'PàgginiMenuNovi' ),
-       'Blankpage'                 => array( 'PàgginaVacanti' ),
+       'Activeusers'               => array( 'UtentiAttivi' ),
+       'Allmessages'               => array( 'Messaggi' ),
+       'Allpages'                  => array( 'TutteLePagine' ),
+       'Ancientpages'              => array( 'PagineMenoRecenti' ),
+       'Badtitle'                  => array( 'TitoloErrato' ),
+       'Blankpage'                 => array( 'PaginaVuota' ),
        'Block'                     => array( 'Blocca' ),
        'Blockme'                   => array( 'BloccaProxy' ),
        'Booksources'               => array( 'RicercaISBN' ),
-       'BrokenRedirects'           => array( 'RinnirizzamentiSbagghiati' ),
-       'Categories'                => array( 'Catigurìi' ),
-       'ChangePassword'            => array( 'RimpostaPassword' ),
-       'Confirmemail'              => array( 'CunfermaEmail' ),
-       'Contributions'             => array( 'Cuntribbuti', 'CuntribbutiUtenti' ),
-       'CreateAccount'             => array( 'CrìatiNuCuntu' ),
-       'Deadendpages'              => array( 'PàgginiSenzaNisciuta' ),
-       'DeletedContributions'      => array( 'CuntribbutiScancillati' ),
-       'Disambiguations'           => array( 'Disambiguazzioni' ),
-       'DoubleRedirects'           => array( 'RinnirizzamentiDuppi' ),
-       'Emailuser'                 => array( 'MannaEmail' ),
+       'BrokenRedirects'           => array( 'RedirectErrati' ),
+       'Categories'                => array( 'Categorie' ),
+       'ChangeEmail'               => array( 'CambiaEmail' ),
+       'ChangePassword'            => array( 'CambiaPassword' ),
+       'ComparePages'              => array( 'ComparaPagine' ),
+       'Confirmemail'              => array( 'ConfermaEMail' ),
+       'Contributions'             => array( 'Contributi', 'ContributiUtente', 'Edit' ),
+       'CreateAccount'             => array( 'CreaAccount' ),
+       'Deadendpages'              => array( 'PagineSenzaUscita' ),
+       'DeletedContributions'      => array( 'ContributiCancellati' ),
+       'Disambiguations'           => array( 'Disambigua' ),
+       'DoubleRedirects'           => array( 'RedirectDoppi' ),
+       'EditWatchlist'             => array( 'ModificaOsservati', 'ModificaOsservatiSpeciali', 'ModificaListaSeguiti' ),
+       'Emailuser'                 => array( 'InviaEMail' ),
        'Export'                    => array( 'Esporta' ),
-       'Fewestrevisions'           => array( 'PàgginiCuCchiùPiccaRivisioni' ),
-       'Import'                    => array( 'Mporta' ),
-       'BlockList'                 => array( 'IPBluccati' ),
-       'LinkSearch'                => array( 'CercaCullicamenti' ),
-       'Listadmins'                => array( 'Amministratura' ),
-       'Listbots'                  => array( 'ListaBot' ),
-       'Listfiles'                 => array( 'Mmàggini' ),
-       'Listgrouprights'           => array( 'AlencuPirmessiGruppi' ),
-       'Listredirects'             => array( 'Rinnirizzamenti', 'ListaRinnirizzamenti' ),
-       'Listusers'                 => array( 'Utilizzatura', 'ListaUtilizzatura' ),
-       'Lockdb'                    => array( 'BloccaDB', 'BloccaDatabase' ),
-       'Log'                       => array( 'Riggistri', 'Riggistru' ),
-       'Lonelypages'               => array( 'PàgginiOrfani' ),
-       'Longpages'                 => array( 'PàgginiCchiùLonghi' ),
-       'MergeHistory'              => array( 'UnìficaCrunuluggìa' ),
+       'Fewestrevisions'           => array( 'PagineConMenoRevisioni' ),
+       'FileDuplicateSearch'       => array( 'CercaFileDuplicati' ),
+       'Filepath'                  => array( 'Percorso' ),
+       'Import'                    => array( 'Importa' ),
+       'Invalidateemail'           => array( 'InvalidaEMail' ),
+       'JavaScriptTest'            => array( 'TestJavaScript' ),
+       'BlockList'                 => array( 'IPBloccati', 'ElencoBlocchi', 'Blocchi' ),
+       'LinkSearch'                => array( 'CercaCollegamenti', 'CercaLink' ),
+       'Listadmins'                => array( 'Amministratori', 'ElencoAmministratori', 'Admin', 'Sysop', 'Cricca' ),
+       'Listbots'                  => array( 'Bot', 'ElencoBot' ),
+       'Listfiles'                 => array( 'File', 'Immagini' ),
+       'Listgrouprights'           => array( 'ElencoPermessiGruppi', 'Privilegi' ),
+       'Listredirects'             => array( 'Redirect', 'ElencoRedirect' ),
+       'Listusers'                 => array( 'Utenti', 'ElencoUtenti' ),
+       'Lockdb'                    => array( 'BloccaDB' ),
+       'Log'                       => array( 'Registri', 'Registro' ),
+       'Lonelypages'               => array( 'PagineOrfane' ),
+       'Longpages'                 => array( 'PaginePiùLunghe' ),
+       'MergeHistory'              => array( 'FondiCronologia', 'UnificaCronologia' ),
        'MIMEsearch'                => array( 'RicercaMIME' ),
-       'Mostcategories'            => array( 'PàgginiCuCchiossaiCatigurìi' ),
-       'Mostimages'                => array( 'MmàgginiCchiùRichiamati' ),
-       'Mostlinked'                => array( 'PàgginiCchiùRichiamati' ),
-       'Mostlinkedcategories'      => array( 'CatigurìiCchiùRichiamati' ),
-       'Mostlinkedtemplates'       => array( 'TemplateCchiùRichiamati' ),
-       'Mostrevisions'             => array( 'PàgginiCuCchiossaiRivisioni' ),
-       'Movepage'                  => array( 'Sposta', 'Rinòmina' ),
-       'Mycontributions'           => array( 'CuntribbutiMei' ),
-       'Mypage'                    => array( 'MèPàgginaUtenti' ),
-       'Mytalk'                    => array( 'DiscussioniMei' ),
-       'Newimages'                 => array( 'MmàgginiRicenti' ),
-       'Newpages'                  => array( 'PàgginiCchiùNovi' ),
-       'Popularpages'              => array( 'PàgginiCchiùVisitati' ),
-       'Preferences'               => array( 'Prifirenzi' ),
-       'Prefixindex'               => array( 'Prifissi' ),
-       'Protectedpages'            => array( 'PàgginiPrutiggiuti' ),
-       'Protectedtitles'           => array( 'TìtuliPrutiggiuti' ),
-       'Randompage'                => array( 'PàgginaAmmuzzu' ),
-       'Randomredirect'            => array( 'RedirectAmmuzzu' ),
-       'Recentchanges'             => array( 'ÙrtimiCanciamenti' ),
-       'Recentchangeslinked'       => array( 'CanciamentiCurrilati' ),
-       'Revisiondelete'            => array( 'ScancellaRivisioni' ),
-       'Search'                    => array( 'Ricerca', 'Cerca' ),
-       'Shortpages'                => array( 'PàgginiCchiùCurti' ),
-       'Specialpages'              => array( 'PàgginiSpiciali' ),
-       'Statistics'                => array( 'Statìstichi' ),
-       'Uncategorizedcategories'   => array( 'CatigurìiSenzaCatigurìi' ),
-       'Uncategorizedimages'       => array( 'MmàgginiSenzaCatigurìi' ),
-       'Uncategorizedpages'        => array( 'PàgginiSenzaCatigurìi' ),
-       'Uncategorizedtemplates'    => array( 'TemplateSenzaCatigurìi' ),
-       'Undelete'                  => array( 'Riprìstina' ),
-       'Unlockdb'                  => array( 'SbloccaDB', 'SbloccaDatabase' ),
-       'Unusedcategories'          => array( 'CatigurìiNonUsati' ),
-       'Unusedimages'              => array( 'MmàgginiNonUsati' ),
-       'Unusedtemplates'           => array( 'TemplateNunUsati' ),
-       'Unwatchedpages'            => array( 'PàgginiNunTaliati' ),
-       'Upload'                    => array( 'Càrrica' ),
-       'Userlogin'                 => array( 'Tràsi', 'Login' ),
-       'Userlogout'                => array( 'Nesci', 'Logout' ),
-       'Userrights'                => array( 'PirmessiUtenti' ),
-       'Version'                   => array( 'Virsioni' ),
-       'Wantedcategories'          => array( 'CatigurìiAddumannati' ),
-       'Wantedfiles'               => array( 'FileAddumannati' ),
-       'Wantedpages'               => array( 'PàgginiAddumannati' ),
-       'Wantedtemplates'           => array( 'TemplateAddumannati' ),
-       'Watchlist'                 => array( 'ArtìculiTaliati' ),
-       'Whatlinkshere'             => array( 'ChiPuntaCcà' ),
-       'Withoutinterwiki'          => array( 'SenzaInterwiki' ),
+       'Mostcategories'            => array( 'PagineConPiùCategorie' ),
+       'Mostimages'                => array( 'ImmaginiPiùRichiamate' ),
+       'Mostinterwikis'            => array( 'InterwikiPiùRichiamati' ),
+       'Mostlinked'                => array( 'PaginePiùRichiamate' ),
+       'Mostlinkedcategories'      => array( 'CategoriePiùRichiamate' ),
+       'Mostlinkedtemplates'       => array( 'TemplatePiùRichiamati' ),
+       'Mostrevisions'             => array( 'PagineConPiùRevisioni' ),
+       'Movepage'                  => array( 'Sposta', 'Rinomina' ),
+       'Mycontributions'           => array( 'MieiContributi' ),
+       'Mypage'                    => array( 'MiaPaginaUtente', 'MiaPagina' ),
+       'Mytalk'                    => array( 'MieDiscussioni' ),
+       'Myuploads'                 => array( 'MieiUpload', 'MieiEdit' ),
+       'Newimages'                 => array( 'ImmaginiRecenti' ),
+       'Newpages'                  => array( 'PaginePiùRecenti' ),
+       'PasswordReset'             => array( 'ReimpostaPassword' ),
+       'PermanentLink'             => array( 'LinkPermanente' ),
+       'Popularpages'              => array( 'PaginePiùVisitate' ),
+       'Preferences'               => array( 'Preferenze' ),
+       'Prefixindex'               => array( 'Prefissi' ),
+       'Protectedpages'            => array( 'PagineProtette' ),
+       'Protectedtitles'           => array( 'TitoliProtetti' ),
+       'Randompage'                => array( 'PaginaCasuale' ),
+       'Randomredirect'            => array( 'RedirectCasuale' ),
+       'Recentchanges'             => array( 'UltimeModifiche' ),
+       'Recentchangeslinked'       => array( 'ModificheCorrelate' ),
+       'Revisiondelete'            => array( 'CancellaRevisione' ),
+       'Search'                    => array( 'Arriscedi', 'Cerca', 'Trova' ),
+       'Shortpages'                => array( 'PaginePiùCorte' ),
+       'Specialpages'              => array( 'PagineSpeciali' ),
+       'Statistics'                => array( 'Statistiche' ),
+       'Tags'                      => array( 'Etichette', 'Tag' ),
+       'Unblock'                   => array( 'ElencoSblocchi', 'Sblocchi' ),
+       'Uncategorizedcategories'   => array( 'CategorieSenzaCategorie' ),
+       'Uncategorizedimages'       => array( 'ImmaginiSenzaCategorie' ),
+       'Uncategorizedpages'        => array( 'PagineSenzaCategorie' ),
+       'Uncategorizedtemplates'    => array( 'TemplateSenzaCategorie' ),
+       'Undelete'                  => array( 'Ripristina' ),
+       'Unlockdb'                  => array( 'SbloccaDB' ),
+       'Unusedcategories'          => array( 'CategorieNonUsate', 'CategorieVuote' ),
+       'Unusedimages'              => array( 'ImmaginiNonUsate' ),
+       'Unusedtemplates'           => array( 'TemplateNonUsati' ),
+       'Unwatchedpages'            => array( 'PagineNonOsservate' ),
+       'Upload'                    => array( 'Carica' ),
+       'Userlogin'                 => array( 'Entra', 'Login' ),
+       'Userlogout'                => array( 'Esci', 'Logout' ),
+       'Userrights'                => array( 'PermessiUtente' ),
+       'Version'                   => array( 'Versione' ),
+       'Wantedcategories'          => array( 'CategorieRichieste' ),
+       'Wantedfiles'               => array( 'FileRichiesti' ),
+       'Wantedpages'               => array( 'PagineRichieste' ),
+       'Wantedtemplates'           => array( 'TemplateRichiesti' ),
+       'Watchlist'                 => array( 'OsservatiSpeciali' ),
+       'Whatlinkshere'             => array( 'PuntanoQui' ),
+       'Withoutinterwiki'          => array( 'PagineSenzaInterwiki' ),
 );
 
 $messages = array(
@@ -616,6 +631,9 @@ Aspetta tanticchia prima di pruvari  n'àutra vota.",
 Pò èssiri ca ggià canciasti cu successu la tò password o c'addumannasti na nova password timpurrània.",
 'resetpass-temp-password' => 'Password timpurrània:',
 
+# Special:ChangeEmail
+'changeemail-submit' => 'Cancia e-mail',
+
 # Edit page toolbar
 'bold_sample' => 'Grassettu',
 'bold_tip' => 'Grassettu',
@@ -977,7 +995,7 @@ S'havi accirtari ca la cuntinuità storica di la pàggina nun veni altirata.",
 'searchhelp-url' => 'Help:Cuntinuti',
 'searchmenu-prefix' => '[[Special:PrefixIndex/$1|Visualizza li pàggini cu stu prifissu]]',
 'searchprofile-articles' => 'Pàggini di cuntinutu',
-'searchprofile-project' => "Pàggini d'aiutu e dô pruggettu",
+'searchprofile-project' => "Pàggini d'ajutu e dô pruggettu",
 'searchprofile-images' => 'Multimedia',
 'searchprofile-everything' => 'Tuttu',
 'searchprofile-advanced' => 'Avanzata',
@@ -1697,7 +1715,7 @@ Talìa macari li [[Special:WantedCategories|catigurìi addumannati]].',
 'linksearch' => 'Lijami di fora',
 'linksearch-pat' => 'Mudellu di circata:',
 'linksearch-ns' => 'Namespace:',
-'linksearch-ok' => 'Cerca',
+'linksearch-ok' => 'Arriscedi',
 'linksearch-text' => 'C\'è la pussibbilitati di fari usu di metacaràttiri, p\'asèmpiu "*.wikipedia.org".<br />
 Protucolli suppurtati: <code>$1</code>',
 'linksearch-line' => '$1 prisenti ntâ pàggina $2',
@@ -1762,6 +1780,7 @@ Protucolli suppurtati: <code>$1</code>',
 # Watchlist
 'watchlist' => 'Lista taliata mia',
 'mywatchlist' => 'Lista taliata mia',
+'watchlistfor2' => 'Pi $1, $2',
 'nowatchlist' => "Nun hai innicatu pàggini a tèniri d'occhiu.",
 'watchlistanontext' => "Pi visualizzari e canciari l'alencu di l'ossirvati spiciali è nicissariu $1.",
 'watchnologin' => 'Nun hai effittuatu lu login',
@@ -1998,7 +2017,7 @@ $1',
 'sp-contributions-search' => 'Ricerca cuntribbuti',
 'sp-contributions-username' => 'Nnirizzu IP o nomu utenti:',
 'sp-contributions-toponly' => "Ammuscia sulu li cuntribbuti ca sunnu l'ùrtimi rivisioni pâ pàggina",
-'sp-contributions-submit' => 'Ricerca',
+'sp-contributions-submit' => 'Risciduta',
 
 # What links here
 'whatlinkshere' => 'Chi punta ccà',
@@ -2063,7 +2082,7 @@ Pi maggiuri nfurmazzioni, talìa la [[Special:BlockList|lista di l'IP bluccati]]
 'unblocked-id' => 'Lu bloccu $1 hà statu cacciatu',
 'ipblocklist' => 'Utiloizzatura bluccati',
 'ipblocklist-legend' => "Atrova n'utenti bluccatu",
-'ipblocklist-submit' => 'Ricerca',
+'ipblocklist-submit' => 'Risciduta',
 'infiniteblock' => 'nfinitu',
 'expiringblock' => 'scadi lu $1 ê $2',
 'anononlyblock' => 'sulu anònimi',
@@ -2388,6 +2407,9 @@ Visita [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] e [//trans
 'spam_reverting' => "Ripristinata l'ùrtima virsioni priva di culligamenti a $1",
 'spam_blanking' => 'Pàggina svacantata, tutti li virsioni cuntinìanu culligamenti a $1',
 
+# Info page
+'pageinfo-toolboxlink' => 'Nfurmazzioni ncapu la pàggina',
+
 # Skin names
 'skinname-standard' => 'Classicu',
 'skinname-nostalgia' => 'Nustargìa',
@@ -2976,11 +2998,10 @@ Mèttiri lu nomu dû file senza lu prifissu "{{ns:file}}:"',
 'revdelete-unrestricted' => 'ristrizzioni pi suli amministraturi rimossi',
 'logentry-move-move' => '$1 spustau la pàggina $3 a $4',
 'logentry-newusers-create' => '$1 criau na utenza',
-'newuserlog-byemail' => 'password mannata via mail',
 'rightsnone' => '(nuddu)',
 
 # Search suggestions
-'searchsuggest-search' => 'Ricerca',
+'searchsuggest-search' => 'Risciduta',
 
 # API errors
 'api-error-nomodule' => 'Erruri nternu: nun fu mpustatu lu mòdulu di carricamentu',
index 31bd8ea..95d0344 100644 (file)
@@ -121,6 +121,8 @@ $magicWords = array(
        'numberofarticles'          => array( '1', 'ARTIHKKALIIDMEARRI', 'NUMBEROFARTICLES' ),
 );
 
+$separatorTransformTable = array( ',' => "\xc2\xa0", '.' => ',' );
+
 $linkTrail = '/^(:?[a-zàáâçčʒǯđðéèêëǧǥȟíìîïıǩŋñóòôõßšŧúùûýÿüžþæøåäö]+)(.*)$/sDu';
 
 $messages = array(
index e49f5b3..6f981d1 100644 (file)
@@ -1962,7 +1962,6 @@ Tamsta tēpuogi galėt [[Special:EditWatchlist/raw|redagoutė grīnaji keravuoja
 'logentry-newusers-newusers' => '$1 padėrba nauduotuojė paskīra',
 'logentry-newusers-create2' => '$1 padėrba nauduotuojė paskīra $3',
 'logentry-newusers-autocreate' => 'Paskīra $1 bova padėrbta autuomatėškā',
-'newuserlog-byemail' => 'slaptažuodis ėšsiōsts par el. pašta',
 'rightsnone' => '(juokiū)',
 
 );
index 4629ec4..c33c931 100644 (file)
@@ -340,6 +340,7 @@ $messages = array(
 'newwindow' => '(otvara se u novom prozoru)',
 'cancel' => 'Poništi',
 'moredotdotdot' => 'Još...',
+'morenotlisted' => 'Više nije prikazano...',
 'mypage' => 'Stranica',
 'mytalk' => 'Razgovor',
 'anontalk' => 'Razgovor za ovu IP adresu',
@@ -642,7 +643,7 @@ Ne zaboravite izmijeniti vlastite [[Special:Preferences|{{SITENAME}} postavke]].
 'gotaccount' => "Imate račun? '''$1'''.",
 'gotaccountlink' => 'Prijavi se',
 'userlogin-resetlink' => 'Zaboravili ste detalje vaše prijave?',
-'createaccountmail' => 'e-mailom',
+'createaccountmail' => 'Koristite privremenu slučajno stvorenu lozinku i pošaljite na dolje specificiranu e-mail adresu',
 'createaccountreason' => 'Razlog:',
 'badretype' => 'Lozinke koje ste unijeli se ne poklapaju.',
 'userexists' => 'Uneseno korisničko ime već je u upotrebi.
@@ -719,6 +720,7 @@ Molimo Vas da sačekate prije nego što pokušate ponovo.',
 # E-mail sending
 'php-mail-error-unknown' => 'Nepoznata greška u PHP funkciji mail()',
 'user-mail-no-addy' => 'Pokušaj slanja e-maila bez e-mail adrese.',
+'user-mail-no-body' => 'Pokušano slanje e-maila s praznim ili nerazumno kratkim sadržajem.',
 
 # Change password dialog
 'resetpass' => 'Promijeni korisničku šifru',
@@ -783,6 +785,7 @@ Privremena šifra: $2',
 'changeemail-oldemail' => 'Trenutna e-mail adresa:',
 'changeemail-newemail' => 'Nova e-mail adresa:',
 'changeemail-none' => '(ništa)',
+'changeemail-password' => 'Tvoja šifra/lozinka za {{SITENAME}}:',
 'changeemail-submit' => 'Promijeni e-mail',
 'changeemail-cancel' => 'Odustani',
 
@@ -951,8 +954,8 @@ Također nam garantujete da ste ovo Vi napisali, ili da ste ga kopirali iz javne
 '''NE ŠALJITE DJELA ZAŠTIĆENA AUTORSKIM PRAVOM BEZ DOZVOLE!'''",
 'longpageerror' => "'''Greška: tekst koji ste uneli je veličine {{PLURAL:$1|jedan kilobajt|$1 kilobajta|$1 kilobajta}}, što je veće od {{PLURAL:$2|dozvoljenog jednog kilobajta|dozvoljena $2 kilobajta|dozvoljenih $2 kilobajta}}.'''
 Stranica ne može biti sačuvana.",
-'readonlywarning' => "'''PAŽNJA: Baza je zaključana zbog održavanja, tako da nećete moći da snimite svoje izmjene za sada.
-Možda želite da kopirate i nalijepite tekst u tekst editor i sačuvate ga za kasnije.'''
+'readonlywarning' => "'''PAŽNJA: Baza je zaključana zbog održavanja, tako da nećete moći da sačuvate svoje izmjene za sada.'''
+Možda želite da kopirate i nalijepite tekst u tekst editor i sačuvate ga za kasnije.
 
 Administrator koji je zaključao bazu je naveo slijedeće objašnjenje: $1",
 'protectedpagewarning' => "'''PAŽNJA: Ova stranica je zaključana tako da samo korisnici sa administratorskim privilegijama mogu da je mijenjaju.'''
@@ -1260,7 +1263,7 @@ Više informacija možete pronaći u [{{fullurl:{{#Special:Log}}/delete|page={{F
 'search-interwiki-default' => '$1 rezultati:',
 'search-interwiki-more' => '(više)',
 'search-relatedarticle' => 'Povezano',
-'mwsuggest-disable' => 'Onemogući AJAX prijedloge',
+'mwsuggest-disable' => 'Onemogući prijedloge pretrage',
 'searcheverything-enable' => 'Pretraga u svim imenskim prostorima',
 'searchrelated' => 'povezano',
 'searchall' => 'sve',
@@ -1370,9 +1373,9 @@ Ovo se ne može vratiti unazad.',
 'prefs-emailconfirm-label' => 'E-mail potvrda:',
 'prefs-textboxsize' => 'Veličina prozora za uređivanje',
 'youremail' => 'E-mail:',
-'username' => 'Korisničko ime:',
-'uid' => 'Korisnički ID:',
-'prefs-memberingroups' => 'Član {{PLURAL:$1|grupe|grupa}}:',
+'username' => 'Ime {{GENDER:$1|korisnika|korisnice}}:',
+'uid' => '{{GENDER:$1|Korisnički}} ID:',
+'prefs-memberingroups' => '{{GENDER:$2|Korisnik|Korisnica}} je član {{PLURAL:$1|grupe|grupâ}}:',
 'prefs-registration' => 'Vrijeme registracije:',
 'yourrealname' => 'Vaše pravo ime:',
 'yourlanguage' => 'Jezik:',
@@ -2152,9 +2155,9 @@ Vidi također [[Special:WantedCategories|zatražene kategorije]].',
 'linksearch-pat' => 'Šema pretrage:',
 'linksearch-ns' => 'Imenski prostor:',
 'linksearch-ok' => 'Traži',
-'linksearch-text' => 'Mogu se koristiti džokeri poput "*.wikipedia.org".<br />
-Potreban je najviši domen, na primjer "*.org".<br />
-Podržani protokoli: <tt>$1</tt> (zadaje http:// ako ne navedete protokol).',
+'linksearch-text' => 'Možete koristiti džoker znakove poput "*.wikipedia.org".
+Potrebno je navesti osnovnu domenu (TLD), npr. "*.org".<br />
+Podržani {{PLURAL:$2|protokol|protokoli}}: <code>$1</code> (default je http:// ako nijedan protokol nije naveden).',
 'linksearch-line' => '$1 je povezan od $2',
 'linksearch-error' => 'Džokeri se mogu pojavljivati samo na početku naziva servera.',
 
@@ -2167,7 +2170,7 @@ Podržani protokoli: <tt>$1</tt> (zadaje http:// ako ne navedete protokol).',
 # Special:ActiveUsers
 'activeusers' => 'Spisak aktivnih korisnika',
 '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|nedavna $1 izmjena|nedavne $1 izmjene|nedavnih $1 izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 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',
@@ -2230,7 +2233,7 @@ E-mail koju ste uneli u vašim [[Special:Preferences|postavkama]] će se prikaza
 'usermessage-editor' => 'Sistem za poruke',
 
 # Watchlist
-'watchlist' => 'Moj spisak praćenja',
+'watchlist' => 'Spisak praćenja',
 'mywatchlist' => 'Spisak praćenja',
 'watchlistfor2' => 'Za $1 $2',
 'nowatchlist' => 'Nemate ništa na svom spisku praćenih članaka.',
@@ -2238,8 +2241,8 @@ E-mail koju ste uneli u vašim [[Special:Preferences|postavkama]] će se prikaza
 'watchnologin' => 'Niste prijavljeni',
 'watchnologintext' => 'Morate biti [[Special:UserLogin|prijavljeni]] da bi ste mijenjali spisak praćenih članaka.',
 'addwatch' => 'Dodaj u popis praćenja',
-'addedwatchtext' => "Stranica \"[[:\$1]]\" je dodana [[Special:Watchlist|vašoj listi praćenih stranica]].
-Buduće promjene ove stranice i njoj pridružene stranice za razgovor će biti navedene ovdje, te će stranica izgledati '''podebljana''' u [[Special:RecentChanges|listi nedavnih]] izmjena kako bi se lakše uočila.",
+'addedwatchtext' => 'Stranica "[[:$1]]" je dodata vašem [[Special:Watchlist|spisku praćenih članaka]]. 
+Buduće promjene ove stranice i njoj pridružene stranice za razgovor će biti navedene ovde.',
 'removewatch' => 'Ukloni sa spiska praćenja',
 'removedwatchtext' => 'Stranica "[[:$1]]" je uklonjena s [[Special:Watchlist|vaše liste praćenja]].',
 'watch' => 'Prati',
@@ -2273,7 +2276,7 @@ Buduće promjene ove stranice i njoj pridružene stranice za razgovor će biti n
 'enotif_subject_moved' => '{{SITENAME}} stranicu $1 {{gender:|je premijestio|je premjestila|je premjestio}} $2',
 'enotif_subject_restored' => '{{SITENAME}} stranicu $1 {{gender:|je obnovio|je obnovila|je obnovio}} $2',
 'enotif_subject_changed' => '{{SITENAME}} stranicu $1 {{gender:|je promijenio|je promijenila|je promijenio}} $2',
-'enotif_body_intro_deleted' => '{{SITENAME}} stranica $1 je izbrisana na $PAGEEDITDATE od {{GENDER:|korisnika|korisnice|korisnika}} $2, v. $3 za trenutnu verziju.',
+'enotif_body_intro_deleted' => 'Stranicu $1 projekta {{SITENAME}} {{GENDER:$2|obrisao|obrisala}} je dana $PAGEEDITDATE {{GENDER:$2|korisnik|korisnica}} $2, pogledajte $3.',
 'enotif_body_intro_created' => '{{SITENAME}} stranica $1 je stvorena na $PAGEEDITDATE od {{GENDER:|korisnika|korisnice|korisnika}} $2, v. $3 za trenutnu verziju.',
 'enotif_body_intro_moved' => '{{SITENAME}} stranica $1 je premještena na $PAGEEDITDATE od {{GENDER:|korisnika|korisnice|korisnika}} $2, v. $3 za trenutnu verziju.',
 'enotif_body_intro_restored' => '{{SITENAME}} stranica $1 je obnovljena na $PAGEEDITDATE od {{GENDER:|korisnika|korisnice|korisnika}} $2, v. $3 za trenutnu verziju.',
@@ -2380,6 +2383,8 @@ Pogledajte [[Special:ProtectedPages|spisak zaštićenih stranica]] za pregled tr
 'prot_1movedto2' => '[[$1]] premješten na [[$2]]',
 'protect-badnamespace-title' => 'Nezaštitljiv imenski prostor',
 'protect-badnamespace-text' => 'Stranice u ovom imenskom prostoru se ne mogu zaštititi.',
+'protect-norestrictiontypes-text' => 'Ova stranica se ne može zaštititi jer nema dostupnih oblika ograničenja.',
+'protect-norestrictiontypes-title' => 'Stranica koju nije moguće zaštititi',
 'protect-legend' => 'Potvrdite zaštitu',
 'protectcomment' => 'Razlog:',
 'protectexpiry' => 'Ističe:',
@@ -2396,9 +2401,9 @@ Slijede trenutne postavke stranice '''$1''':",
 'protect-cascadeon' => 'Ova stranica je trenutno zaštićena jer je uključena u {{PLURAL:$1|stranicu, koja ima|stranice, koje imaju|stranice, koje imaju}} uključenu prenosnu (kaskadnu) zaštitu.
 Možete promijeniti stepen zaštite ove stranice, ali to neće uticati na prenosnu zaštitu.',
 'protect-default' => 'Dozvoli svim korisnicima',
-'protect-fallback' => 'Potrebno je imati "$1" ovlasti',
-'protect-level-autoconfirmed' => 'Blokiraj nove i neregistrovane korisnike',
-'protect-level-sysop' => 'Samo administratori',
+'protect-fallback' => 'Dopušteno samo korisnicima s dozvolom "$1"',
+'protect-level-autoconfirmed' => 'Dopušteno samo automatski potvrđenim korisnicima',
+'protect-level-sysop' => 'Dopušteno samo administratorima',
 'protect-summary-cascade' => 'prenosna (kaskadna) zaštita',
 'protect-expiring' => 'ističe $1 (UTC)',
 'protect-expiring-local' => 'ističe $1',
@@ -2702,18 +2707,18 @@ Ako želite otključati ili zaključati bazu, ova datoteka mora biti omogućena
 # Move page
 'move-page' => 'Preusmjeravanje $1',
 'move-page-legend' => 'Premjestite stranicu',
-'movepagetext' => "Korištenjem donjeg formulara možete preimenovati stranicu, preusmjerivši njenu historiju na novi naziv.
-Stari naslov će postati stranica za preusmjerenje na novi naslov.
-Možete updateirati preusmjerenja koja idu na originalni naslov automatski.
-Ako to ne učinite, budite sigurni da ste provjerili [[Special:DoubleRedirects|dupla]] ili [[Special:BrokenRedirects|mrtva preusmjerenja]].
-Odgovorni ste za to da poveznice nastave povezivati stranice kojima su namijenjene.
-
-Uzmite u obzir da stranica '''neće''' biti preusmjerena ako već postoji stranica s novim naslovom, osim ako je prazna ili ako je preusmjerenje bez prethodne historije uređivanja.
-To znači da stranicu možete ponovno preimenovati u stari naslov ako je u pitanju bila pogreška, te da ne možete presnimiti već postojeću stranicu.
-
-'''UPOZORENJE!'''
-Ovo može biti drastična i neočekivana promjena za popularnu stranicu;
-budite sigurni da ste shvatili sve posljedice prije nego što nastavite.",
+'movepagetext' => "Korištenjem ovog formulara možete preimenovati stranicu, premještajući cijelu historiju na novo ime.
+Članak pod starim imenom će postati stranica koja preusmjerava na članak pod novim imenom. 
+Možete automatski izmjeniti preusmjerenje do izvornog naslova.
+Ako se ne odlučite na to, provjerite [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|neispravna preusmjeravanja]].
+Dužni ste provjeriti da svi linkovi i dalje nastave voditi na prave stranice.
+
+Imajte na umu da članak '''neće''' biti preusmjeren ukoliko već postoji članak pod imenom na koje namjeravate da preusmjerite osim u slučaju stranice za preusmjeravanje koja nema nikakvih starih izmjena.
+To znači da možete vratiti stranicu na prethodno mjesto ako pogriješite, ali ne možete zamijeniti postojeću stranicu.
+
+'''Pažnja!'''
+Ovo može biti drastična i neočekivana promjena kad su u pitanju popularne stranice;
+Molimo dobro razmislite prije nego što preimenujete stranicu.",
 'movepagetext-noredirectfixer' => "Koristeći obrazac ispod ćete preimenovati stranicu i premjestiti cijelu njenu historiju na novi naziv.
 Stari naziv će postati preusmjerenje na novi naziv.
 Molimo provjerite da li postoje [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|nedovršena preusmjerenja]].
@@ -2893,6 +2898,7 @@ Molimo pokušajte ponovno.',
 'import-error-interwiki' => 'Ne mogu da uvezem stranicu „$1“ jer je njen naziv rezervisan za spoljno povezivanje (interwiki).',
 'import-error-special' => 'Ne mogu da uvezem stranicu „$1“ jer ona pripada posebnom imenskom prostoru koje ne prihvata stranice.',
 'import-error-invalid' => 'Ne mogu da uvezem stranicu „$1“ jer je njen naziv neispravan.',
+'import-error-unserialize' => 'Verzija $2 stranice "$1" ne može biti pročitana/uvezena. Zapisano je da verzija koristi $3 tip sadržaja u $4 formatu.',
 'import-options-wrong' => '{{PLURAL:$2|Pogrešna opcija|Pogrešne opcije}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Navedena osnovna stranica ima neispravan naslov.',
 'import-rootpage-nosubpage' => 'Imenski prostor „$1“ osnovne stranice ne dozvoljava podstranice.',
@@ -3029,6 +3035,7 @@ Ovo je vjerovatno izazvano vezom ka vanjskoj nepoželjnoj stranici.',
 'pageinfo-robot-noindex' => 'Ne može se indeksirati',
 'pageinfo-views' => 'Broj pregleda',
 'pageinfo-watchers' => 'Broj pratitelja stranice',
+'pageinfo-few-watchers' => 'Manje od $1 {{PLURAL:$1|pratioca|pratilaca}}',
 'pageinfo-redirects-name' => 'Preusmjeravanja na ovu stranicu',
 'pageinfo-subpages-name' => 'Podstranice ove stranice',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|preusmjerenje|preusmjerenja|preusmjerenja}}; $3 {{PLURAL:$3|nepreusmjerenje|nepreusmjerenja|nepreusmjerenja}})',
@@ -3043,6 +3050,7 @@ Ovo je vjerovatno izazvano vezom ka vanjskoj nepoželjnoj stranici.',
 'pageinfo-magic-words' => '{{PLURAL:$1|Magična riječ|Magične riječi}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Sakrivena kategorija|Sakrivene kategorije}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Uključeni šablon|Uključeni šabloni}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Stranica|Stranice}} uključene u ($1)',
 'pageinfo-toolboxlink' => 'Informacije o stranici',
 'pageinfo-redirectsto' => 'Preusmjerava na',
 'pageinfo-redirectsto-info' => 'Informacije',
@@ -3051,6 +3059,10 @@ Ovo je vjerovatno izazvano vezom ka vanjskoj nepoželjnoj stranici.',
 'pageinfo-protect-cascading' => 'Prenosiva zaštita stranica važi odavde',
 'pageinfo-protect-cascading-yes' => 'Da',
 'pageinfo-protect-cascading-from' => 'Stranice sa prenosivom zaštitom od',
+'pageinfo-category-info' => 'Informacije o kategoriji',
+'pageinfo-category-pages' => 'Broj stranica',
+'pageinfo-category-subcats' => 'Broj potkategorija',
+'pageinfo-category-files' => 'Broj datoteka',
 
 # Patrolling
 'markaspatrolleddiff' => 'Označi kao patrolirano',
@@ -3127,6 +3139,8 @@ Njegovim izvršavanjem možete da ugrozite Vaš sistem.",
 'minutes' => '{{PLURAL:$1|$1 minut|$1 minuta|$1 minuta}}',
 'hours' => '{{PLURAL:$1|$1 sat|$1 sata|$1 sati}}',
 'days' => '{{PLURAL:$1|$1 dan|$1 dana|$1 dana}}',
+'months' => '{{PLURAL:$1|$1 mjesec|$1 mjeseci}}',
+'years' => '{{PLURAL:$1|$1 godina|$1 godine|$1 godina}}',
 'ago' => 'prije $1',
 'just-now' => 'upravo sada',
 
@@ -3787,7 +3801,7 @@ Slike su prikazane u punoj veličini, ostale vrste datoteka su prikazane direktn
 'specialpages-group-highuse' => 'Često korištene stranice',
 'specialpages-group-pages' => 'Spiskovi stranica',
 'specialpages-group-pagetools' => 'Alati za stranice',
-'specialpages-group-wiki' => 'Wiki podaci i alati',
+'specialpages-group-wiki' => 'Podaci i alati',
 'specialpages-group-redirects' => 'Preusmjeravanje posebnih stranica',
 'specialpages-group-spam' => 'Spam alati',
 
@@ -3884,8 +3898,8 @@ Slike su prikazane u punoj veličini, ostale vrste datoteka su prikazane direktn
 'logentry-newusers-newusers' => 'Korisnički račun $1 je napravljen',
 'logentry-newusers-create' => 'Korisnički račun $1 je napravljen',
 'logentry-newusers-create2' => 'Korisnički račun $3 {{GENDER:|je napravio|je napravila|je napravio}} $1',
+'logentry-newusers-byemail' => 'Korisnički račun $3 je napravio $1 i lozinka/šifra je poslana putem e-maila',
 'logentry-newusers-autocreate' => 'Račun $1 je samostalno otvoren',
-'newuserlog-byemail' => 'lozinka je poslana putem e-maila',
 'logentry-rights-rights' => '$1 {{GENDER:$1|je promijenio|je promijenila|je promijenio}} članstvo grupe za $3 iz $4 u $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|je promenio|je promenila|je promenio}} članstvo grupe za $3',
 'logentry-rights-autopromote' => '$1 je automatski {{GENDER:$1|unaprijeđen|unaprijeđena|unaprijeđen}} iz $4 u $5',
@@ -3943,6 +3957,7 @@ U suprotnom, poslužite se jednostavnim obrascem ispod. Vaš komentar će stajat
 'api-error-ok-but-empty' => 'Unutrašnja greška: nema odgovora od servera.',
 'api-error-overwrite' => 'Pisanje preko postojeće datoteke nije dopušteno.',
 'api-error-stashfailed' => 'Unutrašnja greška: server nije mogao da spremi privremenu datoteku.',
+'api-error-publishfailed' => 'Unutrašnja greška: server nije mogao da spremi privremenu datoteku.',
 'api-error-timeout' => 'Server nije odgovorio unutar očekivanog vremena.',
 'api-error-unclassified' => 'Desila se nepoznata greška',
 'api-error-unknown-code' => 'Nepoznata greška: "$1"',
index a7909c3..0dbb6f3 100644 (file)
@@ -3944,7 +3944,6 @@ MediaWiki බෙදාහැර ඇත්තේ එය ප්‍රයෝජන
 'logentry-newusers-create' => '$1 පරිශීලක ගිණුමක් තනන ලදී',
 'logentry-newusers-create2' => '$1 විසින් $3 පරිශීලක ගිණුම තනන ලදී',
 'logentry-newusers-autocreate' => '$1 ගිණුම ස්වංක්‍රීයව නිර්මිතය',
-'newuserlog-byemail' => 'විද්‍යුත්-තැපෑලෙන් මුර-පදය යවන ලදි',
 'rightsnone' => '(කිසිවක් නොමැත)',
 
 # Feedback
index c07e914..34d3fbe 100644 (file)
@@ -2173,7 +2173,7 @@ Môžete zúžiť rozsah, ak zvolíte typ záznamu, používateľské meno alebo
 'allpagesprev' => 'Predchádzajúci',
 'allpagesnext' => 'Ďalší',
 'allpagessubmit' => 'Vykonať',
-'allpagesprefix' => 'Zobraziť stránky s predponou:',
+'allpagesprefix' => 'Zobraziť stránky začínajúce na:',
 'allpagesbadtitle' => 'Zadaný názov stránky je neplatný alebo mal medzijazykový alebo interwiki prefix. Môže obsahovať jeden alebo viac znakov, ktoré nie je možné použiť v názve stránky.',
 'allpages-bad-ns' => '{{SITENAME}} nemá menný priestor „$1“.',
 'allpages-hide-redirects' => 'Skryť presmerovania',
@@ -3959,7 +3959,6 @@ Obrázky sa zobrazia v plnom rozlíšení, ostatné typy súborov sa spustia v p
 'logentry-newusers-create' => 'Bol vytvorený používateľský účet $1',
 'logentry-newusers-create2' => '$1 vytvoril používateľský účet $3',
 'logentry-newusers-autocreate' => 'Automaticky bol založený účet $1',
-'newuserlog-byemail' => 'heslo poslané emailom',
 'logentry-rights-rights' => '$1 {{GENDER:$2|zmenil|zmenila}} členstvo $3 v skupinách z $4 na $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$2|zmenil|zmenila}} členstvo $3 v skupinách',
 'logentry-rights-autopromote' => '$1 {{GENDER:$2|bol automaticky povýšený|bola automaticky povýšená}} z $4 na $5',
index 198db24..bd709c6 100644 (file)
@@ -624,7 +624,7 @@ Ne pozabite si prilagoditi vaših [[Special:Preferences|nastavitev {{GRAMMAR:rod
 'gotaccount' => 'Račun že imate? $1.',
 'gotaccountlink' => 'Prijavite se',
 'userlogin-resetlink' => 'Ste pozabili svoje prijavne podatke?',
-'createaccountmail' => 'Po e-pošti',
+'createaccountmail' => 'Ustvari začasno naključno geslo in ga pošlji na spodaj navedeni e-poštni naslov',
 'createaccountreason' => 'Razlog:',
 'badretype' => 'Gesli, ki ste ju vnesli, se ne ujemata.',
 'userexists' => 'Uporabniško ime, ki ste ga vnesli, je že zasedeno.
@@ -1241,7 +1241,7 @@ Podrobnosti lahko najdete v [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'search-interwiki-default' => '$1 zadetkov:',
 'search-interwiki-more' => '(več)',
 'search-relatedarticle' => 'Podobno',
-'mwsuggest-disable' => 'Onemogoči predloge Ajax',
+'mwsuggest-disable' => 'Onemogoči iskalne predloge',
 'searcheverything-enable' => 'Iskanje po vseh imenskih prostorih',
 'searchrelated' => 'povezano',
 'searchall' => 'vse',
@@ -1553,7 +1553,7 @@ Ko vas drugi uporabniki kontaktirajo, jim vašega e-poštnega naslova ne bomo ra
 'nchanges' => '$1 {{PLURAL:$1|sprememba|spremembi|spremembe|sprememb|sprememb}}',
 'recentchanges' => 'Zadnje spremembe',
 'recentchanges-legend' => 'Možnosti zadnjih sprememb',
-'recentchanges-summary' => 'Na tej strani lahko spremljajte najnedavnejše spremembe wikija.',
+'recentchanges-summary' => 'Na tej strani lahko spremljate najnovejše spremembe wikija.',
 'recentchanges-feed-description' => 'Spremljajte zadnje spremembe wikija prek tega vira.',
 'recentchanges-label-newpage' => 'S tem urejanjem je bila ustvarjena nova stran',
 'recentchanges-label-minor' => 'Manjše urejanje',
@@ -2163,7 +2163,7 @@ Zahtevana je vsaj najvišja domena, na primer »*.org«.<br />
 # Special:ActiveUsers
 'activeusers' => 'Seznam aktivnih uporabnikov',
 'activeusers-intro' => 'Seznam uporabnikov, ki so bili kakor koli aktivni v {{PLURAL:$1|zadnjem $1 dnevu|zadnjih $1 dneh}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|urejanje|urejanji|urejanja|urejanj}} v {{PLURAL:$3|preteklem dnevu|preteklih $3 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',
@@ -3023,6 +3023,7 @@ Omogoča vnos pojasnila v povzetku urejanja.',
 'pageinfo-robot-noindex' => 'Ni na voljo za indeksiranje',
 'pageinfo-views' => 'Število ogledov',
 'pageinfo-watchers' => 'Število spremljevalcev strani',
+'pageinfo-few-watchers' => 'Manj kot $1 {{PLURAL:$1|spremljevalec|spremljevalca|spremljevalci|spremljevalcev}}',
 'pageinfo-redirects-name' => 'Preusmeritve na stran',
 'pageinfo-subpages-name' => 'Podstrani strani',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|preusmeritev|preusmeritvi|preusmeritve|preusmeritev}}; $3 {{PLURAL:$3|nepreusmeritev|nepreusmeritvi|nepreusmeritve|nepreusmeritev}})',
@@ -3799,7 +3800,7 @@ Vnesite ime datoteke brez predpone »{{ns:file}}:«.',
 'specialpages-group-highuse' => 'Strani visoke uporabe',
 'specialpages-group-pages' => 'Seznam strani',
 'specialpages-group-pagetools' => 'Orodja strani',
-'specialpages-group-wiki' => 'Podatki in orodja wiki',
+'specialpages-group-wiki' => 'Podatki in orodja',
 'specialpages-group-redirects' => 'Preusmerjajoče posebne strani',
 'specialpages-group-spam' => 'Orodja za spam',
 
@@ -3897,8 +3898,8 @@ Ta stran se sooča s tehničnimi težavami.',
 'logentry-newusers-newusers' => '$1 je ustvaril(-a) uporabniški račun',
 'logentry-newusers-create' => '$1 je ustvaril(-a) uporabniški račun',
 'logentry-newusers-create2' => '$1 je ustvaril(-a) uporabniški račun $3',
+'logentry-newusers-byemail' => '$1 je {{GENDER:$2|ustvaril|ustvarila|ustvaril(-a)}} uporabniški račun $3; geslo je bilo poslano po e-pošti',
 'logentry-newusers-autocreate' => 'Račun $1 je bil samodejno ustvarjen',
-'newuserlog-byemail' => 'geslo je bilo poslano po e-pošti',
 'logentry-rights-rights' => '$1 je spremenil(-a) članstvo skupine $3 z $4 na $5',
 'logentry-rights-rights-legacy' => '$1 je spremenil(-a) članstvo skupine $3',
 'logentry-rights-autopromote' => '$1 je bil(-a) samodejno povišan(-a) z $4 na $5',
@@ -3956,6 +3957,7 @@ V nasprotnem primeru lahko uporabite preprost obrazec spodaj. Vašo pripombo bom
 'api-error-ok-but-empty' => 'Notranja napaka: strežnik se ne odziva.',
 'api-error-overwrite' => 'Prepisovanje obstoječe datoteke ni dovoljeno.',
 'api-error-stashfailed' => 'Notranja napaka: strežnik ni uspel shraniti začasne datoteke.',
+'api-error-publishfailed' => 'Notranja napaka: strežnik ni uspel objaviti začasne datoteke.',
 'api-error-timeout' => 'Strežnik se ni odzval v pričakovanem času.',
 'api-error-unclassified' => 'Prišlo je do neznane napake',
 'api-error-unknown-code' => 'Neznana napaka: »$1«',
index 274ddd3..08d25e2 100644 (file)
@@ -2362,6 +2362,5 @@ De Eengabe muuß ohne dann Zusatz „{{ns:file}}:“ erfolga.',
 # New logging system
 'revdelete-restricted' => 'Einschränkungen gelten au fier Administratorn',
 'revdelete-unrestricted' => 'Einschränkungen fier Administratorn uffgehobn',
-'newuserlog-byemail' => 'doas Passwurt wourde per E-Mail versandt',
 
 );
index d69ce96..d93c164 100644 (file)
@@ -757,6 +757,7 @@ sababteeda neh waxaa laga heli kartaa  [{{fullurl:{{#Special:Log}}/delete|page={
 'search-redirect' => '(waxaa loo toosiyay $1)',
 'search-section' => '(maqaalka $1)',
 'search-suggest' => 'Ma waxaad ulajeeday: $1',
+'search-interwiki-caption' => 'Mashaariicda walaalaha',
 'search-interwiki-default' => '$1 natiijooyinka:',
 'search-interwiki-more' => '(wax kale)',
 'search-relatedarticle' => 'La xiriiro',
@@ -828,10 +829,12 @@ E-mailkaada mala sheegaayo markii ee dadka kale kula soo xiriirayaan.',
 # User rights
 'saveusergroups' => 'Kaydi kooxaha isticmaalayaasha',
 'userrights-groupsmember' => 'Ka mid ah:',
+'userrights-reason' => 'Sababta:',
 
 # Groups
 'group' => 'Koox:',
 'group-user' => 'Isticmaalada',
+'group-autoconfirmed' => 'Gude galayaasha la hubiyey si iskeed ah',
 'group-bot' => 'botyada',
 'group-sysop' => 'Maamulada',
 'group-all' => '(dhamaan)',
@@ -841,6 +844,7 @@ E-mailkaada mala sheegaayo markii ee dadka kale kula soo xiriirayaan.',
 'group-sysop-member' => '{{GENDER:$1|maamulaha}}',
 
 'grouppage-user' => '{{ns:project}}:Isticmaalada',
+'grouppage-autoconfirmed' => '{{ns:project}}:Gude gale la hubiyey si iskeeda ah',
 'grouppage-sysop' => '{{ns:project}}:Maamulada',
 
 # Rights
@@ -971,6 +975,7 @@ ku saabsan: $1',
 'filehist-thumb' => 'Sawir yar',
 'filehist-thumbtext' => 'Sawirka yar nuuciisa ahaa $1',
 'filehist-user' => 'Isticmaale',
+'filehist-dimensions' => 'Cabirka',
 'filehist-comment' => 'Ka hadalka',
 'imagelinks' => 'Faylka lagu isticmaalay',
 'linkstoimage' => 'Boggagaan soo socota ee  {{PLURAL:$1|ah waxey la xiriiraan|$1 ah waxey la xiriiraan}} faylkan:',
@@ -1108,7 +1113,9 @@ Hadii aad rabootid in aad boggan ka saartid wardiyeynta, dhagsii \"Ha' wardiyeyn
 'watching' => 'Daawasho...',
 
 'enotif_subject_created' => '{{SITENAME}} Bogga $1 Qof ayaa sameeyey {{gender:$2|$2}}',
+'enotif_subject_changed' => '{{SITENAME}} Bogga $1 Waxaa {{GENDER:$2|Bedel}} ku sameeyey qof $2',
 'enotif_body_intro_created' => 'Bogga {{SITENAME}} ga $1 waxaa la sameeyey $PAGEEDITDATE qof {{gender:$2|$2}}, eeg $3 sida laga dhigay hadda.',
+'enotif_body_intro_restored' => 'Booga {{SITENAME}} $1 waa labadelay {{GENDER:$2|dib u habayn}} waqtigaan $PAGEEDITDATE waxaana badalay $2, eeg $3 sida hadda laga dhigay.',
 'enotif_body_intro_changed' => 'Bogga {{SITENAME}} ga $1 waxaa la badelay $PAGEEDITDATE qof {{gender:$2|$2}}, eeg $3 sida laga dhigay hadda.',
 'enotif_lastvisited' => 'Eeg $1 Dhamaan isbedeleda ilaa goortii kuugu dambaysay.',
 'enotif_lastdiff' => 'Eeg $1 si aad u aragto bedelkaan.',
index 7ddf3e2..6e0886f 100644 (file)
@@ -3777,7 +3777,6 @@ Kjo faqe është duke përjetuar vështirësi teknike.',
 'logentry-newusers-create' => '$1 krijoi një llogari',
 'logentry-newusers-create2' => '$1 krijoi një llogari $3',
 'logentry-newusers-autocreate' => 'Llogaria $1 u krijua automatikisht',
-'newuserlog-byemail' => 'fjalëkalimi u dërgua në postën elektronike',
 'rightsnone' => '(asgjë)',
 
 # Feedback
index cc8cbc7..4eab336 100644 (file)
@@ -1004,8 +1004,8 @@ $2
 'minoredit' => 'мања измена',
 'watchthis' => 'надгледај ову страницу',
 'savearticle' => 'Сачувај страницу',
-'preview' => 'Преглед',
-'showpreview' => 'Ð\9fÑ\80егледаÑ\98',
+'preview' => 'Претпреглед',
+'showpreview' => 'Ð\9fÑ\80икажи Ð¿Ñ\80еÑ\82пÑ\80еглед',
 'showlivepreview' => 'Тренутни преглед',
 'showdiff' => 'Прикажи измене',
 'anoneditwarning' => "'''Упозорење:''' нисте пријављени.
@@ -4002,7 +4002,7 @@ $5
 
 # Delete conflict
 'deletedwhileediting' => "'''Упозорење''': ова страница је обрисана након што сте почели с уређивањем!",
-'confirmrecreate' => "[[User:$1|$1]] ([[User talk:$1|разговор]]) {{GENDER:$1|је обрисао|је обрисала|је обрисао}} ову страницу након што сте почели да је уређујете из следећег разлога:
+'confirmrecreate' => "[[User:$1|$1]] ([[User talk:$1|разговор]]) {{GENDER:$1|је обрисао|је обрисала|обриса}} ову страницу након што сте почели да је уређујете из следећег разлога:
 : ''$2''
 Потврдите да стварно желите да направите страницу.",
 'confirmrecreate-noreason' => 'Корисник [[User:$1|$1]] ([[User talk:$1|разговор]]) је обрисао ову страницу након што сте почели да га уређујете. Потврдите да стварно желите да поново направите ову страницу.',
@@ -4333,7 +4333,6 @@ $5
 'logentry-newusers-create' => '$1 {{GENDER:|је отворио|је отворила|је отворио}} кориснички налог',
 'logentry-newusers-create2' => '$1 {{GENDER:|је отворио|је отворила|је отворио}} кориснички налог $3',
 'logentry-newusers-autocreate' => 'Налог $1 је самостално отворен',
-'newuserlog-byemail' => 'лозинка је послата е-поштом',
 'logentry-rights-rights' => '$1 {{GENDER:$1|је променио|је променила|је променио}} чланство групе за $3 из $4 у $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|је променио|је променила|је променио}} чланство групе за $3',
 'logentry-rights-autopromote' => '$1 је аутоматски {{GENDER:$1|унапређен|унапређена|унапређен}} из $4 у $5',
index b96a139..c516bf8 100644 (file)
@@ -4227,7 +4227,6 @@ Slike su prikazane u punoj veličini, a druge vrste datoteka se pokreću pomoću
 'logentry-newusers-create' => '$1 {{GENDER:|je otvorio|je otvorila|je otvorio}} korisnički nalog',
 'logentry-newusers-create2' => '$1 {{GENDER:|je otvorio|je otvorila|je otvorio}} korisnički nalog $3',
 'logentry-newusers-autocreate' => 'Nalog $1 je samostalno otvoren',
-'newuserlog-byemail' => 'lozinka je poslata e-poštom',
 'logentry-rights-rights' => '$1 {{GENDER:$1|je promenio|je promenila|je promenio}} članstvo grupe za $3 iz $4 u $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|je promenio|je promenila|je promenio}} članstvo grupe za $3',
 'logentry-rights-autopromote' => '$1 je automatski {{GENDER:$1|unapređen|unapređena|unapređen}} iz $4 u $5',
index e420ab3..f2bd238 100644 (file)
@@ -3286,7 +3286,6 @@ Ne [{{SERVER}}{{SCRIPTPATH}}/COPYING Kopie fon ju ''GNU General Public License''
 # New logging system
 'revdelete-restricted' => 'Einskränkengen jäilde uk foar Administratore',
 'revdelete-unrestricted' => 'Ienskränkengen foar Administratore wächhoald',
-'newuserlog-byemail' => 'dät Paaswoud wuud uur E-Mail fersoand',
 'rightsnone' => '(-)',
 
 # Search suggestions
index e3a6f93..4e41157 100644 (file)
@@ -3042,7 +3042,6 @@ Coba ku sawangan normal.',
 # New logging system
 'revdelete-restricted' => 'akses geus dibatesan ukur keur kuncén',
 'revdelete-unrestricted' => 'Watesan akses kuncén dihapuskeun',
-'newuserlog-byemail' => 'Sandi geus dikirim maké surélék.',
 'rightsnone' => '(euweuh)',
 
 # Feedback
index a63af45..60a5d8d 100644 (file)
@@ -454,6 +454,7 @@ $messages = array(
 'newwindow' => '(öppnas i ett nytt fönster)',
 'cancel' => 'Avbryt',
 'moredotdotdot' => 'Mer...',
+'morenotlisted' => 'Mer som inte är listad...',
 'mypage' => 'Min sida',
 'mytalk' => 'Diskussion',
 'anontalk' => 'Diskussionssida för denna IP-adress',
@@ -754,7 +755,7 @@ Glöm inte att justera dina [[Special:Preferences|{{SITENAME}}-inställningar]].
 'gotaccount' => "Har du redan ett användarkonto? '''$1'''.",
 'gotaccountlink' => 'Logga in',
 'userlogin-resetlink' => 'Har du glömt dina inloggningsuppgifter?',
-'createaccountmail' => 'med e-post',
+'createaccountmail' => 'Använd ett tillfällig slumpartat lösenord och skicka den till e-postadressen som anges nedan',
 'createaccountreason' => 'Orsak:',
 'badretype' => 'De lösenord du uppgett överensstämmer inte med varandra.',
 'userexists' => 'Det valda användarnamnet används redan.
@@ -1046,7 +1047,7 @@ Du lovar oss också att du skrev texten själv, eller kopierade från kulturellt
 'longpageerror' => "'''FEL: Texten som du försöker spara är {{PLURAL:$1|en kilobyte|$1 kilobyte}}, vilket är mer än det maximalt tillåtna {{PLURAL:$2|en kilobyte|$2 kilobyte}}.'''
 Den kan inte sparas.",
 'readonlywarning' => "'''VARNING: Databasen är tillfälligt låst för underhåll. Du kommer inte att kunna spara dina ändringar just nu.
-Det kan vara klokt att kopiera över texten till din egen dator, tills databasen är upplåst igen.'''
+Det kan vara klokt att kopiera texten till ett textdokument som sparas på din dator tills vidare.'''
 
 Administratören som låste databasen gav följande förklaring: $1",
 'protectedpagewarning' => "'''Varning: Den här sidan har låsts så att bara användare med administratörsrättigheter kan redigera den.'''
@@ -1354,7 +1355,7 @@ Detaljer kan hittas i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'search-interwiki-default' => 'Resultat i $1:',
 'search-interwiki-more' => '(mer)',
 'search-relatedarticle' => 'Relaterad',
-'mwsuggest-disable' => 'Avaktivera AJAX-förslag',
+'mwsuggest-disable' => 'Inaktivera sökförslag',
 'searcheverything-enable' => 'Sök i alla namnrymder',
 'searchrelated' => 'relaterad',
 'searchall' => 'alla',
@@ -1574,7 +1575,7 @@ Om du väljer att ange ditt riktiga namn, kommer det att användas för att till
 'right-bot' => 'Behandlas som en automatisk process',
 'right-nominornewtalk' => 'Mindre ändringar på diskussionssidor ger inte besked om nya meddelanden',
 'right-apihighlimits' => 'Använda högre gränser i API-frågor',
-'right-writeapi' => 'Använda skriv-API:t',
+'right-writeapi' => 'Använda skriv-API:et',
 'right-delete' => 'Radera sidor',
 'right-bigdelete' => 'Radera sidor med stor historik',
 'right-deletelogentry' => 'Radera och återställ specifika loggposter',
@@ -2260,7 +2261,7 @@ Det krävs åtminstone en toppdomän, t.ex. "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Lista över aktiva användare',
 '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|redigering|redigeringar}} {{PLURAL:$3|det senaste dygnet|de senaste $3 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' => 'Göm botar',
 'activeusers-hidesysops' => 'Dölj administratörer',
@@ -2788,7 +2789,7 @@ Du kan välja att automatiskt uppdatera omdirigeringar som leder till den gamla
 Om du väljer att inte göra det, kontrollera då att du inte skapar några [[Special:DoubleRedirects|dubbla]] eller [[Special:BrokenRedirects|trasiga omdirigeringar]].
 Du bör också se till att länkar fortsätter att peka dit de ska.
 
-Notera att sidan '''inte''' kan flyttas om det redan finns en sida under den nya sidtiteln, såvida inte den sidan är tom eller en omdirigering till den gamla titeln och saknar annan versionshistorik.
+Notera att sidan '''inte''' kan flyttas om det redan finns en sida under den nya sidtiteln, såvida inte den sidan är en omdirigering till den gamla titeln och saknar annan versionshistorik.
 Det innebär att du kan flytta tillbaks en sida om du råkar göra fel, och att du inte kan skriva över existerande sidor.
 
 '''VARNING!'''
@@ -3141,6 +3142,7 @@ Detta orsakades troligen av en länk till en svartlistad webbplats.',
 'pageinfo-robot-noindex' => 'Inte indexerbar',
 'pageinfo-views' => 'Antal visningar',
 'pageinfo-watchers' => 'Antal användare som bevakar sidan',
+'pageinfo-few-watchers' => 'Färre än $1 {{PLURAL:$1|bevakare}}',
 'pageinfo-redirects-name' => 'Omdirigeringar till denna sida',
 'pageinfo-subpages-name' => 'Undersidor till denna sida',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|omdirigering|omdirigeringar}}; $3 {{PLURAL:$3|icke-omdirigering|icke-omdirigeringar}})',
@@ -3917,7 +3919,7 @@ Bilder visas i full upplösning, andra filtyper öppnas direkt i de program som
 'specialpages-group-highuse' => 'Sidor som används mycket',
 'specialpages-group-pages' => 'Listor över sidor',
 'specialpages-group-pagetools' => 'Sidverktyg',
-'specialpages-group-wiki' => 'Information och verktyg för wikin',
+'specialpages-group-wiki' => 'Data och verktyg',
 'specialpages-group-redirects' => 'Omdirigerande specialsidor',
 'specialpages-group-spam' => 'Spamverktyg',
 
@@ -4014,8 +4016,8 @@ Bilder visas i full upplösning, andra filtyper öppnas direkt i de program som
 'logentry-newusers-newusers' => 'Användarkonto $1 skapades',
 'logentry-newusers-create' => 'Användarkonto $1 skapades',
 'logentry-newusers-create2' => 'Användarkonto $3 skapades av $1',
+'logentry-newusers-byemail' => 'Användarkontot $3 skapades av $1 och lösenordet skickades via e-post',
 'logentry-newusers-autocreate' => 'Kontot $1 skapades automatiskt',
-'newuserlog-byemail' => 'lösenord skickat med e-post',
 'logentry-rights-rights' => '$1 ändrade gruppmedlemskap för $3 från $4 till $5',
 'logentry-rights-rights-legacy' => '$1 ändrade gruppmedlemskap för $3',
 'logentry-rights-autopromote' => '$1 befordrades automatiskt från $4 till $5',
@@ -4073,6 +4075,7 @@ Annars kan du använda det enkla formuläret nedan. Din kommentar kommer att lä
 'api-error-ok-but-empty' => 'Internt fel: Inget svar från servern.',
 'api-error-overwrite' => 'Det är inte tillåtet att skriva över en befintlig fil.',
 'api-error-stashfailed' => 'Internt fel: servern kunde inte lagra temporär fil.',
+'api-error-publishfailed' => 'Internt fel: Servern kunde inte publicera temporär fil.',
 'api-error-timeout' => 'Servern svarade inte inom förväntad tid.',
 'api-error-unclassified' => 'Ett okänt fel uppstod',
 'api-error-unknown-code' => 'Okänt fel: "$1"',
index 46077e5..f2ead23 100644 (file)
@@ -1099,7 +1099,7 @@ Tazama [[Special:BlockList|IP block orodha ya uzuio wa IP]] kuona orodha ya zuio
 'search-interwiki-default' => 'Matokeo toka $1:',
 'search-interwiki-more' => '(zaidi)',
 'search-relatedarticle' => 'Zingine zinazofanana',
-'mwsuggest-disable' => 'Kutoonyesha mapendekezo ya AJAX',
+'mwsuggest-disable' => 'Kutoonyesha mapendekezo ya kutafuta',
 'searcheverything-enable' => 'Tafuta katika maeneo yote ya wiki',
 'searchrelated' => 'zingine zinazofanana',
 'searchall' => 'zote',
@@ -1981,7 +1981,7 @@ Anwani yako ya barua pepe ulioitaja katika [[Special:Preferences|mapendekezo yak
 'usermessage-editor' => 'Jumbe za mfumo',
 
 # Watchlist
-'watchlist' => 'Maangalizi yangu',
+'watchlist' => 'Maangalizi',
 'mywatchlist' => 'Maangalizi',
 'watchlistfor2' => 'Kwa ajili ya $1 $2',
 'nowatchlist' => 'Hamna vitu katika maangalizi yako.',
@@ -2200,7 +2200,7 @@ $1',
 'blanknamespace' => '(Kuu)',
 
 # Contributions
-'contributions' => 'Michango ya mtumiaji',
+'contributions' => 'Michango ya {{GENDER:$1|mtumiaji}}',
 'contributions-title' => 'Michango ya mtumiaji $1',
 'mycontris' => 'Michango',
 'contribsub2' => 'Kwa $1 ($2)',
@@ -2243,7 +2243,7 @@ Rejea kumbukumbu ya uzuio ya mwisho inayoandikwa chini:',
 'whatlinkshere-hideredirs' => '$1 maelekezo',
 'whatlinkshere-hidetrans' => '$1 majumuisho',
 'whatlinkshere-hidelinks' => '$1 viungo',
-'whatlinkshere-hideimages' => '$1 viungo vya picha',
+'whatlinkshere-hideimages' => 'viungo $1 vya faili',
 'whatlinkshere-filters' => 'Machujio',
 
 # Block/unblock
@@ -3158,7 +3158,6 @@ Tovuti hii inapata matatatizo wakati huu.',
 'logentry-newusers-create' => '$1 alianzisha akaunti ya mtumiaji',
 'logentry-newusers-create2' => '$1 alianzisha akaunti ya mtumiaji $3',
 'logentry-newusers-autocreate' => 'Akaunti ya mtumiaji $1 ilianzishwa na mashine',
-'newuserlog-byemail' => 'neno la siri limetumwa kwa barua pepe',
 'rightsnone' => '(hana)',
 
 # Feedback
index 39c5d9b..4cbd8eb 100644 (file)
@@ -2842,7 +2842,6 @@ Naškryflej sam mjano plika bez prefiksu „{{ns:file}}:”.',
 # New logging system
 'revdelete-restricted' => 'naštaluj uograničyńo do administratorůw',
 'revdelete-unrestricted' => 'wycofej uograničyńo do administratorůw',
-'newuserlog-byemail' => 'hasło uostało wysłane e-brifym',
 'rightsnone' => 'podstawowo',
 
 );
index fd63bb0..dbd54c4 100644 (file)
@@ -237,7 +237,7 @@ $messages = array(
 'vector-action-protect' => 'காக்கவும்',
 'vector-action-undelete' => 'நீக்கத்தை நிறுத்து',
 'vector-action-unprotect' => 'காப்பை மாற்று',
-'vector-simplesearch-preference' => 'à®®à¯\87à®®à¯\8dபà®\9fà¯\8dà®\9f à®¤à¯\87à®\9fà¯\81தலà¯\8d à®®à¯\81à®\9fிவà¯\81à®\95ளà¯\88à®\9aà¯\8d செயல்படுத்தவும் (Vector தோல் மட்டும்)',
+'vector-simplesearch-preference' => 'à®\9aாதாரண à®¤à¯\87à®\9fà¯\81தலà¯\8d à®ªà®\9fà¯\8dà®\9fà¯\88யதà¯\8dதà¯\88 செயல்படுத்தவும் (Vector தோல் மட்டும்)',
 'vector-view-create' => 'உருவாக்கவும்',
 'vector-view-edit' => 'தொகு',
 'vector-view-history' => 'வரலாற்றைக் காட்டவும்',
@@ -2130,6 +2130,7 @@ $NEWPAGE
 'prot_1movedto2' => '[[$1]], [[$2]] என்றத் தலைப்புக்கு நகர்த்தப்பட்டுள்ளது.',
 'protect-badnamespace-title' => 'பாதுகாக்க முடியாத பெயரிடைவெளி',
 'protect-badnamespace-text' => 'இந்த பெயரிடைவெளியில் உள்ள  பக்கங்கள் பாதுகாக்கப்படாது.',
+'protect-norestrictiontypes-title' => 'பாதுகாக்க முடியாத பக்கங்கள்',
 'protect-legend' => 'காப்பை உறுதிப்படுத்து',
 'protectcomment' => 'காரணம்:',
 'protectexpiry' => 'முடிவுறுகிறது:',
@@ -2745,10 +2746,14 @@ $1',
 'pageinfo-hidden-categories' => 'மறைக்கப்பட்ட {{PLURAL:$1|பகுப்பு|பகுப்புகள்}} ($1)',
 'pageinfo-templates' => 'பயன்படுத்தப்பட்ட {{PLURAL:$1|வார்ப்புரு|வார்ப்புருக்கள்}} ($1)',
 'pageinfo-toolboxlink' => 'பக்கத் தகவல்',
+'pageinfo-redirectsto' => 'வழிமாற்றவும்:',
 'pageinfo-redirectsto-info' => 'தகவல்',
 'pageinfo-contentpage' => 'உள்ளடக்கப் பக்கமாய்க் கணக்கிடப்பட்டது.',
 'pageinfo-contentpage-yes' => 'ஆம்',
 'pageinfo-protect-cascading-yes' => 'ஆம்',
+'pageinfo-category-info' => 'பகுப்புகளின் எண்ணிக்கை',
+'pageinfo-category-pages' => 'பக்கங்களின் எண்ணிக்கை',
+'pageinfo-category-files' => 'கோப்புகளின் எண்ணிக்கை',
 
 # Skin names
 'skinname-standard' => 'இயல்பான',
@@ -3557,7 +3562,6 @@ $5
 'logentry-newusers-create' => '$1 ஒரு புதிய பயனர் கணக்கை உருவாக்கியுள்ளார்.',
 'logentry-newusers-create2' => '$3 பயனர் கணக்கினை $1 உருவாக்கினார்',
 'logentry-newusers-autocreate' => 'கணக்கு  $1   தானாக    உருவாக்கப்பட்டது',
-'newuserlog-byemail' => 'மின்னஞ்சல் மூலம் கடவுச்சொல் அனுப்பப்பட்டுவிட்டது',
 'rightsnone' => '(எதுவுமில்லை)',
 
 # Feedback
index f1b9bba..5c28ebd 100644 (file)
@@ -1041,7 +1041,8 @@ $1",
 'revdelete-only-restricted' => '$2, $1 తేదీ గల అంశాన్ని దాచడంలో పొరపాటు: ఇతర దృశ్యత వికల్పాల్లోంచి ఒకదాన్ని ఎంచుకోకుండా అంశాలని నిర్వాహకులకు కనబడకుండా అణచివెయ్యలేరు.',
 'revdelete-reason-dropdown' => '*సాధారణ తొలగింపు కారణాలు
 ** కాపీహక్కుల ఉల్లంఘన
-** అసంబద్ధ వ్యక్తిగత సమాచారం
+** అసంబద్ధ వ్యాఖ్య లేదా వ్యక్తిగత సమాచారం
+** అసంబద్ధ వాడుకరి పేరు
 ** నిందాపూర్వక సమాచారం',
 'revdelete-otherreason' => 'ఇతర/అదనపు కారణం:',
 'revdelete-reasonotherlist' => 'ఇతర కారణం',
@@ -1229,7 +1230,7 @@ $1",
 'timezoneregion-indian' => 'హిందూ మహాసముద్రం',
 'timezoneregion-pacific' => 'పసిఫిక్ మహాసముద్రం',
 'allowemail' => 'ఇతర వాడుకరుల నుండి ఈ-మెయిళ్ళను రానివ్వు',
-'prefs-searchoptions' => 'à°\85à°¨à±\8dà°µà±\87à°·à°£ à°\8eà°\82పిà°\95à°²à±\81',
+'prefs-searchoptions' => 'à°µà±\86à°¤à±\81à°\95à±\81లాà°\9f',
 'prefs-namespaces' => 'పేరుబరులు',
 'defaultns' => 'లేకపోతే ఈ నేంస్పేసులలో అన్వేషించు:',
 'default' => 'అప్రమేయం',
@@ -1241,7 +1242,7 @@ $1",
 'prefs-emailconfirm-label' => 'ఈ-మెయిల్ నిర్ధారణ:',
 'prefs-textboxsize' => 'దిద్దుబాటు కిటికీ పరిమాణం',
 'youremail' => 'మీ ఈ-మెయిలు*',
-'username' => 'వాడుకరి పేరు:',
+'username' => '{{GENDER:$1|వాడుకరి పేరు}}:',
 'uid' => 'వాడుకరి ID:',
 'prefs-memberingroups' => 'సభ్యులుగా ఉన్న {{PLURAL:$1|గుంపు|గుంపులు}}:',
 'prefs-registration' => 'నమోదైన సమయం:',
@@ -2264,7 +2265,7 @@ $UNWATCHURL కి వెళ్ళండి.
 'blanknamespace' => '(మొదటి)',
 
 # Contributions
-'contributions' => 'వాడుకరి రచనలు',
+'contributions' => '{{GENDER:$1|వాడుకరి}} రచనలు',
 'contributions-title' => '$1 యొక్క మార్పులు-చేర్పులు',
 'mycontris' => 'మార్పులు చేర్పులు',
 'contribsub2' => '$1 ($2) కొరకు',
@@ -2832,7 +2833,10 @@ $1',
 'minutes' => '{{PLURAL:$1|ఒక నిమిషం|$1 నిమిషాల}}',
 'hours' => '{{PLURAL:$1|ఒక గంట|$1 గంటల}}',
 'days' => '{{PLURAL:$1|ఒక రోజు|$1 రోజుల}}',
+'months' => '{{PLURAL:$1|ఒక నెల|$1 నెలల}}',
+'years' => '{{PLURAL:$1|ఒక సంవత్సరం|$1 సంవత్సరాల}}',
 'ago' => '$1 క్రితం',
+'just-now' => 'ఇప్పుడే',
 
 # Bad image list
 'bad_image_list' => 'కింద తెలిపిన తీరులో కలపాలి:
@@ -3521,7 +3525,6 @@ $5
 'logentry-newusers-create' => '$1 ఒక వాడుకరి ఖాతాను సృష్టించారు',
 'logentry-newusers-create2' => '$1  వాడుకరి ఖాతా $3ను సృష్టించారు',
 'logentry-newusers-autocreate' => '$1 ఖాతాను ఆటోమెటిగ్గా సృష్టించారు',
-'newuserlog-byemail' => 'ఈ-మెయిలులో సంకేతపదం పంపించాం',
 'rightsnone' => '(ఏమీలేవు)',
 
 # Feedback
index b614b9f..ebde245 100644 (file)
@@ -82,11 +82,15 @@ $messages = array(
 'tog-watchdefault' => "Hateke pájina sira-ne'ebé ha'u edita",
 'tog-watchmoves' => "Hateke pájina sira-ne'ebé ha'u book",
 'tog-watchdeletion' => "Hateke pájina sira-ne'ebé ha'u halakon",
+'tog-minordefault' => 'Edita hotu-hotu "ki\'ik"',
+'tog-oldsig' => 'Asinatura atuál',
 'tog-watchlisthideown' => "La hatudu ha'u-nia edita iha lista hateke",
 'tog-watchlisthidebots' => 'Hamsumik bot iha lista hateke',
 'tog-watchlisthideminor' => "Hamsumik muda ki-ki'ik iha lista hateke",
 'tog-watchlisthideliu' => 'La hatudu edita ema rejista nian iha lista hateke',
 'tog-watchlisthideanons' => 'La hatudu edita ema anónimu nian iha lista hateke',
+'tog-watchlisthidepatrolled' => 'Hamsumik muda patrolada iha lista hateke',
+'tog-ccmeonemails' => "Haruka ba ha'u kopia korreiu eletróniku nian ne'ebé ha'u korreia",
 'tog-showhiddencats' => "Hatudu kategoria sira-ne'ebé subar",
 
 'underline-always' => 'Sempre',
@@ -367,6 +371,7 @@ Ita-nia mudansa la armazenadu seidauk!",
 # History pages
 'currentrev' => 'Versaun atuál',
 'revisionasof' => 'Versaun $1 nian',
+'revision-info' => 'Revisaun loron $4, tempu $5, husi $2',
 'previousrevision' => '←Versaun tuan liu',
 'nextrevision' => 'Versaun foun liu→',
 'currentrevisionlink' => 'Versaun atuál',
index 3b58018..371a819 100644 (file)
@@ -2533,7 +2533,6 @@ $5
 # New logging system
 'revdelete-restricted' => 'маҳдудиятҳо ба мудирон амалӣ шуданд',
 'revdelete-unrestricted' => 'маҳдудиятҳо аз мудирон бардошта шуданд',
-'newuserlog-byemail' => 'калимаи убур ба почтаи электронӣ фиристода шуд',
 'rightsnone' => '(ҳеҷ)',
 
 );
index 359c5cd..6d8f1d3 100644 (file)
@@ -2335,7 +2335,6 @@ Nişonai pajvandro biduni peşvand "{{ns:file}}:" vorid kuned.',
 # New logging system
 'revdelete-restricted' => 'mahdudijatho ba mudiron amalī şudand',
 'revdelete-unrestricted' => 'mahdudijatho az mudiron bardoşta şudand',
-'newuserlog-byemail' => 'kalimai ubur ba poctai elektronī firistoda şud',
 'rightsnone' => '(heç)',
 
 );
index d79544b..7b4cbe5 100644 (file)
@@ -197,7 +197,7 @@ $linkTrail = '/^([a-z]+)(.*)\$/sD';
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'à¸\82ีà¸\94à¹\80สà¹\89à¸\99à¹\83à¸\95à¹\89ลิà¸\87à¸\81à¹\8c',
+'tog-underline' => 'à¸\81ารà¸\82ีà¸\94à¹\80สà¹\89à¸\99à¹\83à¸\95à¹\89ลิà¸\87à¸\81à¹\8c:',
 'tog-justify' => 'จัดย่อหน้าชิดขอบ',
 'tog-hideminor' => 'ซ่อนการแก้ไขเล็กน้อยในหน้าปรับปรุงล่าสุด',
 'tog-hidepatrolled' => 'ซ่อนการแก้ไขที่ตรวจแล้วในหน้าปรับปรุงล่าสุด',
@@ -248,7 +248,7 @@ $messages = array(
 'underline-default' => 'ค่าโดยปริยายของหน้าตาหรือเบราว์เซอร์',
 
 # Font style option in Special:Preferences
-'editfont-style' => 'รูà¸\9bà¹\81à¸\9aà¸\9aà¸\95ัวอักษรในพื้นที่แก้ไข:',
+'editfont-style' => 'รูà¸\9bà¹\81à¸\9aà¸\9aà¸\8aุà¸\94à¹\81à¸\9aà¸\9aอักษรในพื้นที่แก้ไข:',
 'editfont-default' => 'ค่าตั้งต้นของเบราว์เซอร์',
 'editfont-monospace' => 'ชุดอักษรแบบความกว้างคงที่',
 'editfont-sansserif' => 'ชุดอักษรแบบไม่มีเชิง',
@@ -333,7 +333,7 @@ $messages = array(
 'morenotlisted' => 'มีที่ยังไม่แสดงอีก...',
 'mypage' => 'หน้า',
 'mytalk' => 'พูดคุย',
-'anontalk' => 'พูดคุยกับไอพีนี้',
+'anontalk' => 'à¸\9eูà¸\94à¸\84ุยà¸\81ัà¸\9aà¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¸\99ีà¹\89',
 'navigation' => 'ป้ายบอกทาง',
 'and' => '&#32;และ',
 
@@ -369,14 +369,14 @@ $messages = array(
 'returnto' => 'กลับไป $1',
 'tagline' => 'จาก {{SITENAME}}',
 'help' => 'คำอธิบาย',
-'search' => 'สืà¸\9aà¸\84à¹\89à¸\99',
-'searchbutton' => 'สืà¸\9aà¸\84à¹\89à¸\99',
+'search' => 'à¸\84à¹\89à¸\99หา',
+'searchbutton' => 'à¸\84à¹\89à¸\99หา',
 'go' => 'ไป',
 'searcharticle' => 'ไป',
 'history' => 'ประวัติหน้า',
 'history_short' => 'ประวัติ',
 'updatedmarker' => 'การปรับตั้งแต่การเข้าชมครั้งล่าสุดของฉัน',
-'printableversion' => 'รุà¹\88à¸\99สำหรัà¸\9aพิมพ์',
+'printableversion' => 'รุà¹\88à¸\99à¸\9eรà¹\89อมพิมพ์',
 'permalink' => 'ลิงก์ถาวร',
 'print' => 'พิมพ์',
 'view' => 'ดู',
@@ -391,14 +391,14 @@ $messages = array(
 'protect' => 'ล็อก',
 'protect_change' => 'เปลี่ยน',
 'protectthispage' => 'ล็อกหน้านี้',
-'unprotect' => 'à¹\80à¸\9bลีà¹\88ยà¸\99à¸\84à¹\88าà¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99',
-'unprotectthispage' => 'à¹\81à¸\81à¹\89à¹\84à¸\82การป้องกันหน้านี้',
+'unprotect' => 'เปลี่ยนการป้องกัน',
+'unprotectthispage' => 'à¹\80à¸\9bลีà¹\88ยà¸\99การป้องกันหน้านี้',
 'newpage' => 'หน้าใหม่',
 'talkpage' => 'อภิปรายหน้านี้',
 'talkpagelinktext' => 'พูดคุย',
 'specialpage' => 'หน้าพิเศษ',
 'personaltools' => 'เครื่องมือส่วนตัว',
-'postcomment' => 'à¸\95อนใหม่',
+'postcomment' => 'สà¹\88วนใหม่',
 'articlepage' => 'ดูหน้าเนื้อหา',
 'talk' => 'อภิปราย',
 'views' => 'ดู',
@@ -419,18 +419,18 @@ $messages = array(
 'protectedpage' => 'หน้าถูกล็อก',
 'jumpto' => 'ข้ามไปยัง:',
 'jumptonavigation' => 'นำทาง',
-'jumptosearch' => 'สืà¸\9aà¸\84à¹\89à¸\99',
+'jumptosearch' => 'à¸\84à¹\89à¸\99หา',
 'view-pool-error' => 'ขออภัย ขณะนี้เซิร์ฟเวอร์มีภาระเกิน
 ผู้ใช้พยายามเข้าดูหน้านี้มากเกินไป
 กรุณารอสักครู่ก่อนที่จะเข้าดูหน้านี้อีกครั้งหนึ่ง
 
 $1',
-'pool-timeout' => 'à¹\80à¸\81ิà¸\99à¹\80วลารอà¸\81ารลà¹\87อà¸\84',
+'pool-timeout' => 'à¹\80à¸\81ิà¸\99à¹\80วลารอà¸\81ารลà¹\87อà¸\81',
 'pool-queuefull' => 'พื้นที่รองรับคิวเต็ม',
-'pool-errorunknown' => 'à¹\80à¸\81ิà¸\94à¸\84วามผิดพลาดไม่ทราบสาเหตุ',
+'pool-errorunknown' => 'à¹\80à¸\81ิà¸\94à¸\82à¹\89อผิดพลาดไม่ทราบสาเหตุ',
 
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
-'aboutsite' => 'เกี่ยวกับ {{SITENAME}}',
+'aboutsite' => 'เกี่ยวกับ{{SITENAME}}',
 'aboutpage' => 'Project:เกี่ยวกับ',
 'copyright' => 'เนื้อหาอนุญาตให้เผยแพร่ภายใต้ $1',
 'copyrightpage' => '{{ns:project}}:ลิขสิทธิ์',
@@ -450,8 +450,8 @@ $1',
 'privacypage' => 'Project:นโยบายสิทธิส่วนบุคคล',
 
 'badaccess' => 'มีข้อผิดพลาดในการใช้สิทธิ',
-'badaccess-group0' => 'à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aอà¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¸\95ามà¸\97ีà¹\88รà¹\89อà¸\87à¸\82อ',
-'badaccess-groups' => 'à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\81ารà¸\97ีà¹\88à¸\84ุà¸\93รà¹\89อà¸\87à¸\82อà¸\99ีà¹\89สà¸\87วà¸\99à¹\84วà¹\89à¹\80à¸\89à¸\9eาะà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\83à¸\99{{PLURAL:$2|à¸\81ลุà¹\88ม|à¸\81ลุà¹\88มหà¸\99ึà¹\88à¸\87à¸\81ลุà¹\88มà¹\83à¸\94 à¸\94ัà¸\87à¸\99ีà¹\89}}: $1',
+'badaccess-group0' => 'คุณไม่ได้รับอนุญาตให้ดำเนินการตามที่ขอ',
+'badaccess-groups' => 'ปฏิบัติการที่คุณขอนี้สงวนไว้เฉพาะผู้ใช้ใน{{PLURAL:$2|กลุ่ม|กลุ่มหนึ่งกลุ่มใด ดังนี้}}: $1',
 
 'versionrequired' => 'ต้องการมีเดียวิกิรุ่น $1',
 'versionrequiredtext' => 'ต้องการมีเดียวิกิรุ่น $1 สำหรับใช้งานหน้านี้ ดู[[Special:Version|หน้ารุ่น]]',
@@ -477,7 +477,7 @@ $1',
 'hidetoc' => 'ซ่อน',
 'collapsible-collapse' => 'ยุบ',
 'collapsible-expand' => 'ขยาย',
-'thisisdeleted' => 'à¹\81สà¸\94à¸\87หรือà¹\80รียà¸\81à¸\94ู $1',
+'thisisdeleted' => 'à¸\94ูหรือà¸\81ูà¹\89à¸\84ืà¸\99 $1 à¸«à¸£à¸·à¸­à¹\84มà¹\88',
 'viewdeleted' => 'ดู $1',
 'restorelink' => '$1 การแก้ไขที่ถูกลบ',
 'feedlinks' => 'ฟีด',
@@ -509,7 +509,7 @@ $1',
 คุณอาจกรอกยูอาร์แอลผิด หรือมาตามลิงก์ที่ไม่ถูกต้อง
 หรืออาจเกิดจากข้อผิดพลาดในซอฟต์แวร์ซึ่ง {{SITENAME}} ใช้อยู่',
 'nosuchspecialpage' => 'ไม่มีหน้าพิเศษดังกล่าว',
-'nospecialpagetext' => '<strong>à¸\84ุà¸\93รà¹\89อà¸\87à¸\82อหà¸\99à¹\89าà¸\9eิà¹\80ศษà¹\84มà¹\88à¸\96ูà¸\81à¸\95à¹\89อà¸\87</strong>
+'nospecialpagetext' => '<strong>คุณขอหน้าพิเศษไม่ถูกต้อง</strong>
 
 รายการหน้าพิเศษที่ถูกต้องดูได้ที่ [[Special:SpecialPages|รายการหน้าพิเศษ]]',
 
@@ -537,7 +537,7 @@ $1',
 
 สาเหตุมักเกิดจากการเปรียบเทียบที่ล้าสมัย หรือการเชื่อมโยงประวัติไปยังหน้านั้นได้ถูกลบแล้ว
 
-หากไม่ใช่กรณีดังกล่าว คุณอาจพบบั๊กในซอฟต์แวร์ กรุณารายงานต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]] พร้อมระบุ URL',
+หากไม่ใช่กรณีดังกล่าว คุณอาจพบบั๊กในซอฟต์แวร์ กรุณารายงานต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]] พร้อมระบุยูอาร์แอล',
 'missingarticle-rev' => '(รุ่น#: $1)',
 'missingarticle-diff' => '(ต่าง: $1, $2)',
 'readonly_lag' => 'ฐานข้อมูลถูกล็อกอัตโนมัติขณะที่เซิร์ฟเวอร์ฐานข้อมูลรองกำลังปรับปรุงตามฐานข้อมูลหลัก',
@@ -553,17 +553,18 @@ $1',
 'fileexistserror' => 'ไม่สามารถเขียนไฟล์ "$1" ได้ เนื่องจากมีไฟล์อยู่แล้ว',
 'unexpected' => 'ผลที่ไม่คาดคิด: "$1"="$2"',
 'formerror' => 'ผิดพลาด: ไม่สามารถส่งแบบได้',
-'badarticleerror' => 'à¹\84มà¹\88สามารà¸\96à¸\94ำà¹\80à¸\99ิà¸\99à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\81ารà¸\99ี้ในหน้านี้',
+'badarticleerror' => 'à¸\81ารà¸\81ระà¸\97ำà¸\99ีà¹\89à¹\84มà¹\88สามารà¸\96à¸\97ำà¹\84à¸\94้ในหน้านี้',
 'cannotdelete' => 'ไม่สามารถลบหน้าหรือไฟล์ "$1" 
 อาจมีผู้อื่นลบไปแล้ว',
 'cannotdelete-title' => "ไม่สามารถลบหน้า ''$1''",
 'delete-hook-aborted' => 'การลบถูกฮุกยกเลิก
-ไม่มีคำอธิบายสำหรับการยกเลิกนี้',
-'badtitle' => 'ชื่อไม่เหมาะสม',
-'badtitletext' => 'ชื่อหน้าที่ร้องขอไม่ถูกต้อง เป็นชื่อว่าง หรือชื่อที่ผิดพลาดเนื่องจากลิงก์ข้ามมาจากภาษาอื่น ชื่อที่ใช้อาจมีตัวอักษรที่ไม่สามารถปรากฏในชื่อได้',
-'perfcached' => 'ข้อมูลต่อไปนี้ถูกเก็บไว้ในแคช และอาจล้าสมัย มีผลการค้นหาสูงสุด $1 รายการในแคช',
-'perfcachedts' => 'ข้อมูลต่อไปนี้ถูกเก็บไว้ในหน่วยความจำแคช และได้รับการปรับล่าสุดเมื่อ $1 ค่าสูงสุด $4 ผลลัพธ์สามารถเก็บไว้ในหน่วยความจำแคชได้',
-'querypage-no-updates' => 'ขณะนี้การปรับปรุงหน้านี้ถูกระงับ ข้อมูลในที่นี่จะไม่รีเฟรชเป็นปัจจุบัน',
+โดยไม่มีคำอธิบาย',
+'badtitle' => 'ใช้ชื่อหัวข้อนี้ไม่ได้',
+'badtitletext' => 'ชื่อหน้าที่ขอไม่ถูกต้อง เป็นชื่อว่าง หรือชื่อข้ามภาษาหรือข้ามวิกิที่เชื่อมโยงไม่ถูกต้อง
+อาจมีอักขระที่ไม่สามารถใช้ในชื่อเรื่องได้',
+'perfcached' => 'ข้อมูลต่อไปนี้ถูกเก็บในแคช และอาจล้าสมัย มีผลการค้นหาสูงสุด $1 รายการในแคช',
+'perfcachedts' => 'ข้อมูลต่อไปนี้ถูกเก็บในแคช และได้รับการปรับล่าสุดเมื่อ $1 ผลลัพธ์สูงสุด $4 รายการสามารถเก็บในแคชได้',
+'querypage-no-updates' => 'ขณะนี้การปรับปรุงหน้านี้ถูกระงับ ข้อมูลในที่นี้จะไม่รีเฟรชเป็นปัจจุบัน',
 'wrong_wfQuery_params' => 'พารามิเตอร์ที่ส่งไป wfQuery() ไม่ถูกต้อง<br />
 ฟังก์ชั่น: $1<br />
 คำค้น: $2',
@@ -585,15 +586,17 @@ $1',
 'customcssprotected' => 'คุณไม่มีสิทธิแก้ไขหน้าสไตล์ CSS นี้ เนื่องจากหน้านี้มีการตั้งค่าส่วนบุคคลของผู้ใช้อื่น',
 'customjsprotected' => 'คุณไม่มีสิทธิแก้ไขหน้าจาวาสคริปต์นี้ เนื่องจากหน้านี้มีการตั้งค่าส่วนบุคคลของผู้ใช้อื่น',
 'ns-specialprotected' => 'หน้าพิเศษไม่สามารถแก้ไขได้',
-'titleprotected' => "หัวเรื่องนี้ถูกป้องกันมิให้สร้างโดย [[User:$1|$1]] 
-เหตุผลที่ให้ไว้ คือ ''$2''",
-'invalidtitle-knownnamespace' => 'ชื่อที่มีเนมสเปซ "$2" กับข้อความ "$3" ไม่ถูกต้อง',
-'invalidtitle-unknownnamespace' => 'ชื่อที่ไม่ทราบเนมสเปซหมายเลข $1 กับข้อความ "$2" ไม่ถูกต้อง',
+'titleprotected' => "ชื่อเรื่องนี้ถูกป้องกันมิให้สร้างโดย [[User:$1|$1]] 
+เหตุผลที่ให้ไว้คือ ''$2''",
+'filereadonlyerror' => 'ไม่สามารถแก้ไขไฟล์ "$1" เพราะที่เก็บไฟล์ "$2" อยู่ในภาวะอ่านอย่างเดียว
+ผู้ดูแลระบบที่ล็อกให้คำอธิบายว่า: "$3"',
+'invalidtitle-knownnamespace' => 'ชื่อเรื่องที่มีเนมสเปซ "$2" กับข้อความ "$3" ไม่ถูกต้อง',
+'invalidtitle-unknownnamespace' => 'ชื่อเรื่องที่ไม่ทราบเนมสเปซหมายเลข $1 กับข้อความ "$2" ไม่ถูกต้อง',
 'exception-nologin' => 'ไม่ได้ล็อกอิน',
-'exception-nologin-text' => 'หน้าหรือปฏิบัติการนี้กำหนดให้คุณล็อกอินเข้าสู่วิกินี้ก่อน',
+'exception-nologin-text' => 'หà¸\99à¹\89าหรือà¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\81ารà¸\99ีà¹\89à¸\81ำหà¸\99à¸\94à¹\83หà¹\89à¸\84ุà¸\93à¸\95à¹\89อà¸\87ลà¹\87อà¸\81อิà¸\99à¹\80à¸\82à¹\89าสูà¹\88วิà¸\81ิà¸\99ีà¹\89à¸\81à¹\88อà¸\99',
 
 # Virus scanner
-'virus-badscanner' => "à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าผิดพลาด: ไม่รู้จักตัวสแกนไวรัส: ''$1''",
+'virus-badscanner' => "à¹\82à¸\84รà¸\87à¹\81à¸\9aà¸\9aผิดพลาด: ไม่รู้จักตัวสแกนไวรัส: ''$1''",
 'virus-scanfailed' => 'การสแกนล้มเหลว (โค้ด $1)',
 'virus-unknownscanner' => 'ไม่รู้จักโปรแกรมป้องกันไวรัสตัวนี้:',
 
@@ -601,7 +604,7 @@ $1',
 'logouttext' => "'''ขณะนี้คุณได้ล็อกเอาต์แล้ว'''
 
 คุณสามารถใช้งาน {{SITENAME}} ต่อในฐานะผู้ใช้นิรนาม หรือคุณสามารถ<span class='plainlinks'>[$1 ล็อกอินกลับเข้าไป]</span>ด้วยชื่อผู้ใช้เดิมหรือชื่อผู้ใช้อื่น
-อย่างไรก็ตามอาจมีบางหน้าที่แสดงผลเสมือนคุณกำลังล็อกอินอยู่ จนกว่าคุณจะล้างแคชเบราว์เซอร์ของคุณ",
+อยà¹\88าà¸\87à¹\84รà¸\81à¹\87à¸\95ามอาà¸\88มีà¸\9aาà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¹\81สà¸\94à¸\87à¸\9cลà¹\80สมือà¸\99วà¹\88าà¸\84ุà¸\93à¸\81ำลัà¸\87ลà¹\87อà¸\81อิà¸\99อยูà¹\88 à¸\88à¸\99à¸\81วà¹\88าà¸\84ุà¸\93à¸\88ะลà¹\89าà¸\87à¹\81à¸\84à¸\8aà¹\80à¸\9aราวà¹\8cà¹\80à¸\8bอรà¹\8cà¸\82อà¸\87à¸\84ุà¸\93",
 'welcomeuser' => 'ยินดีต้อนรับ $1!',
 'welcomecreation-msg' => 'บัญชีของคุณถูกสร้างขึ้นแล้ว
 อย่าลืมเปลี่ยนแปลง[[Special:Preferences|การตั้งค่าใน {{SITENAME}}]] ของคุณ',
@@ -627,7 +630,7 @@ $1',
 'gotaccount' => "มีบัญชีแล้วใช่ไหม '''$1'''",
 'gotaccountlink' => 'ล็อกอิน',
 'userlogin-resetlink' => 'ลืมรายละเอียดล็อกอินของคุณหรือ',
-'createaccountmail' => 'à¸\9cà¹\88าà¸\99à¸\97าà¸\87อีà¹\80มล',
+'createaccountmail' => 'à¹\83à¸\8aà¹\89รหัสà¸\9cà¹\88าà¸\99สุà¹\88มà¸\8aัà¹\88วà¸\84ราวà¹\81ละสà¹\88à¸\87à¹\84à¸\9bยัà¸\87à¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\97ีà¹\88ระà¸\9aุà¸\94à¹\89าà¸\99ลà¹\88าà¸\87',
 'createaccountreason' => 'เหตุผล:',
 'badretype' => 'รหัสผ่านที่ใส่ไม่ตรงกัน',
 'userexists' => 'ชื่อผู้ใช้ที่กรอกมีผู้อื่นใช้ไปแล้ว กรุณาเลือกชื่ออื่น',
@@ -641,55 +644,57 @@ $1',
 'loginsuccesstitle' => 'ล็อกอินสำเร็จ',
 'loginsuccess' => "'''ขณะนี้คุณล็อกอินเข้าสู่ {{SITENAME}} ด้วยชื่อ \"\$1\"'''",
 'nosuchuser' => 'ไม่มีผู้ใช้ชื่อ "$1"
-อัà¸\81ษรà¹\83หà¸\8dà¹\88à¹\80ลà¹\87à¸\81มีà¸\9cลà¸\95à¹\88อà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89
+à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ัà¹\89à¸\99à¹\84วà¸\95à¹\88ออัà¸\81ษรà¹\83หà¸\8dà¹\88à¹\80ลà¹\87à¸\81
 กรุณาตรวจการสะกดอีกครั้ง หรือ[[Special:UserLogin/signup|สร้างบัญชีใหม่]]',
 'nosuchusershort' => 'ไม่มีผู้ใช้ชื่อ "$1" กรุณาตรวจสอบการสะกด',
 'nouserspecified' => 'คุณต้องระบุชื่อผู้ใช้',
 'login-userblocked' => 'ผู้ใช้นี้ถูกบล็อก ไม่อนุญาตให้ล็อกอิน',
 'wrongpassword' => 'รหัสผ่านที่ใส่ไม่ถูกต้อง โปรดลองอีกครั้ง',
 'wrongpasswordempty' => 'ยังไม่ได้ระบุรหัสผ่าน โปรดลองอีกครั้ง',
-'passwordtooshort' => 'รหัสà¸\9cà¹\88าà¸\99à¸\95à¹\89อà¸\87มีà¸\84วามยาวอยà¹\88าà¸\87à¸\99à¹\89อย $1 à¸\95ัวอัà¸\81ษร',
-'password-name-match' => 'รหัสà¸\9cà¹\88าà¸\99à¸\82อà¸\87à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\95à¹\88าà¸\87à¸\88าà¸\81à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\82อà¸\87à¸\84ุà¸\93',
+'passwordtooshort' => 'รหัสà¸\9cà¹\88าà¸\99à¸\95à¹\89อà¸\87มีà¸\84วามยาวอยà¹\88าà¸\87à¸\99à¹\89อย $1 à¸­à¸±à¸\81à¸\82ระ',
+'password-name-match' => 'รหัสà¸\9cà¹\88าà¸\99à¸\95à¹\89อà¸\87à¸\95à¹\88าà¸\87à¸\88าà¸\81à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89',
 'password-login-forbidden' => 'ห้ามใช้ชื่อผู้ใช้และรหัสผ่านนี้',
 'mailmypassword' => 'อีเมลรหัสผ่านใหม่',
 'passwordremindertitle' => 'รหัสผ่านชั่วคราวใหม่สำหรับ {{SITENAME}}',
-'passwordremindertext' => 'à¸\9cูà¹\89à¹\83à¸\94à¸\9cูà¹\89หà¸\99ึà¹\88à¸\87 (à¸\8bึà¹\88à¸\87อาà¸\88à¹\80à¸\9bà¹\87à¸\99à¸\84ุà¸\93 à¸\97ีà¹\88à¹\83à¸\8aà¹\89หมายà¹\80ลà¸\82à¹\84อà¸\9eี $1) à¸\82อà¹\83หà¹\89สà¹\88à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\82อà¸\87 {{SITENAME}} ($4) à¸£à¸«à¸±à¸ªà¸\9cà¹\88าà¸\99à¸\8aัà¹\88วà¸\84ราวสำหรัà¸\9aà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89 "$2" à¸\96ูà¸\81สรà¹\89าà¸\87à¸\82ึà¹\89à¸\99 à¹\81ละà¸\81ำหà¸\99à¸\94à¹\80à¸\9bà¹\87à¸\99 "$3" à¸«à¸²à¸\81เป็นเจตนาของคุณ คุณจำต้องล็อกอินและเลือกรหัสผ่านใหม่ ณ ขณะนี้ รหัสผ่านชั่วคราวของคุณจะหมดอายุใน $5 วัน
+'passwordremindertext' => 'à¸\9cูà¹\89à¹\83à¸\94à¸\9cูà¹\89หà¸\99ึà¹\88à¸\87 (à¸\8bึà¹\88à¸\87อาà¸\88à¹\80à¸\9bà¹\87à¸\99à¸\84ุà¸\93 à¸\97ีà¹\88à¹\83à¸\8aà¹\89à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี $1) à¸\82อà¹\83หà¹\89สà¹\88à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\82อà¸\87 {{SITENAME}} ($4) à¸£à¸«à¸±à¸ªà¸\9cà¹\88าà¸\99à¸\8aัà¹\88วà¸\84ราวสำหรัà¸\9aà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89 "$2" à¸\96ูà¸\81สรà¹\89าà¸\87à¸\82ึà¹\89à¸\99 à¹\81ละà¸\81ำหà¸\99à¸\94à¹\80à¸\9bà¹\87à¸\99 "$3" à¸«à¸²à¸\81à¸\81ารà¸\82อรหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\99ีà¹\89เป็นเจตนาของคุณ คุณจำต้องล็อกอินและเลือกรหัสผ่านใหม่ ณ ขณะนี้ รหัสผ่านชั่วคราวของคุณจะหมดอายุใน $5 วัน
 
-หาà¸\81à¸\9aุà¸\84à¸\84ลอืà¹\88à¸\99à¸\9aุà¸\84à¸\84ลà¹\83à¸\94ขอรหัสผ่านใหม่ หรือหากคุณจำรหัสผ่านของคุณได้แล้ว และไม่ต้องการเปลี่ยนรหัสผ่านใหม่อีกต่อไป คุณอาจละเลยข้อความนี้และใช้รหัสผ่านเดิมของคุณต่อไป',
+หาà¸\81à¹\80à¸\9bà¹\87à¸\99à¸\9aุà¸\84à¸\84ลอืà¹\88à¸\99à¸\97ีà¹\88ขอรหัสผ่านใหม่ หรือหากคุณจำรหัสผ่านของคุณได้แล้ว และไม่ต้องการเปลี่ยนรหัสผ่านใหม่อีกต่อไป คุณอาจละเลยข้อความนี้และใช้รหัสผ่านเดิมของคุณต่อไป',
 'noemail' => 'ไม่มีที่อยู่อีเมลบันทึกไว้สำหรับผู้ใช้ "$1"',
 'noemailcreate' => 'คุณจำต้องใส่ที่อยู่อีเมลให้ถูกต้อง',
-'passwordsent' => 'รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81สà¹\88à¸\87à¹\84à¸\9bยัà¸\87à¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\97ีà¹\88ลà¸\87à¸\97ะà¹\80à¸\9aียà¸\99à¹\84วà¹\89à¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89 "$1"
-à¸\81รุà¸\93าลà¹\87อà¸\81อิà¸\99อีà¸\81à¸\84รัà¹\89à¸\87หลัà¸\87à¸\88าà¸\81à¸\84ุà¸\93à¹\84à¸\94à¹\89รัà¸\9aอีà¹\80มล',
-'blocked-mailpassword' => 'หมายà¹\80ลà¸\82ไอพีของคุณถูกบล็อกมิให้แก้ไข ฉะนั้น จึงไม่ได้รับอนุญาตให้ใช้ฟังก์ชันขอกู้รหัสผ่านเพื่อป้องกันการกระทำผิด',
-'eauthentsent' => 'อีà¹\80มลยืà¸\99ยัà¸\99à¹\84à¸\94à¹\89à¸\96ูà¸\81สà¹\88à¸\87à¹\84à¸\9bà¸\97ีà¹\88อีà¹\80มลà¸\97ีà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81à¹\80สà¸\99อ à¸\81à¹\88อà¸\99à¸\97ีà¹\88อีà¹\80มลà¸\88ะà¸\96ูà¸\81สà¹\88à¸\87à¹\84à¸\9bà¸\97ีà¹\88à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีà¸\99ัà¹\89à¸\99 à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\95ามà¸\84ำà¹\81à¸\99ะà¸\99ำà¹\83à¸\99อีà¹\80มลà¹\80à¸\9eืà¹\88อยืà¸\99ยัà¸\99วà¹\88าหมายà¹\80ลยà¸\9aัà¸\8dà¸\8aีà¸\99ัà¹\89à¸\99à¹\80à¸\9bà¹\87à¸\99à¸\82อà¸\87à¸\84ุà¸\93',
+'passwordsent' => 'รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\96ูà¸\81สà¹\88à¸\87à¹\84à¸\9bยัà¸\87à¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\97ีà¹\88ลà¸\87à¸\97ะà¹\80à¸\9aียà¸\99à¹\84วà¹\89à¸\82อà¸\87 "$1"
+กรุณาล็อกอินอีกครั้งหลังได้รับอีเมล',
+'blocked-mailpassword' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณถูกบล็อกมิให้แก้ไข ฉะนั้น จึงไม่ได้รับอนุญาตให้ใช้ฟังก์ชันขอกู้รหัสผ่านเพื่อป้องกันการกระทำผิด',
+'eauthentsent' => 'อีà¹\80มลยืà¸\99ยัà¸\99à¹\84à¸\94à¹\89à¸\96ูà¸\81สà¹\88à¸\87à¹\84à¸\9bà¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\97ีà¹\88à¹\80สà¸\99อ à¸\81à¹\88อà¸\99à¸\97ีà¹\88อีà¹\80มลà¸\88ะà¸\96ูà¸\81สà¹\88à¸\87à¹\84à¸\9bà¸\97ีà¹\88à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีà¸\99ัà¹\89à¸\99 à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\95ามà¸\84ำà¹\81à¸\99ะà¸\99ำà¹\83à¸\99อีà¹\80มลà¹\80à¸\9eืà¹\88อยืà¸\99ยัà¸\99วà¹\88าà¸\9aัà¸\8dà¸\8aีà¸\99ัà¹\89à¸\99à¹\80à¸\9bà¹\87à¸\99à¸\82อà¸\87à¸\84ุà¸\93à¸\88ริà¸\87 à¹\86',
 'throttled-mailpassword' => 'ตัวเตือนรหัสผ่านได้ถูกส่งไปแล้วใน $1 ชั่วโมงที่ผ่านมา ตัวเตือนรหัสผ่านนี้จะถูกส่งได้หนึ่งครั้งต่อ $1 ชั่วโมงเท่านั้น เพื่อป้องกันการกระทำผิด',
-'mailerror' => 'ไม่สามารถส่งอีเมลเนื่องจาก $1',
-'acct_creation_throttle_hit' => 'ผู้เข้าชมที่ใช้หมายเลขไอพีของคุณในวิกินี้ ได้สร้างชื่อบัญชีแล้ว $1 บัญชีในวันที่ผ่านมา ซึ่งเป็นจำนวนมากที่สุดที่อนุญาตในช่วงเวลาดังกล่าว
-จึงส่งผลให้ผู้เข้าชมที่ใช้หมายเลขไอพีนี้ ไม่สามารถสร้างบัญชีได้อีกในขณะนี้',
-'emailauthenticated' => 'อีเมลของคุณได้รับการรับรอง ณ วันที่ $2 เวลา $3',
-'emailnotauthenticated' => 'อีเมลของคุณยังไม่ได้ถูกยืนยัน ดังนั้นคำสั่งพิเศษที่ใช้งานผ่านอีเมลยังไม่เปิดใช้งาน',
+'mailerror' => 'ข้อผิดพลาดในการส่งเมล: $1',
+'acct_creation_throttle_hit' => 'ผู้เข้าชมวิกินี้ที่ใช้เลขที่อยู่ไอพีของคุณ ได้สร้างบัญชีแล้ว $1 บัญชีในวันที่ผ่านมา ซึ่งเป็นจำนวนสูงสุดที่อนุญาตในช่วงเวลาดังกล่าว
+จึงส่งผลให้ผู้เข้าชมที่ใช้เลขที่อยู่ไอพีนี้ ไม่สามารถสร้างบัญชีได้อีกในขณะนี้',
+'emailauthenticated' => 'ที่อยู่อีเมลของคุณได้รับการยืนยันเมื่อวันที่ $2 เวลา $3',
+'emailnotauthenticated' => 'ที่อยู่อีเมลของคุณยังไม่ได้รับการยืนยัน 
+ไม่มีการส่งอีเมลสำหรับคุณลักษณะใด ๆ ต่อไปนี้',
 'noemailprefs' => 'ระบุที่อยู่อีเมลในการตั้งค่าของคุณเพื่อให้คุณลักษณะเหล่านี้ทำงานได้',
-'emailconfirmlink' => 'ยืนยันอีเมลของคุณ',
+'emailconfirmlink' => 'ยืà¸\99ยัà¸\99à¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\82อà¸\87à¸\84ุà¸\93',
 'invalidemailaddress' => 'ไม่สามารถรับที่อยู่อีเมลได้ เพราะดูมีรูปแบบไม่ถูกต้อง
 โปรดใส่ที่อยู่ให้มีรูปแบบถูกต้อง หรือเว้นช่องนั้น',
 'cannotchangeemail' => 'ไม่สามารถเปลี่ยนที่อยู่อีเมลบนวิกินี้',
 'emaildisabled' => 'เว็บไซต์นี้ไม่สามารถส่งอีเมล',
-'accountcreated' => 'à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีà¹\84à¸\94à¹\89ถูกสร้างขึ้น',
-'accountcreatedtext' => 'à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีสำหรัà¸\9a $1 à¹\84à¸\94à¹\89ถูกสร้างขึ้นแล้ว',
+'accountcreated' => 'à¸\9aัà¸\8dà¸\8aีถูกสร้างขึ้น',
+'accountcreatedtext' => 'à¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\82อà¸\87 $1 ถูกสร้างขึ้นแล้ว',
 'createaccount-title' => 'สร้างบัญชีสำหรับ {{SITENAME}}',
-'createaccount-text' => 'มีà¸\9aาà¸\87à¸\84à¸\99สรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีสำหรัà¸\9aà¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\82อà¸\87à¸\84ุà¸\93à¹\84วà¹\89à¸\9aà¸\99 {{SITENAME}} ($4) à¹\82à¸\94ยà¹\83à¸\8aà¹\89à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89 "$2" และรหัสผ่าน "$3" คุณควรล็อกอินเพื่อเปลี่ยนรหัสผ่านทันที
+'createaccount-text' => 'มีà¸\9aาà¸\87à¸\84à¸\99สรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีà¹\82à¸\94ยà¹\83à¸\8aà¹\89à¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\82อà¸\87à¸\84ุà¸\93à¸\9aà¸\99 {{SITENAME}} ($4) à¹\82à¸\94ยà¹\83à¸\8aà¹\89à¸\8aืà¹\88อ "$2" และรหัสผ่าน "$3" คุณควรล็อกอินเพื่อเปลี่ยนรหัสผ่านทันที
 
 คุณอาจเพิกเฉยข้อความนี้ หากการสร้างบัญชีนี้เกิดจากความผิดพลาด',
-'usernamehasherror' => 'à¹\83à¸\99à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\95à¹\89อà¸\87à¹\84มà¹\88มีà¸\95ัวอัà¸\81ษร "#"',
-'login-throttled' => 'à¸\84ุà¸\93à¹\84à¸\94à¹\89พยายามล็อกอินมากครั้งเกินไป
+'usernamehasherror' => 'à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\95à¹\89อà¸\87à¹\84มà¹\88มีอัà¸\81à¸\82ระà¹\81ฮà¸\8a',
+'login-throttled' => 'à¸\97ีà¹\88à¸\9cà¹\88าà¸\99มาà¸\84ุà¸\93พยายามล็อกอินมากครั้งเกินไป
 กรุณารอสักครู่แล้วลองใหม่อีกครั้ง',
 'login-abort-generic' => 'การเข้าสู่ระบบของคุณไม่ประสบความสำเร็จ - ล้มเลิกแล้ว',
 'loginlanguagelabel' => 'ภาษา: $1',
-'suspicious-userlogout' => 'à¸\84ำà¸\82อà¸\82อà¸\87à¸\84ุà¸\93à¹\80à¸\9eืà¹\88อออà¸\81à¸\88าà¸\81ระà¸\9aà¸\9aà¸\96ูà¸\81à¸\9bà¸\8fิà¹\80สà¸\98 à¹\80à¸\9eราะà¸\94ูà¹\80หมือà¸\99วà¹\88าà¸\88ะสà¹\88à¸\87มาà¸\88าà¸\81à¹\80à¸\9aราวà¹\8cà¹\80à¸\8bอรà¹\8cหรือà¸\9eรà¹\87อà¸\81à¸\8bีà¹\88แคชที่เสีย',
+'suspicious-userlogout' => 'à¸\84ำà¸\82อลà¹\87อà¸\81à¹\80อาà¸\95à¹\8cà¸\82อà¸\87à¸\84ุà¸\93à¸\96ูà¸\81à¸\9bà¸\8fิà¹\80สà¸\98à¹\80à¸\9eราะà¸\94ูà¹\80หมือà¸\99สà¹\88à¸\87มาà¸\88าà¸\81à¹\80à¸\9aราวà¹\8cà¹\80à¸\8bอรà¹\8cหรือà¸\9eรà¹\87อà¸\81à¸\8bีแคชที่เสีย',
 
 # E-mail sending
-'php-mail-error-unknown' => 'ข้อผิดพลาดไม่ทราบสาเหตุในฟังก์ชัน mail() ของพีเอชพี',
+'php-mail-error-unknown' => 'à¹\80à¸\81ิà¸\94à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94à¹\84มà¹\88à¸\97ราà¸\9aสาà¹\80หà¸\95ุà¹\83à¸\99à¸\9fัà¸\87à¸\81à¹\8cà¸\8aัà¸\99 mail() à¸\82อà¸\87à¸\9eีà¹\80อà¸\8aà¸\9eี',
 'user-mail-no-addy' => 'พยายามส่งอีเมลโดยไม่มีที่อยู่อีเมล',
+'user-mail-no-body' => 'พยายามส่งอีเมลที่มีเนื้อหาว่างหรือสั้นอย่างไร้เหตุผล',
 
 # Change password dialog
 'resetpass' => 'เปลี่ยนรหัสผ่าน',
@@ -706,21 +711,35 @@ $1',
 'resetpass-submit-loggedin' => 'เปลี่ยนรหัสผ่าน',
 'resetpass-submit-cancel' => 'ยกเลิก',
 'resetpass-wrong-oldpass' => 'รหัสผ่านชั่วคราวหรือปัจจุบันไม่ถูกต้อง
-à¸\84ุà¸\93อาà¸\88à¹\80à¸\9bลีà¹\88ยà¸\99รหัสà¸\9cà¹\88าà¸\99à¸\82อà¸\87à¸\84ุà¸\93à¹\84à¸\9bà¹\81ลà¹\89ว à¸«à¸£à¸·à¸­à¸£à¹\89อà¸\87à¸\82อรหัสà¸\9cà¹\88าà¸\99à¸\8aัà¹\88วà¸\84ราวà¹\83หมà¹\88à¹\81ลà¹\89ว',
+คุณอาจเปลี่ยนรหัสผ่านของคุณไปแล้ว หรือขอรหัสผ่านชั่วคราวใหม่แล้ว',
 'resetpass-temp-password' => 'รหัสผ่านชั่วคราว:',
 
 # Special:PasswordReset
 'passwordreset' => 'ตั้งรหัสผ่านใหม่',
-'passwordreset-text' => 'à¸\81รอà¸\81à¹\81à¸\9aà¸\9aà¸\99ีà¹\89à¹\80à¸\9eืà¹\88อรัà¸\9aà¸\95ัวà¹\80à¸\95ือà¸\99อีà¹\80มลà¸\82อà¸\87รายละà¹\80อียà¸\94à¸\9aัà¸\8dà¸\8aีà¸\82อà¸\87à¸\84ุà¸\93',
+'passwordreset-text' => 'กรอกแบบนี้เพื่อรับตัวเตือนอีเมลรายละเอียดบัญชีของคุณ',
 'passwordreset-legend' => 'เปลี่ยนรหัสผ่าน',
 'passwordreset-disabled' => 'การตั้งรหัสผ่านใหม่ปิดใช้งานบนวิกินี้',
 'passwordreset-username' => 'ชื่อผู้ใช้:',
 'passwordreset-domain' => 'โดเมน:',
 'passwordreset-email' => 'ที่อยู่อีเมล:',
 'passwordreset-emailtitle' => 'รายละเอียดบัญชีบน {{SITENAME}}',
+'passwordreset-emailtext-ip' => 'ใครบางคน (ซึ่งอาจเป็นคุณ ที่ใช้เลขที่อยู่ไอพี $1) ขอตัวเตือนรายละเอียดบัญชีของคุณบน {{SITENAME}} ($4) บัญชีผู้ใช้ดังกล่าวเกี่ยวข้องกับที่อยู่อีเมลนี้:
+
+$2
+
+{{PLURAL:$3|รหัสผ่านชั่วคราวนี้|รหัสผ่านชั่วคราวเหล่านี้}}จะหมดอายุใน $5 วัน
+ตอนนี้คุณควรล็อกอินและเลือกรหัสผ่านใหม่ หากบุคคลอื่นขอตัวเตือนรายละเอียดบัญชี หรือคุณจำรหัสผ่านเดิมของคุณได้แล้ว และคุณไม่ต้องการเปลี่ยนรหัสผ่านอีกต่อไป คุณอาจละเลยข้อความนี้และใช้รหัสผ่านเก่าของคุณต่อไป',
+'passwordreset-emailtext-user' => 'ผู้ใช้ $1 ขอตัวเตือนรายละเอียดบัญชีของคุณบน {{SITENAME}} ($4) {{PLURAL:$3||}}บัญชีผู้ใช้ดังกล่าวเกี่ยวข้องกับที่อยู่อีเมลนี้:
+
+$2
+
+{{PLURAL:$3|รหัสผ่านชั่วคราวนี้|รหัสผ่านชั่วคราวเหล่านี้}}จะหมดอายุใน $5 วัน
+ตอนนี้คุณควรล็อกอินและเลือกรหัสผ่านใหม่ หากบุคคลอื่นขอตัวเตือนรายละเอียดบัญชี หรือคุณจำรหัสผ่านเดิมของคุณได้แล้ว และคุณไม่ต้องการเปลี่ยนรหัสผ่านอีกต่อไป คุณอาจละเลยข้อความนี้และใช้รหัสผ่านเก่าของคุณต่อไป',
 'passwordreset-emailelement' => 'ชื่อผู้ใช้: $1
 รหัสผ่านชั่วคราว: $2',
 'passwordreset-emailsent' => 'อีเมลแจ้งเตือนได้ถูกส่งไปแล้ว',
+'passwordreset-emailsent-capture' => 'อีเมลแจ้งเตือนได้ถูกส่งไปแล้ว ซึ่งแสดงด้านล่าง',
+'passwordreset-emailerror-capture' => 'อีเมลแจ้งเตือนถูกสร้างขึ้นแล้ว ซึ่งแสดงข้างล่าง แต่การส่งไปยังผู้ใช้ล้มเหลว: $1',
 
 # Special:ChangeEmail
 'changeemail' => 'เปลี่ยนที่อยู่อีเมล',
@@ -730,14 +749,14 @@ $1',
 'changeemail-oldemail' => 'ที่อยู่อีเมลปัจจุบัน:',
 'changeemail-newemail' => 'ที่อยู่อีเมลใหม่:',
 'changeemail-none' => '(ไม่มี)',
-'changeemail-password' => 'รหัสผ่าน{{SITENAME}}ของคุณ:',
+'changeemail-password' => 'รหัสผ่าน {{SITENAME}} ของคุณ:',
 'changeemail-submit' => 'เปลี่ยนอีเมล',
 'changeemail-cancel' => 'ยกเลิก',
 
 # Edit page toolbar
-'bold_sample' => 'à¸\97ำตัวหนา',
+'bold_sample' => 'à¸\82à¹\89อà¸\84วามตัวหนา',
 'bold_tip' => 'ทำตัวหนา',
-'italic_sample' => 'à¸\95ัวหà¸\99ัà¸\87สือà¸\97ีà¹\88à¹\80à¸\9bà¹\87à¸\99ตัวเอน',
+'italic_sample' => 'à¸\82à¹\89อà¸\84วามตัวเอน',
 'italic_tip' => 'ทำตัวเอน',
 'link_sample' => 'ลิงก์เชื่อมโยง',
 'link_tip' => 'ลิงก์ภายในเว็บ',
@@ -745,8 +764,8 @@ $1',
 'extlink_tip' => 'ลิงก์ภายนอก (อย่าลืมใส่ http:// นำหน้าเสมอ)',
 'headline_sample' => 'หัวข้อ',
 'headline_tip' => 'หัวข้อ',
-'nowiki_sample' => 'à¹\83สà¹\88à¸\82à¹\89อà¸\84วามà¸\97ีà¹\88à¹\84มà¹\88à¸\88ัà¸\94รูà¸\9bà¹\81à¸\9aà¸\9a',
-'nowiki_tip' => 'à¸\82à¹\89ามการจัดรูปแบบวิกิ',
+'nowiki_sample' => 'à¹\81à¸\97รà¸\81à¸\82à¹\89อà¸\84วามà¸\97ีà¹\88à¹\84มà¹\88à¸\88ัà¸\94รูà¸\9bà¹\81à¸\9aà¸\9aà¸\97ีà¹\88à¸\99ีà¹\88',
+'nowiki_tip' => 'à¹\84มà¹\88สà¸\99à¹\83à¸\88การจัดรูปแบบวิกิ',
 'image_sample' => 'ตัวอย่าง.jpg',
 'image_tip' => 'ใส่ไฟล์',
 'media_sample' => 'ตัวอย่าง.ogg',
@@ -764,47 +783,45 @@ $1',
 'showpreview' => 'แสดงตัวอย่าง',
 'showlivepreview' => 'แสดงตัวอย่างทันที',
 'showdiff' => 'แสดงความเปลี่ยนแปลง',
-'anoneditwarning' => "'''คำเตือน:''' คุณมิได้ล็อกอิน ที่อยู่ไอพีของคุณจะถูกบันทึกไว้ในประวัติการแก้ไขของหน้านี้",
-'anonpreviewwarning' => "'''คุณมิได้ล็อกอิน การบันทึกจะเก็บที่อยู่ไอพีของคุณในประวัติการแก้ไขของหน้านี้'''",
-'missingsummary' => "'''อย่าลืม:''' คุณยังไม่ได้ระบุคำอธิบายการแก้ไขครั้งนี้ ถ้าคุณกดบันทึกไปส่วนคำอธิบายการแก้ไขนั้นจะว่างและไม่แสดงผล",
+'anoneditwarning' => "'''à¸\84ำà¹\80à¸\95ือà¸\99:''' à¸\84ุà¸\93มิà¹\84à¸\94à¹\89ลà¹\87อà¸\81อิà¸\99 à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¸\82อà¸\87à¸\84ุà¸\93à¸\88ะà¸\96ูà¸\81à¸\9aัà¸\99à¸\97ึà¸\81à¹\84วà¹\89à¹\83à¸\99à¸\9bระวัà¸\95ิà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89",
+'anonpreviewwarning' => "'''à¸\84ุà¸\93มิà¹\84à¸\94à¹\89ลà¹\87อà¸\81อิà¸\99 à¸\81ารà¸\9aัà¸\99à¸\97ึà¸\81à¸\88ะà¹\80à¸\81à¹\87à¸\9aà¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¸\82อà¸\87à¸\84ุà¸\93à¹\83à¸\99à¸\9bระวัà¸\95ิà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89'''",
+'missingsummary' => "'''อย่าลืม:''' คุณยังไม่ได้ระบุคำอธิบายการแก้ไข ถ้าคุณกด \"บันทึก\" อีกครั้ง การแก้ไขของคุณจะถูกบันทึกโดยไม่มีคำอธิบายการแก้ไข",
 'missingcommenttext' => 'กรุณาใส่ความเห็นด้านล่าง',
 'missingcommentheader' => "'''ประกาศเตือน:''' คุณยังไม่ได้ใส่หัวข้อ/จ่าหัวสำหรับความเห็นนี้ ถ้าคุณกด \"{{int:savearticle}}\" อีกครั้ง การแก้ไขของคุณจะถูกบันทึกโดยไม่มีหัวข้อ",
 'summary-preview' => 'ตัวอย่างคำอธิบายการแก้ไข:',
 'subject-preview' => 'ตัวอย่างหัวข้อ:',
-'blockedtitle' => 'ผู้ใช้ถูกบล็อก',
-'blockedtext' => "'''à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหมายà¹\80ลà¸\82à¹\84อà¸\9eีà¸\96ูà¸\81ของคุณถูกบล็อก'''
+'blockedtitle' => 'ผู้ใช้ถูกบล็อกอยู่',
+'blockedtext' => "'''à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือà¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีของคุณถูกบล็อก'''
 
-$1 เป็นผู้ดำเนินการบล็อก 
¹\82à¸\94ยà¹\83หà¹\89เหตุผลว่า ''$2''
+การบล็อกนี้ดำเนินการโดย $1
¸\8bึà¹\88à¸\87ระà¸\9aุเหตุผลว่า ''$2''
 
 * เริ่มการบล็อก: $8
 * หมดเขตการบล็อก: $6
 * ผู้ถูกบล็อก: $7
 
-คุณสามารถติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่อหารือเกี่ยวกับการบล็อกนี้ 
-คุณไม่สามารถใช้คุณลักษณะ 'ส่งอีเมลหาผู้ใช้รายนี้ได้' จนกว่าจะระบุที่อยู่อีเมลที่ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกบล็อกมิให้ใช้
+คุณสามารถติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่ออภิปรายการบล็อกนี้ได้
+คุณไม่สามารถใช้คุณลักษณะ 'ส่งอีเมลหาผู้ใช้รายนี้ได้' จนกว่าจะระบุที่อยู่อีเมลให้ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกบล็อกไม่ให้ใช้ความสามารถนี้
+เลขที่อยู่ไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 
+โปรดแสดงรายละเอียดข้างต้นทั้งหมดนี้ในการอภิปรายเกี่ยวกับการบล็อกของคุณด้วย",
+'autoblockedtext' => "เลขที่อยู่ไอพีของคุณถูกบล็อกอัตโนมัติ เพราะมีผู้ใช้อื่นใช้มาก่อน ซึ่งถูกบล็อกโดย $1
+โดยระบุเหตุผลว่า
 
-หมายเลขไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 กรุณาระบุหมายเลขเหล่านี้ในการติดต่อใด ๆ",
-'autoblockedtext' => 'หมายเลขไอพีของคุณถูกบล็อกโดยอัตโนมัติ เนื่องจากมีผู้ใช้อื่นใช้งานผ่านหมายเลขไอพีนี้มาก่อน ซึ่งถูกบล็อกโดย $1
-เหตุผลที่ให้ไว้ในการบล็อกคือ:
-
-:\'\'$2\'\'
+:''$2''
 
 * เริ่มการบล็อก: $8
 * สิ้นสุดการบล็อก: $6
-* ผู้ถูกบล็อกโดยเจตนา: $7
-
-คุณอาจติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่อหารือเกี่ยวกับการบล็อกนี้
-
-โปรดทราบว่าคุณอาจไม่สามารถใช้คำสั่ง "อีเมลหาผู้ใช้นี้" หากคุณไม่มีที่อยู่อีเมลที่ถูกต้อง ดังที่ลงทะเบียนไว้ใน[[Special:Preferences|การตั้งค่าผู้ใช้]] และไม่ถูกบล็อกจากการใช้คำสั่งนี้
+* ผู้ถูกบล็อก: $7
 
-หมายเลขไอพีปัจจุบันของคุณคือ $3 หมายเลขการบล็อกคือ #$5
-กรุณาระบุรายละเอียดทั้งหมดข้างต้นในการร้องขอใดๆ ที่คุณกระทำ',
+คุณสามารถติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่อหารือการบล็อกนี้ 
+คุณไม่สามารถใช้คุณลักษณะ 'ส่งอีเมลหาผู้ใช้รายนี้ได้' จนกว่าจะระบุที่อยู่อีเมลที่ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกบล็อกไม่ให้ใช้
+เลขที่อยู่ไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 
+โปรดรวมรายละเอียดข้างต้นทั้งหมดในการสอบถามใด ๆ",
 'blockednoreason' => 'ไม่ได้ให้เหตุผลไว้',
-'whitelistedittext' => 'à¸\84ุà¸\93à¸\95à¹\89อà¸\87$1à¹\80à¸\9eืà¹\88อà¸\97ำà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89า',
+'whitelistedittext' => 'คุณต้อง$1เพื่อแก้ไขหน้า',
 'confirmedittext' => 'คุณต้องยืนยันที่อยู่อีเมลของคุณก่อนแก้ไขหน้า โปรดกำหนดที่อยู่อีเมลของคุณและทำให้ถูกต้องผ่าน[[Special:Preferences|การตั้งค่าผู้ใช้]]',
-'nosuchsectiontitle' => 'à¹\84มà¹\88à¸\9eà¸\9aหัวà¸\82à¹\89อยà¹\88อย',
-'nosuchsectiontext' => 'à¸\84ุà¸\93à¸\9eยายามà¹\81à¸\81à¹\89à¹\84à¸\82à¸\95อà¸\99à¸\97ีà¹\88à¹\84มà¹\88มีอยูà¹\88 à¸\95อนดังกล่าวอาจถูกย้ายหรือลบขณะที่คุณดูหน้าอยู่',
+'nosuchsectiontitle' => 'à¹\84มà¹\88à¸\9eà¸\9aสà¹\88วà¸\99',
+'nosuchsectiontext' => 'à¸\84ุà¸\93à¸\9eยายามà¹\81à¸\81à¹\89à¹\84à¸\82สà¹\88วà¸\99à¸\97ีà¹\88à¹\84มà¹\88มีอยูà¹\88 à¸ªà¹\88วนดังกล่าวอาจถูกย้ายหรือลบขณะที่คุณดูหน้าอยู่',
 'loginreqtitle' => 'จำเป็นต้องล็อกอิน',
 'loginreqlink' => 'ล็อกอิน',
 'loginreqpagetext' => 'คุณต้อง$1เพื่อดูหน้าอื่น',
@@ -815,58 +832,60 @@ $1 เป็นผู้ดำเนินการบล็อก
 'newarticle' => '(ใหม่)',
 'newarticletext' => "คุณตามลิงก์ไปยังหน้าที่ยังไม่มีในขณะนี้
 ในการสร้างหน้า เริ่มพิมพ์ในกล่องด้านล่าง (ดูข้อมูลเพิ่มเติมใน[[{{MediaWiki:Helppage}}|หน้าคำอธิบาย]])
-à¸\96à¹\89าà¸\84ุà¸\93มาà¹\82à¸\94ยอุà¸\9aัà¸\95ิà¹\80หà¸\95ุ à¹\83หà¹\89à¸\81à¸\94'''à¸\96อยหลัà¸\87''' (back) à¸\97ีà¹\88เบราว์เซอร์",
-'anontalkpagetext' => "----''หà¸\99à¹\89าà¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยสำหรัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ิรà¸\99าม à¸\8bึà¹\88à¸\87ยัà¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89สรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89
¹\82à¸\94ยà¸\97าà¸\87à¹\80ราà¸\88ำà¹\80à¸\9bà¹\87à¸\99à¸\95à¹\89อà¸\87ระà¸\9aุà¸\95ัวà¸\95à¸\99à¸\9cà¹\88าà¸\99à¸\97าà¸\87หมายà¹\80ลà¸\82à¹\84อà¸\9eี
¸\8bึà¹\88à¸\87หมายà¹\80ลà¸\82à¹\84อà¸\9eีà¸\99ีà¹\89อาà¸\88à¸\96ูà¸\81à¹\83à¸\8aà¹\89รà¹\88วมà¸\81ัà¸\99à¹\82à¸\94ยà¸\9cูà¹\89à¹\83à¸\8aà¹\89หลายคน
+à¸\96à¹\89าà¸\84ุà¸\93à¹\80à¸\82à¹\89ามาหà¸\99à¹\89าà¸\99ีà¹\89à¹\82à¸\94ยà¸\9cิà¸\94à¸\9eลาà¸\94 à¹\83หà¹\89à¸\81à¸\94à¸\9bุà¹\88ม'''à¸\96อยหลัà¸\87''' (back) à¸\82อà¸\87เบราว์เซอร์",
+'anontalkpagetext' => "----''หà¸\99à¹\89าà¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99หà¸\99à¹\89าà¸\84ุยà¸\81ัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89สำหรัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ิรà¸\99ามà¸\8bึà¹\88à¸\87ยัà¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89สรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีหรือà¹\84มà¹\88à¹\84à¸\94à¹\89ลà¹\87อà¸\81อิà¸\99
¸\94ัà¸\87à¸\99ัà¹\89à¸\99à¹\80ราà¸\88ึà¸\87ระà¸\9aุà¸\95ัวà¸\95à¸\99à¹\82à¸\94ยà¹\83à¸\8aà¹\89à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¹\81à¸\97à¸\99
¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¸\99ีà¹\89อาà¸\88มีà¸\9cูà¹\89à¹\83à¸\8aà¹\89รà¹\88วมà¸\81ัà¸\99หลายคน
 ถ้าคุณเป็นผู้ใช้นิรนาม และรู้สึกว่าความเห็นที่คุณได้รับไม่เกี่ยวข้องกับคุณแต่อย่างใด กรุณา[[Special:UserLogin/signup|สร้างบัญชีผู้ใช้]]หรือ[[Special:UserLogin|ล็อกอิน]] เพื่อป้องกันการสับสนกับผู้ใช้นิรนามรายอื่น''",
-'noarticletext' => 'ขณะนี้ไม่มีเนื้อหาในหน้านี้
-คุณสามารถ [[Special:Search/{{PAGENAME}}|ค้นหาชื่อหน้านี้]]ในหน้าอื่น
-<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ค้นหาปูมที่เกี่ยวข้อง] หรือ[{{fullurl:{{FULLPAGENAME}}|action=edit}} แก้ไขหน้านี้]</span>',
-'noarticletext-nopermission' => 'ปัจจุบันไม่มีข้อความในหน้านี้
-คุณสามารถ[[Special:Search/{{PAGENAME}}|ค้นหาชื่อบทความนี้]]ในหน้าอื่น หรือ<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ค้นหาปูมที่เกี่ยวข้อง]</span> แต่คุณไม่มีสิทธิ์สร้างหน้านี้',
+'noarticletext' => 'ปัจจุบันไม่มีเนื้อหาในหน้านี้
+คุณสามารถ[[Special:Search/{{PAGENAME}}|ค้นหาชื่อหน้านี้]]ในหน้าอื่น หรือ<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ค้นหาปูมที่เกี่ยวข้อง] หรือ[{{fullurl:{{FULLPAGENAME}}|action=edit}} แก้ไขหน้านี้]</span>',
+'noarticletext-nopermission' => 'ปัจจุบันไม่มีเนื้อหาในหน้านี้
+คุณสามารถ[[Special:Search/{{PAGENAME}}|ค้นหาชื่อหน้านี้]]ในหน้าอื่น หรือ<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ค้นหาปูมที่เกี่ยวข้อง]</span> แต่คุณไม่มีสิทธิสร้างหน้านี้',
+'missing-revision' => 'ไม่มีรุ่น #$1 ของหน้าชื่อ "{{PAGENAME}}" 
+
+โดยปกติเกิดจากการเข้าลิงก์ประวัติเก่าของหน้าที่ถูกลบไปแล้ว
+ดูรายละเอียดได้ที่[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]',
 'userpage-userdoesnotexist' => 'บัญชีผู้ใช้ "<nowiki>$1</nowiki>" มิได้ลงทะเบียน กรุณาตรวจสอบก่อนว่าคุณต้องการสร้างหรือแก้ไขหน้านี้',
 'userpage-userdoesnotexist-view' => 'บัญชีผู้ใช้ "$1" มิได้ลงทะเบียน',
 'blocked-notice-logextract' => 'ปัจจุบันเลขที่อยู่ไอพีนี้ถูกบล็อก
-รายการบล็อกล่าสุดแสดงด้านล่างนี้เพื่อการอ้างอิง:',
-'clearyourcache' => "'''หมายเหตุ:''' หลังจากบันทึกแล้ว คุณอาจจะต้องล้างแคชเว็บเบราว์เซอร์ของคุณเพื่อดูการเปลี่ยนแปลง
-* '''ไฟร์ฟอกซ์ / ซาฟารี:''' กดปุ่ม ''Shift'' ค้างไว้ขณะคลิก ''Reload'' หรือกดปุ่ม ''Ctrl-F5'' หรือ ''Ctrl-R'' (''⌘-R'' บนแมคอินทอช)
-* '''กูเกิล โครม:''' กดปุ่ม ''Ctrl-Shift-R'' (''⌘-Shift-R'' บนแมคอินทอช)
-* '''อินเทอร์เน็ตเอกซ์พลอเรอร์:''' กดปุ่ม ''Ctrl'' ค้างไว้ขณะคลิก ''Refresh'' หรือกดปุ่ม ''Ctrl-F5''
-* '''คองเคอเรอร์:''' คลิก ''Reload'' หรือกดปุ่ม ''F5''
-* '''โอเปร่า:''' ล้างแคชในเมนู ''Tools → Preferences''",
-'usercssyoucanpreview' => "'''คำแนะนำ:''' กดปุ่ม \"{{int:showpreview}}\" เพื่อทดสอบสไตล์ชีท CSS ก่อนบันทึก",
-'userjsyoucanpreview' => "'''คำแนะนำ:''' กดปุ่ม \"แสดงตัวอย่าง\" เพื่อทดสอบจาวาสคริปต์ใหม่ก่อนบันทึก",
+หน่วยบล็อกล่าสุดแสดงด้านล่างนี้เพื่อการอ้างอิง:',
+'clearyourcache' => "'''หมายเหตุ:''' หลังจากบันทึก คุณอาจต้องล้างแคชเว็บเบราว์เซอร์ของคุณเพื่อดูการเปลี่ยนแปลง
+* '''ไฟร์ฟอกซ์ / ซาฟารี:''' กดปุ่ม ''Shift'' ค้างไว้ขณะคลิก ''Reload'' หรือกด ''Ctrl-F5'' หรือ ''Ctrl-R'' (''⌘-R'' บนแมค)
+* '''กูเกิล โครม:''' กดปุ่ม ''Ctrl-Shift-R'' (''⌘-Shift-R'' บนแมค)
+* '''อินเทอร์เน็ตเอกซ์พลอเรอร์:''' กดปุ่ม ''Ctrl'' ค้างไว้ขณะคลิก ''Refresh'' หรือกด ''Ctrl-F5''
+* '''โอเปร่า:''' ล้างแคชใน ''Tools → Preferences''",
+'usercssyoucanpreview' => "'''คำแนะนำ:''' กดปุ่ม \"{{int:showpreview}}\" เพื่อทดสอบ CSS ใหม่ของคุณก่อนบันทึก",
+'userjsyoucanpreview' => "'''คำแนะนำ:''' กดปุ่ม \"{{int:showpreview}}\" เพื่อทดสอบจาวาสคริปต์ใหม่ของคุณก่อนบันทึก",
 'usercsspreview' => "'''อย่าลืมว่าคุณกำลังดูตัวอย่าง CSS ผู้ใช้ของคุณ'''
 '''ยังไม่ได้ถูกบันทึก!'''",
 'userjspreview' => "'''อย่าลืมว่าคุณกำลังทดสอบ/ดูตัวอย่างจาวาสคริปต์ผู้ใช้ของคุณ'''
 '''ยังไม่ถูกบันทึก!'''",
 'sitecsspreview' => "'''พึงระลึกว่าคุณกำลังแสดงตัวอย่าง CSS นี้เท่านั้น'''
-'''มัà¸\99ยัà¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\9aัà¸\99à¸\97ึà¸\81!'''",
+'''ยังไม่ได้ถูกบันทึก!'''",
 'sitejspreview' => "'''พึงระลึกว่าคุณกำลังแสดงตัวอย่างโค้ดจาวาสคริปต์นี้เท่านั้น'''
-'''มัà¸\99ยัà¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\9aัà¸\99à¸\97ึà¸\81!'''",
-'userinvalidcssjstitle' => "'''à¸\84ำà¹\80à¸\95ือà¸\99:''' à¹\84มà¹\88มีหà¸\99à¹\89าà¸\95า \"\$1\" à¸«à¸\99à¹\89า .css à¹\81ละ .js à¸\97ีà¹\88à¸\9bรัà¸\9aà¹\81à¸\95à¹\88à¸\87à¹\80อà¸\87 à¹\83à¸\8aà¹\89à¸\95ัวà¸\9eิมà¸\9eà¹\8cà¹\80ลà¹\87à¸\81à¸\97ัà¹\89à¸\87หมà¸\94 à¹\80à¸\8aà¹\88à¸\99 à¹\83à¸\8aà¹\89 {{ns:user}}:Foo/vector.css à¹\81à¸\97à¸\99à¸\97ีà¹\88à¸\88ะà¹\80à¸\9bà¹\87à¸\99 {{ns:user}}:Foo/Vector.css",
-'updated' => '(à¸\9bรัà¸\9aà¸\9bรุà¸\87à¹\81ลà¹\89ว)',
-'note' => "'''à¸\84ำà¹\81à¸\99ะà¸\99ำ:'''",
-'previewnote' => "'''พึงระลึกว่านี่เป็นเพียงตัวอย่างเท่านั้น'''
+'''ยังไม่ได้ถูกบันทึก!'''",
+'userinvalidcssjstitle' => "'''à¸\84ำà¹\80à¸\95ือà¸\99:''' à¹\84มà¹\88มีหà¸\99à¹\89าà¸\95า \"\$1\" à¸«à¸\99à¹\89า .css à¹\81ละ .js à¸\97ีà¹\88à¸\9bรัà¸\9aà¹\81à¸\95à¹\88à¸\87à¹\80อà¸\87 à¹\83à¸\8aà¹\89à¸\95ัวà¹\80ลà¹\87à¸\81à¸\97ัà¹\89à¸\87หมà¸\94 à¹\80à¸\8aà¹\88à¸\99 {{ns:user}}:Foo/vector.css à¸¡à¸´à¹\83à¸\8aà¹\88 {{ns:user}}:Foo/Vector.css",
+'updated' => '(ปรับแล้ว)',
+'note' => "'''หมายà¹\80หà¸\95ุ:'''",
+'previewnote' => "'''à¸\9eึà¸\87ระลึà¸\81วà¹\88าà¸\99ีà¹\88à¹\80à¸\9bà¹\87à¸\99à¹\80à¸\9eียà¸\87à¸\81ารà¹\81สà¸\94à¸\87à¸\95ัวอยà¹\88าà¸\87à¹\80à¸\97à¹\88าà¸\99ัà¹\89à¸\99'''
 การเปลี่ยนแปลงของคุณยังไม่ได้ถูกบันทึก!",
 'continue-editing' => 'ไปยังพื้นที่แก้ไข',
-'previewconflict' => 'à¸\81ารà¹\81สà¸\94à¸\87à¸\9cลสà¹\88วà¸\99à¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99à¸\95ัวอยà¹\88าà¸\87à¸\82อà¸\87à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\94à¹\89าà¸\99à¸\9aà¸\99  à¸\96à¹\89าà¸\81à¸\94à¸\9aัà¸\99à¸\97ึà¸\81à¸\81ารà¹\81สà¸\94à¸\87à¸\9cลà¸\88ะà¹\81สà¸\94à¸\87à¹\83à¸\99ลัà¸\81ษà¸\93ะà¸\99ีà¹\89à¸\97ัà¸\99à¸\97ี',
-'session_fail_preview' => "'''à¸\82ออภัย à¹\84มà¹\88สามารà¸\96à¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\95à¹\88อà¹\84à¸\94à¹\89 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\82à¹\89อมูลà¹\80à¸\8aืà¹\88อมà¸\95à¹\88อสูà¸\8dหาย
-à¹\83หà¹\89à¸\97à¸\94ลอà¸\87à¹\81à¸\81à¹\89à¹\84à¸\82อีà¸\81à¸\84รัà¹\89à¸\87หà¸\99ึà¹\88à¸\87 à¸\96à¹\89ายัà¸\87à¹\84มà¹\88สามารà¸\96à¸\97ำà¹\84à¸\94à¹\89 à¹\83หà¹\89ลอà¸\87ลà¹\87อà¸\81à¹\80อาà¸\95à¹\8cà¹\81ละลà¹\87อà¸\81อิà¸\99à¸\81ลัà¸\9aมาอีà¸\81à¸\84รัà¹\89à¸\87'''",
-'session_fail_preview_html' => "'''à¸\82ออภัย à¹\84มà¹\88สามารà¸\96à¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\95à¹\88อà¹\84à¸\94à¹\89 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\82à¹\89อมูลà¹\80à¸\8aืà¹\88อมà¸\95à¹\88อสูญหาย'''
+'previewconflict' => 'à¸\81ารà¹\81สà¸\94à¸\87à¸\95ัวอยà¹\88าà¸\87à¸\99ีà¹\89สะà¸\97à¹\89อà¸\99à¸\82à¹\89อà¸\84วามà¹\83à¸\99à¸\9eืà¹\89à¸\99à¸\97ีà¹\88à¹\81à¸\81à¹\89à¹\84à¸\82à¸\82à¹\89อà¸\84วามสà¹\88วà¸\99à¸\9aà¸\99à¸\8bึà¹\88à¸\87à¸\88ะà¸\9bราà¸\81à¸\8fหาà¸\81à¸\84ุà¸\93à¹\80ลือà¸\81à¸\9aัà¸\99à¸\97ึà¸\81',
+'session_fail_preview' => "'''à¸\82ออภัย à¹\84มà¹\88สามารà¸\96à¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\95à¹\88อà¹\84à¸\94à¹\89 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\82à¹\89อมูลà¸\8aà¹\88วà¸\87à¹\80วลาสืà¹\88อสารสูà¸\8dหาย'''
+à¹\82à¸\9bรà¸\94à¸\97à¸\94ลอà¸\87อีà¸\81à¸\84รัà¹\89à¸\87 à¸«à¸²à¸\81ยัà¸\87à¹\80สียอยูà¹\88 à¸¥à¸­à¸\87[[Special:UserLogout|ลà¹\87อà¸\81à¹\80อาà¸\95à¹\8c]]à¹\81ละลà¹\87อà¸\81อิà¸\99à¸\81ลัà¸\9aมา",
+'session_fail_preview_html' => "'''à¸\82ออภัย à¹\84มà¹\88สามารà¸\96à¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\95à¹\88อà¹\84à¸\94à¹\89 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\82à¹\89อมูลà¸\8aà¹\88วà¸\87à¹\80วลาสืà¹\88อสารสูญหาย'''
 
-''à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81 {{SITENAME}} à¹\83à¸\8aà¹\89รูà¸\9bà¹\81à¸\9aà¸\9aà¹\80อà¸\8aà¸\97ีà¹\80อà¹\87มà¹\81อลลà¹\89วà¸\99 à¸\81ารà¹\81สà¸\94à¸\87à¸\95ัวอยà¹\88าà¸\87à¸\88ะà¸\96ูà¸\81à¸\8bà¹\88อà¸\99à¹\84วà¹\89à¹\80à¸\9eืà¹\88อà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\81ารà¹\82à¸\95มตีด้วยจาวาสคริปต์''
+''à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81 {{SITENAME}} à¹\80à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99à¹\80อà¸\8aà¸\97ีà¹\80อà¹\87มà¹\81อลลà¹\89วà¸\99 à¸\81ารà¹\81สà¸\94à¸\87à¸\95ัวอยà¹\88าà¸\87à¸\88ะà¸\96ูà¸\81à¸\8bà¹\88อà¸\99à¹\84วà¹\89à¹\80à¸\9eืà¹\88อà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\81ารà¹\82à¸\88มตีด้วยจาวาสคริปต์''
 
-'''à¸\96à¹\89าà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\84รัà¹\89à¸\87à¸\99ีà¹\89à¸\96ูà¸\81à¸\95à¹\89อà¸\87 à¹\83หà¹\89à¸\97à¸\94ลอà¸\87à¹\81à¸\81à¹\89à¹\84à¸\82อีà¸\81à¸\84รัà¹\89à¸\87หà¸\99ึà¹\88à¸\87 à¸\96à¹\89ายัà¸\87à¹\84มà¹\88สามารà¸\96à¸\97ำà¹\84à¸\94à¹\89 à¹\83หà¹\89ลอà¸\87[[Special:UserLogout|ลà¹\87อà¸\81à¹\80อาà¸\95à¹\8c]]à¹\81ละลà¹\87อà¸\81อิà¸\99à¸\81ลัà¸\9aมาอีà¸\81à¸\84รัà¹\89à¸\87'''",
-'token_suffix_mismatch' => "'''à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\84ุà¸\93à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\9bà¸\8fิà¹\80สà¸\98 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¹\80à¸\84รืà¹\88อà¸\87ลูà¸\81à¸\82à¹\88ายà¸\97ีà¹\88à¸\84ุà¸\93à¹\83à¸\8aà¹\89อยูà¹\88à¹\84à¸\94à¹\89à¸\97ำลายรูà¸\9bà¹\81à¸\9aà¸\9aà¹\80à¸\84รืà¹\88อà¸\87หมายวรรà¸\84à¸\95อà¸\99à¹\83à¸\99à¸\95ราสารà¸\9bระà¸\88ำà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82 (edit token)'''
-ระà¸\9aà¸\9aà¹\84มà¹\88รัà¸\9aà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\84ุà¸\93à¹\80à¸\9eืà¹\88อà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\84วามà¸\9cิà¸\94à¸\9eลาà¸\94à¸\82อà¸\87à¸\82à¹\89อมูล
¹\83à¸\99à¸\9aาà¸\87à¸\84รัà¹\89à¸\87à¸\9bัà¸\8dหาà¸\99ีà¹\89à¸\88ะà¹\80à¸\81ิà¸\94à¸\82ึà¹\89à¸\99à¸\96à¹\89าคุณใช้บริการเว็บพร็อกซีนิรนามที่มีบั๊ก",
+'''หาà¸\81à¸\99ีà¹\88à¹\80à¸\9bà¹\87à¸\99à¸\84วามà¸\9eยายามà¹\81à¸\81à¹\89à¹\84à¸\82à¹\82à¸\94ยà¸\8aอà¸\9a à¹\82à¸\9bรà¸\94ลอà¸\87อีà¸\81à¸\84รัà¹\89à¸\87หà¸\99ึà¹\88à¸\87''' à¸«à¸²à¸\81ยัà¸\87à¹\80สียอยูà¹\88 à¸¥à¸­à¸\87[[Special:UserLogout|ลà¹\87อà¸\81à¹\80อาà¸\95à¹\8c]]à¹\81ละลà¹\87อà¸\81อิà¸\99à¸\81ลัà¸\9aมา",
+'token_suffix_mismatch' => "'''à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\84ุà¸\93à¸\96ูà¸\81à¸\9bà¸\8fิà¹\80สà¸\98 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¹\80à¸\84รืà¹\88อà¸\87ลูà¸\81à¸\82à¹\88ายà¸\97ีà¹\88à¸\84ุà¸\93à¹\83à¸\8aà¹\89à¸\97ำà¹\83หà¹\89อัà¸\81à¸\82ระà¹\80à¸\84รืà¹\88อà¸\87หมายวรรà¸\84à¸\95อà¸\99à¹\83à¸\99à¸\95ราสารà¸\9bระà¸\88ำà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82 (edit token) à¹\80สีย'''
+à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\99ีà¹\89à¸\96ูà¸\81à¸\9bà¸\8fิà¹\80สà¸\98à¹\80à¸\9eืà¹\88อà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\81ารวิà¸\9aัà¸\95ิà¸\82อà¸\87à¸\82à¹\89อà¸\84วามหà¸\99à¹\89า
¸\9aาà¸\87à¸\84รัà¹\89à¸\87à¹\80à¸\81ิà¸\94à¸\9bัà¸\8dหาà¸\99ีà¹\89à¸\82ึà¹\89à¸\99à¹\80มืà¹\88อคุณใช้บริการเว็บพร็อกซีนิรนามที่มีบั๊ก",
 'edit_form_incomplete' => "'''แบบแก้ไขบางส่วนไปไม่ถึงเซิร์ฟเวอร์ ตรวจสอบอีกครั้งว่าการแก้ไขของคุณยังอยู่และลองอีกครั้ง'''",
 'editing' => 'กำลังแก้ไข $1',
 'creating' => 'กำลังสร้าง $1',
 'editingsection' => 'กำลังแก้ไข $1 (เฉพาะส่วน)',
-'editingcomment' => 'à¸\81ำลัà¸\87à¹\81à¸\81à¹\89à¹\84à¸\82 $1 (à¸\95อนใหม่)',
+'editingcomment' => 'à¸\81ำลัà¸\87à¹\81à¸\81à¹\89à¹\84à¸\82 $1 (สà¹\88วนใหม่)',
 'editconflict' => 'แก้ไขชนกัน: $1',
 'explainconflict' => "ใครบางคนได้เปลี่ยนแปลงหน้านี้ตั้งแต่คุณกำลังแก้ไข
 พื้นที่ข้อความส่วนบนมีข้อความหน้าที่มีอยู่ในปัจจุบัน
@@ -888,7 +907,8 @@ $1 เป็นผู้ดำเนินการบล็อก
 '''อย่าส่งงานที่มีลิขสิทธิ์เข้ามาก่อนได้รับอนุญาตจากเจ้าของ!'''",
 'longpageerror' => "'''ผิดพลาด: ข้อความที่คุณส่งเข้ามามีขนาด $1 กิโลไบต์
 ซึ่งเกินกว่าขนาดที่กำหนดไว้ที่ $2 กิโลไบต์ จึงไม่สามารถบันทึกได้'''",
-'readonlywarning' => "'''คำเตือน: ขณะนี้ฐานข้อมูลถูกล็อกเพื่อบำรุงรักษา จึงไม่สามารถบันทึกข้อมูลที่แก้ไขได้ แนะนำให้คัดลอกไปเก็บไว้ที่อื่นก่อนแล้วนำมาบันทึกในเว็บไซต์นี้ภายหลัง'''
+'readonlywarning' => "'''คำเตือน: ฐานข้อมูลถูกล็อกเพื่อบำรุงรักษา ฉะนั้นคุณจึงไม่สามารถบันทึกการเปลี่ยนแปลงของคุณได้ในขณะนี้'''
+คุณอาจต้องการคัดลอกและวางข้อความของคุณในไฟล์ข้อความ และบันทึกไว้ใช้ภายหลัง
 
 ผู้ดูแลระบบที่ล็อกฐานข้อมูลได้ให้คำอธิบายดังนี้: $1",
 'protectedpagewarning' => "'''คำเตือน: หน้านี้ถูกล็อก และแก้ไขได้เฉพาะผู้ใช้ที่มีสิทธิผู้ดูแลระบบเท่านั้น'''
@@ -930,6 +950,12 @@ $1 เป็นผู้ดำเนินการบล็อก
 เพราะมีหน้านี้แล้ว',
 'defaultmessagetext' => 'ข้อความสารโดยปริยาย',
 
+# Content models
+'content-model-wikitext' => 'ข้อความวิกิ',
+'content-model-text' => 'ข้อความธรรมดา',
+'content-model-javascript' => 'จาวาสคริปต์',
+'content-model-css' => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''คำเตือน:''' หน้านี้มีการเรียกใช้ฟังก์ชันแจงส่วนมากเกินไป
 
@@ -992,41 +1018,41 @@ $1 เป็นผู้ดำเนินการบล็อก
 'rev-deleted-comment' => '(คำอธิบายอย่างย่อถูกลบออก)',
 'rev-deleted-user' => '(ชื่อผู้ใช้ถูกลบออก)',
 'rev-deleted-event' => '(ปฏิบัติการปูมถูกลบออก)',
-'rev-deleted-user-contribs' => '[à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหมายà¹\80ลà¸\82ไอพีถูกลบแล้ว - การแก้ไขถูกซ่อนจากรายการแก้ไข]',
-'rev-deleted-text-permission' => "รุà¹\88à¸\99à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89'''à¸\96ูà¸\81ลà¸\9a'''
+'rev-deleted-user-contribs' => '[à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือà¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีถูกลบแล้ว - การแก้ไขถูกซ่อนจากรายการแก้ไข]',
+'rev-deleted-text-permission' => "รุ่นหน้านี้'''ถูกลบ'''
 รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]",
-'rev-deleted-text-unhide' => "รุà¹\88à¸\99à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89'''à¸\96ูà¸\81ลà¸\9a'''
+'rev-deleted-text-unhide' => "รุ่นหน้านี้'''ถูกลบ'''
 รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]
 คุณยังสามารถ[$1 ดูรุ่นนี้]ได้ถ้าคุณต้องการดำเนินต่อ",
-'rev-suppressed-text-unhide' => "รุà¹\88à¸\99à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89'''à¸\96ูà¸\81ยัà¸\9aยัà¹\89à¸\87'''
+'rev-suppressed-text-unhide' => "รุ่นหน้านี้'''ถูกยับยั้ง'''
 รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ปูมการยับยั้ง]
 คุณยังสามารถ[$1 ดูรุ่นนี้]ได้ถ้าคุณต้องการดำเนินต่อ",
-'rev-deleted-text-view' => "รุà¹\88à¸\99à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89'''à¸\96ูà¸\81ลà¸\9a'''
+'rev-deleted-text-view' => "รุ่นหน้านี้'''ถูกลบ'''
 คุณสามารถดูรุ่นนี้ได้ รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]",
-'rev-suppressed-text-view' => "รุà¹\88à¸\99à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89'''à¸\96ูà¸\81ยัà¸\9aยัà¹\89à¸\87'''
+'rev-suppressed-text-view' => "รุ่นหน้านี้'''ถูกยับยั้ง'''
 คุณสามารถดูรุ่นนี้ได้ รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ปูมการยับยั้ง]",
-'rev-deleted-no-diff' => "à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¹\80รียà¸\81à¸\94ูà¸\84วามà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลงนี้ เพราะมีบางรุ่น'''ถูกลบ'''
+'rev-deleted-no-diff' => "à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¹\80รียà¸\81à¸\94ูà¸\9cลà¸\95à¹\88างนี้ เพราะมีบางรุ่น'''ถูกลบ'''
 รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]",
-'rev-suppressed-no-diff' => "à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¸\94ูà¸\84วามà¹\81à¸\95à¸\81à¸\95à¹\88าà¸\87ระหวà¹\88าà¸\87รุà¹\88à¸\99à¸\97ีà¹\88à¹\80ลือà¸\81à¹\84à¸\94à¹\89 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81มีà¸\84วามà¹\81à¸\95à¸\81à¸\95à¹\88าà¸\87ระหวà¹\88าà¸\87รุà¹\88à¸\99ที่'''ถูกลบ'''",
-'rev-deleted-unhide-diff' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87รายà¸\81ารà¸\84วามà¹\81à¸\95à¸\81ต่างนี้'''ถูกลบ'''
+'rev-suppressed-no-diff' => "à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¸\94ูà¸\9cลà¸\95à¹\88าà¸\87à¸\99ีà¹\89à¹\84à¸\94à¹\89 à¹\80à¸\9eราะมีà¸\9cลà¸\95à¹\88าà¸\87หà¸\99ึà¹\88à¸\87ที่'''ถูกลบ'''",
+'rev-deleted-unhide-diff' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¸\9cลต่างนี้'''ถูกลบ'''
 รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]
-à¸\84ุà¸\93ยัà¸\87สามารà¸\96[$1 à¸\94ูà¸\84วามà¹\81à¸\95à¸\81ต่างนี้]ได้ถ้าคุณต้องการดำเนินต่อ",
-'rev-suppressed-unhide-diff' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87รายà¸\81ารà¸\84วามà¹\81à¸\95à¸\81ต่างนี้'''ถูกยับยั้ง'''
+à¸\84ุà¸\93ยัà¸\87สามารà¸\96[$1 à¸\94ูà¸\9cลต่างนี้]ได้ถ้าคุณต้องการดำเนินต่อ",
+'rev-suppressed-unhide-diff' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¸\9cลต่างนี้'''ถูกยับยั้ง'''
 รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ปูมการยับยั้ง]
-à¸\84ุà¸\93ยัà¸\87สามารà¸\96[$1 à¸\94ูà¸\84วามà¹\81à¸\95à¸\81ต่างนี้]ได้ถ้าคุณต้องการดำเนินต่อ",
-'rev-deleted-diff-view' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87รายà¸\81ารà¸\84วามà¹\81à¸\95à¸\81ต่างนี้'''ถูกลบ'''
-à¸\84ุà¸\93สามารà¸\96à¸\94ูà¸\84วามà¹\81à¸\95à¸\81ต่างนี้ได้ รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]",
-'rev-suppressed-diff-view' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87รายà¸\81ารà¸\84วามà¹\81à¸\95à¸\81ต่างนี้'''ถูกยับยั้ง'''
-à¸\84ุà¸\93สามารà¸\96à¸\94ูà¸\84วามà¹\81à¸\95à¸\81ต่างนี้ได้ รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ปูมการยับยั้ง]",
+à¸\84ุà¸\93ยัà¸\87สามารà¸\96[$1 à¸\94ูà¸\9cลต่างนี้]ได้ถ้าคุณต้องการดำเนินต่อ",
+'rev-deleted-diff-view' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¸\9cลต่างนี้'''ถูกลบ'''
+à¸\84ุà¸\93สามารà¸\96à¸\94ูà¸\9cลต่างนี้ได้ รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]",
+'rev-suppressed-diff-view' => "รุà¹\88à¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¸\9cลต่างนี้'''ถูกยับยั้ง'''
+à¸\84ุà¸\93สามารà¸\96à¸\94ูà¸\9cลต่างนี้ได้ รายละเอียดพบได้ใน[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ปูมการยับยั้ง]",
 'rev-delundel' => 'แสดง/ซ่อน',
 'rev-showdeleted' => 'แสดง',
 'revisiondelete' => 'ลบ/กู้คืนรุ่น',
 'revdelete-nooldid-title' => 'ไม่มีรุ่นที่ต้องการ',
 'revdelete-nooldid-text' => 'คุณมิได้เจาะจงรุ่นเป้าหมายเพื่อดำเนินการฟังก์ชันนี้ หรือไม่มีรุ่นที่เจาะจง หรือคุณกำลังพยายามซ่อนรุ่นปัจจุบันอย่างใดอย่างหนึ่ง',
 'revdelete-nologtype-title' => 'ไม่ได้ระบุประเภทของปูม',
-'revdelete-nologtype-text' => 'à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89à¹\80à¸\88าะà¸\88à¸\87à¸\9bระà¹\80ภà¸\97à¸\82อà¸\87à¸\9bูมà¹\80à¸\9eืà¹\88อà¸\94ำà¹\80à¸\99ิà¸\99à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\81ารà¸\99ีà¹\89à¸\95à¹\88อ',
-'revdelete-nologid-title' => 'à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¹\83à¸\99รายà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82ไม่ถูกต้อง',
-'revdelete-nologid-text' => 'à¸\84ุà¸\93มิà¹\84à¸\94à¹\89à¹\80à¸\88าะà¸\88à¸\87รายà¸\81ารà¸\9bูมà¹\80à¸\9bà¹\89าหมายà¹\80à¸\9eืà¹\88อà¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¸\9fัà¸\87à¸\81à¹\8cà¸\8aัà¸\99à¸\99ีà¹\89 à¸«à¸£à¸·à¸­à¹\84มà¹\88มีรายà¸\81ารที่เจาะจงอย่างใดอย่างหนึ่ง',
+'revdelete-nologtype-text' => 'à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89à¹\80à¸\88าะà¸\88à¸\87à¸\9bระà¹\80ภà¸\97à¸\82อà¸\87à¸\9bูมà¸\97ีà¹\88à¸\88ะà¸\94ำà¹\80à¸\99ิà¸\99à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\81ารà¸\99ีà¹\89',
+'revdelete-nologid-title' => 'หà¸\99à¹\88วยà¸\9bูมไม่ถูกต้อง',
+'revdelete-nologid-text' => 'à¸\84ุà¸\93มิà¹\84à¸\94à¹\89à¹\80à¸\88าะà¸\88à¸\87รายà¸\81ารà¸\9bูมà¹\80à¸\9bà¹\89าหมายà¹\80à¸\9eืà¹\88อà¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¸\9fัà¸\87à¸\81à¹\8cà¸\8aัà¸\99à¸\99ีà¹\89 à¸«à¸£à¸·à¸­à¹\84มà¹\88มีหà¸\99à¹\88วยที่เจาะจงอย่างใดอย่างหนึ่ง',
 'revdelete-no-file' => 'ไม่มีไฟล์ที่ระบุ',
 'revdelete-show-file-confirm' => 'คุณแน่ใจที่จะดูรุ่นที่ถูกลบของไฟล์ "<nowiki>$1</nowiki>" เมื่อวันที่ $2 เวลา $3 หรือไม่',
 'revdelete-show-file-submit' => 'ใช่',
@@ -1034,7 +1060,7 @@ $1 เป็นผู้ดำเนินการบล็อก
 'logdelete-selected' => "'''{{PLURAL:$1|เหตุการณ์ปูมที่เลือก|เหตุการณ์ปูมที่เลือก}} :'''",
 'revdelete-text' => "'''รุ่นการปรับปรุงและเหตุการณ์ที่ถูกลบยังปรากฏในประวัติและปูมของหน้า แต่สาธารณะไม่สามารถเข้าถึงเนื้อหาบางส่วนได้'''
 ผู้ดูแลระบบคนอื่นบน {{SITENAME}} ยังสามารถเข้าถึงเนื้อหาที่ถูกซ่อน และสามารถกู้คืนอีกครั้งในลักษณะเดิมเช่นนี้ เว้นแต่จะมีการกำหนดการจำกัดเพิ่มเติม",
-'revdelete-confirm' => 'à¸\81รุà¸\93ายืà¸\99ยัà¸\99วà¹\88าà¸\84ุà¸\93มีà¹\80à¸\88à¸\95à¸\99าลà¸\9aà¸\88ริà¸\87 à¹\81ละà¹\80à¸\82à¹\89าà¹\83à¸\88à¸\9cลà¸\81ระà¸\97à¸\9a และกระทำภายใต้[[{{MediaWiki:Policy-url}}|นโยบาย]]',
+'revdelete-confirm' => 'à¸\81รุà¸\93ายืà¸\99ยัà¸\99วà¹\88าà¸\84ุà¸\93มีà¹\80à¸\88à¸\95à¸\99าลà¸\9aà¸\88ริà¸\87 à¹\81ละà¹\80à¸\82à¹\89าà¹\83à¸\88à¸\9cลลัà¸\9eà¸\98à¹\8c และกระทำภายใต้[[{{MediaWiki:Policy-url}}|นโยบาย]]',
 'revdelete-suppress-text' => "การระงับควรใช้ '''เฉพาะ''' กรณีต่อไปนี้:
 * ข้อมูลที่อาจหมิ่นประมาท
 * ข้อมูลส่วนบุคคลที่ไม่เหมาะสม
@@ -1044,7 +1070,7 @@ $1 เป็นผู้ดำเนินการบล็อก
 'revdelete-hide-image' => 'ซ่อนเนื้อหาไฟล์',
 'revdelete-hide-name' => 'ซ่อนปฏิบัติการและเป้าหมาย',
 'revdelete-hide-comment' => 'ซ่อนคำอธิบายอย่างย่อ',
-'revdelete-hide-user' => 'à¸\8bà¹\88อà¸\99à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89¸«à¸¡à¸²à¸¢à¹\80ลà¸\82ไอพีผู้เขียน',
+'revdelete-hide-user' => 'à¸\8bà¹\88อà¸\99à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีผู้เขียน',
 'revdelete-hide-restricted' => 'ระงับข้อมูลจากผู้ดูแลระบบเช่นเดียวกับผู้ใช้อื่น',
 'revdelete-radio-same' => '(ไม่เปลี่ยนแปลง)',
 'revdelete-radio-set' => 'ใช่',
@@ -1069,12 +1095,12 @@ $1",
 'revdelete-show-no-access' => 'เกิดความผิดพลาดในการแสดงรุ่นเมื่อวันที่ $2 เวลา $1: ฉบับปรับปรุงนี้ถูกกำหนดให้ "ถูกจำกัด"
 คุณไม่มีสิทธิเข้าถึงรุ่นดังกล่าว',
 'revdelete-modify-no-access' => 'เกิดความผิดพลาดในการแก้ไขรุ่นการแก้ไขเมื่อวันที่ $2 เวลา $1: รุ่นการแก้ไขนี้ถูกกำหนดให้ "ถูกจำกัด"
-à¸\84ุà¸\93à¹\84มà¹\88มีสิà¸\97à¸\98ิà¹\8cà¹\80à¸\82à¹\89าà¸\96ึà¸\87รุà¹\88à¸\99à¸\94ัà¸\87à¸\81ลà¹\88าว',
-'revdelete-modify-missing' => 'à¹\80à¸\81ิà¸\94à¸\84วามà¸\9cิà¸\94à¸\9eลาà¸\94à¹\83à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\89à¸\9aัà¸\9aà¸\9bรัà¸\87à¸\9bรุà¸\87หมายเลข $1: รายการนี้สูญหายจากฐานข้อมูล!',
-'revdelete-no-change' => "'''à¸\84ำà¹\80à¸\95ือà¸\99:''' à¸£à¸¸à¹\88à¸\99à¹\80มืà¹\88อวัà¸\99à¸\97ีà¹\88 $2 à¹\80วลา $1 à¸¡à¸µà¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าà¸\97ัศà¸\99วิสัยà¸\95ามà¸\97ีà¹\88à¸\82ออยูà¹\88à¹\81ลà¹\89ว",
-'revdelete-concurrent-change' => 'à¹\80à¸\81ิà¸\94à¸\84วามà¸\9cิà¸\94à¸\9eลาà¸\94à¹\83à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82รุà¹\88à¸\99à¹\80มืà¹\88อวัà¸\99à¸\97ีà¹\88 $2 à¹\80วลา $1: มีผู้อื่นเปลี่ยนสถานะของรุ่นขณะที่คุณพยายามแก้ไข
+คุณไม่มีสิทธิเข้าถึงรุ่นดังกล่าว',
+'revdelete-modify-missing' => 'à¹\80à¸\81ิà¸\94à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94à¹\83à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82รุà¹\88à¸\99หมายเลข $1: รายการนี้สูญหายจากฐานข้อมูล!',
+'revdelete-no-change' => "'''คำเตือน:''' รุ่นเมื่อวันที่ $2 เวลา $1 ตั้งค่าทัศนวิสัยตามที่ขออยู่แล้ว",
+'revdelete-concurrent-change' => 'à¹\80à¸\81ิà¸\94à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94à¹\83à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82รุà¹\88à¸\99à¹\80มืà¹\88อวัà¸\99à¸\97ีà¹\88 $2 à¹\80วลา $1: à¸\94ูà¹\80หมือà¸\99มีผู้อื่นเปลี่ยนสถานะของรุ่นขณะที่คุณพยายามแก้ไข
 กรุณาตรวจสอบปูม',
-'revdelete-only-restricted' => 'à¹\80à¸\81ิà¸\94à¸\84วามผิดพลาดในการซ่อนรุ่นเมื่อวันที่ $2 เวลา $1: คุณไม่สามารถยับยั้งผู้ดูแลระบบมิให้ดูรุ่นนี้ได้โดยไม่เลือกตัวเลือกทัศนวิสัยอื่นด้วย',
+'revdelete-only-restricted' => 'à¹\80à¸\81ิà¸\94à¸\82à¹\89อผิดพลาดในการซ่อนรุ่นเมื่อวันที่ $2 เวลา $1: คุณไม่สามารถยับยั้งผู้ดูแลระบบมิให้ดูรุ่นนี้ได้โดยไม่เลือกตัวเลือกทัศนวิสัยอื่นด้วย',
 'revdelete-reason-dropdown' => '*เหตุผลการลบทั่วไป
 ** ละเมิดลิขสิทธิ์
 ** ความเห็นไม่เหมาะสมหรือข้อมูลส่วนบุคคล
@@ -1092,8 +1118,8 @@ $1",
 
 # History merging
 'mergehistory' => 'ประวัติการรวมหน้า',
-'mergehistory-header' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¹\84วà¹\89à¹\83หà¹\89à¸\84ุà¸\93à¹\83à¸\8aà¹\89รวมรุà¹\88à¸\99à¸\95à¹\88าà¸\87à¹\86 à¹\83à¸\99à¸\9bระวัà¸\95ิà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87หà¸\99à¹\89าà¸\95à¹\89à¸\99à¸\97าà¸\87 à¹\84à¸\9bยัà¸\87หà¸\99à¹\89าà¹\83หมà¹\88.
-à¸\81à¹\88อà¸\99à¸\94ำà¹\80à¸\99ิà¸\99à¸\81าร à¸\84วรà¹\83หà¹\89à¹\81à¸\99à¹\88à¹\83à¸\88à¸\81à¹\88อà¸\99วà¹\88าà¸\81ารà¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¸\99ีà¹\89à¸\88ะà¹\84มà¹\88à¸\97ำà¹\83หà¹\89à¸\84วามà¸\84วามà¸\95à¹\88อà¹\80à¸\99ืà¹\88อà¸\87à¸\82อà¸\87à¸\9bระวัà¸\95ิหà¸\99à¹\89าà¹\80à¸\81à¹\88าà¹\86 à¹\80สียà¹\84à¸\9b.',
+'mergehistory-header' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¹\84วà¹\89à¹\83หà¹\89à¸\84ุà¸\93à¹\83à¸\8aà¹\89รวมรุà¹\88à¸\99à¹\83à¸\99à¸\9bระวัà¸\95ิà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87หà¸\99à¹\89าà¸\95à¹\89à¸\99à¸\97าà¸\87หà¸\99ึà¹\88à¸\87à¹\84à¸\9bยัà¸\87หà¸\99à¹\89าà¹\83หมà¹\88
+à¸\81à¹\88อà¸\99à¸\94ำà¹\80à¸\99ิà¸\99à¸\81าร à¸\84วรà¹\83หà¹\89à¹\81à¸\99à¹\88à¹\83à¸\88à¸\81à¹\88อà¸\99วà¹\88าà¸\81ารà¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¸\99ีà¹\89ยัà¸\87รัà¸\81ษาà¸\84วามà¸\95à¹\88อà¹\80à¸\99ืà¹\88อà¸\87à¸\82อà¸\87à¸\9bระวัà¸\95ิหà¸\99à¹\89าà¹\80à¸\81à¹\88า',
 'mergehistory-box' => 'รวมรุ่นของหน้าทั้งสอง:',
 'mergehistory-from' => 'หน้าต้นทาง:',
 'mergehistory-into' => 'หน้าปลายทาง:',
@@ -1106,40 +1132,44 @@ $1",
 'mergehistory-fail' => 'ไม่สามารถรวมประวัติการแก้ไขได้ โปรดตรวจสอบค่าตัวแปรหน้าและเวลาอีกครั้ง',
 'mergehistory-no-source' => 'ไม่มีหน้าต้นทาง $1 อยู่ในสารบบ',
 'mergehistory-no-destination' => 'ไม่มีหน้าปลายทาง $1 อยู่ในสารบบ',
-'mergehistory-invalid-source' => 'หัวà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\95à¹\89à¸\99à¸\97าà¸\87à¸\95à¹\89อà¸\87à¸\95รà¸\87à¸\95ามà¸\82à¹\89อà¸\81ำหà¸\99à¸\94 (à¹\80à¸\8aà¹\88à¸\99 à¹\84มà¹\88มีà¸\95ัวอัà¸\81ษรà¸\97ีà¹\88à¹\84มà¹\88สามารà¸\96à¹\83à¸\8aà¹\89à¹\83à¸\99หัวà¹\80รืà¹\88อà¸\87à¹\84à¸\94à¹\89)',
-'mergehistory-invalid-destination' => 'หัวà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\9bลายà¸\97าà¸\87à¸\95à¹\89อà¸\87à¸\95รà¸\87à¸\95ามà¸\82à¹\89อà¸\81ำหà¸\99à¸\94 (à¹\80à¸\8aà¹\88à¸\99 à¹\84มà¹\88มีà¸\95ัวอัà¸\81ษรà¸\97ีà¹\88à¹\84มà¹\88สามารà¸\96à¹\83à¸\8aà¹\89à¹\83à¸\99หัวà¹\80รืà¹\88อà¸\87à¹\84à¸\94à¹\89)',
-'mergehistory-autocomment' => 'ยà¹\89าย [[:$1]] à¹\84à¸\9bยัà¸\87 [[:$2]]',
-'mergehistory-comment' => 'ยà¹\89าย [[:$1]] à¹\84à¸\9bยัà¸\87 [[:$2]]: $3',
+'mergehistory-invalid-source' => 'à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\95à¹\89à¸\99à¸\97าà¸\87à¸\95à¹\89อà¸\87สมà¹\80หà¸\95ุสมà¸\9cล',
+'mergehistory-invalid-destination' => 'à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\9bลายà¸\97าà¸\87à¸\95à¹\89อà¸\87สมà¹\80หà¸\95ุสมà¸\9cล',
+'mergehistory-autocomment' => 'รวม [[:$1]] à¹\80à¸\82à¹\89าà¸\81ัà¸\9a [[:$2]]',
+'mergehistory-comment' => 'รวม [[:$1]] à¹\80à¸\82à¹\89าà¸\81ัà¸\9a [[:$2]]: $3',
 'mergehistory-same-destination' => 'หน้าต้นทางและปลายทางเป็นหน้าเดียวกันไม่ได้',
 'mergehistory-reason' => 'เหตุผล:',
 
 # Merge log
 'mergelog' => 'ปูมการรวมหน้า',
-'pagemerge-logentry' => 'ยà¹\89าย [[$1]] à¹\84à¸\9bยัà¸\87 [[$2]] (รุ่นขึ้นอยู่กับ $3)',
+'pagemerge-logentry' => 'รวม [[$1]] à¹\80à¸\82à¹\89าà¸\81ัà¸\9a [[$2]] (รุ่นขึ้นอยู่กับ $3)',
 'revertmerge' => 'ยกเลิกการรวมหน้า',
-'mergelogpagetext' => 'à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¸\99ีà¹\89à¹\81สà¸\94à¸\87รายà¸\81ารลà¹\88าสุà¸\94à¸\82อà¸\87à¸\81ารรวมà¸\9bระวัà¸\95ิหà¸\99à¹\89าหà¸\99ึà¹\88à¸\87à¹\80à¸\82à¹\89าà¸\81ัà¸\9aอีà¸\81หà¸\99à¹\89าหà¸\99ึà¹\88à¸\87',
+'mergelogpagetext' => 'à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99รายà¸\81ารà¸\81ารรวมà¸\9bระวัà¸\95ิà¸\82อà¸\87หà¸\99à¹\89าหà¸\99ึà¹\88à¸\87à¹\80à¸\82à¹\89าà¸\81ัà¸\9aà¸\82อà¸\87อีà¸\81หà¸\99à¹\89าหà¸\99ึà¹\88à¸\87ลà¹\88าสุà¸\94',
 
 # Diffs
 'history-title' => 'ประวัติรุ่นปรับปรุงของ "$1"',
-'difference-title' => 'à¸\84วามà¹\81à¸\95à¸\81ต่างระหว่างรุ่นของ "$1"',
-'difference-title-multipage' => 'à¸\84วามà¹\81à¸\95à¸\81ต่างระหว่างหน้า "$1" และ "$2"',
-'difference-multipage' => '(à¸\84วามà¹\81à¸\95à¸\81à¸\95à¹\88าà¸\87ระหวà¹\88าà¸\87หà¸\99à¹\89าà¸\95à¹\88าà¸\87 à¹\86)',
+'difference-title' => 'à¸\9cลต่างระหว่างรุ่นของ "$1"',
+'difference-title-multipage' => 'à¸\9cลต่างระหว่างหน้า "$1" และ "$2"',
+'difference-multipage' => '(à¸\9cลà¸\95à¹\88าà¸\87ระหวà¹\88าà¸\87หà¸\99à¹\89า)',
 'lineno' => 'แถว $1:',
 'compareselectedversions' => 'เปรียบเทียบสองรุ่นที่เลือก',
 'showhideselectedversions' => 'แสดง/ซ่อนรุ่นที่เลือก',
 'editundo' => 'ย้อน',
-'diff-multi' => '(มิได้แสดง $1 รุ่นระหว่างรุ่นที่เปรียบเทียบโดย{{PLURAL:$2|ผู้ใช้คนหนึ่ง|ผู้ใช้ $2 คน}})',
-'diff-multi-manyusers' => '(มิได้แสดง $1 รุ่นระหว่างรุ่นที่เปรียบเทียบโดยผู้ใช้กว่า $2 คน)',
+'diff-multi' => '(มิได้แสดง $1 รุ่นระหว่างกลางโดย{{PLURAL:$2|ผู้ใช้คนหนึ่ง|ผู้ใช้ $2 คน}})',
+'diff-multi-manyusers' => '(มิได้แสดง $1 รุ่นระหว่างกลางโดยผู้ใช้กว่า $2 คน)',
+'difference-missing-revision' => 'ไม่พบรุ่น{{PLURAL:$2|รุ่น| $2 รุ่น}}ของผลต่างนี้ ($1)
+
+โดยปกติเกิดจากการเข้าลิงก์ผลต่างของหน้าที่ถูกลบไปแล้ว 
+ดูรายละเอียดได้ที่[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ปูมการลบ]',
 
 # Search results
 'searchresults' => 'ผลการค้นหา',
 'searchresults-title' => 'ผลการค้นหาสำหรับ "$1"',
-'searchresulttext' => 'สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการค้น {{SITENAME}} ดูที่ [[{{MediaWiki:Helppage}}|{{int:help}}]]',
-'searchsubtitle' => 'à¸\84ุà¸\93à¹\84à¸\94à¹\89สืà¸\9aà¸\84à¹\89à¸\99หา \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|à¸\97ุà¸\81หà¸\99à¹\89าà¸\97ีà¹\88à¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99à¸\94à¹\89วย "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|à¸\97ุà¸\81หà¸\99à¹\89าà¸\97ีà¹\88à¹\82ยà¸\87มาà¸\97ีà¹\88 "$1"]])',
-'searchsubtitleinvalid' => "à¸\84à¹\89à¸\99หาà¹\80à¸\81ีà¹\88ยวà¸\81ัà¸\9a '''$1'''",
-'toomanymatches' => 'พบตรงกันมากเกินไป กรุณาใช้คำค้นหาอื่น',
-'titlematches' => 'à¸\9eà¸\9aà¸\8aืà¹\88อหัวà¸\82à¹\89อà¸\99ีà¹\89',
-'notitlematches' => 'à¹\84มà¹\88à¸\9eà¸\9aà¸\8aืà¹\88อหัวà¸\82à¹\89อà¸\99ีà¹\89',
+'searchresulttext' => 'สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการค้นหา {{SITENAME}} ดูที่ [[{{MediaWiki:Helppage}}|{{int:help}}]]',
+'searchsubtitle' => 'คุณได้ค้นหา \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|ทุกหน้าที่ขึ้นต้นด้วย "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|ทุกหน้าที่โยงมาที่ "$1"]])',
+'searchsubtitleinvalid' => "à¸\84ุà¸\93à¹\84à¸\94à¹\89à¸\84à¹\89à¸\99หาà¸\84ำวà¹\88า '''$1'''",
+'toomanymatches' => 'à¸\9eà¸\9aà¸\95รà¸\87à¸\81ัà¸\99มาà¸\81à¹\80à¸\81ิà¸\99à¹\84à¸\9b à¸\81รุà¸\93าลอà¸\87à¹\83à¸\8aà¹\89à¸\84ำà¸\84à¹\89à¸\99หาอืà¹\88à¸\99',
+'titlematches' => 'à¸\9eà¸\9aà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\95รà¸\87à¸\81ัà¸\99',
+'notitlematches' => 'à¹\84มà¹\88à¸\9eà¸\9aà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\95รà¸\87à¸\81ัà¸\99',
 'textmatches' => 'พบคำนี้ในหน้า',
 'notextmatches' => 'ไม่พบข้อความในหน้า',
 'prevn' => 'ก่อนหน้า $1',
@@ -1152,7 +1182,7 @@ $1",
 'searchmenu-exists' => "'''มีหน้าชื่อ \"[[:\$1]]\" บนวิกินี้'''",
 'searchmenu-new' => "'''สร้างหน้า \"[[:\$1]]\" บนวิกินี้'''",
 'searchhelp-url' => 'Help:สารบัญ',
-'searchmenu-prefix' => '[[Special:PrefixIndex/$1|สืà¸\9aà¸\84à¹\89à¸\99หน้าที่มีคำขึ้นต้นนี้]]',
+'searchmenu-prefix' => '[[Special:PrefixIndex/$1|à¸\84à¹\89à¸\99à¸\94ูหน้าที่มีคำขึ้นต้นนี้]]',
 'searchprofile-articles' => 'หน้าเนื้อหา',
 'searchprofile-project' => 'คำอธิบายและหน้าโครงการ',
 'searchprofile-images' => 'มัลติมีเดีย',
@@ -1173,16 +1203,16 @@ $1",
 'search-interwiki-default' => '$1 ผลลัพธ์:',
 'search-interwiki-more' => '(เพิ่มเติม)',
 'search-relatedarticle' => 'สัมพันธ์',
-'mwsuggest-disable' => 'ยà¸\81à¹\80ลิà¸\81à¸\81ารà¹\81à¸\99ะà¸\99ำà¹\83à¸\99ลัà¸\81ษà¸\93ะà¹\80อà¹\81à¸\88à¹\87à¸\81à¸\8bà¹\8c',
-'searcheverything-enable' => 'สืà¸\9aà¸\84à¹\89à¸\99à¹\83à¸\99à¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¸\97ัà¹\89à¸\87หมà¸\94',
+'mwsuggest-disable' => 'à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99à¸\81ารà¹\80สà¸\99อà¹\81à¸\99ะà¸\81ารà¸\84à¹\89à¸\99หา',
+'searcheverything-enable' => 'à¸\84à¹\89à¸\99หาà¹\83à¸\99à¸\97ุà¸\81à¹\80à¸\99มสà¹\80à¸\9bà¸\8b',
 'searchrelated' => 'สัมพันธ์',
 'searchall' => 'ทั้งหมด',
-'showingresults' => "à¹\81สà¸\94à¸\87 $1 à¸£à¸²à¸¢à¸\81าร à¹\80ริà¹\88มà¸\95à¹\89à¸\99à¸\88าà¸\81รายการที่ '''$2'''",
-'showingresultsnum' => "à¹\81สà¸\94à¸\87 $3 à¸£à¸²à¸¢à¸\81าร à¹\80ริà¹\88มà¸\95à¹\89à¸\99à¸\88าà¸\81รายการที่  '''$2'''",
-'showingresultsheader' => "{{PLURAL:$5|à¸\9cลà¸\81ารสืà¸\9aà¸\84à¹\89à¸\99 '''$1''' à¸\88าà¸\81 '''$3'''|à¸\9cลà¸\81ารสืà¸\9aà¸\84à¹\89à¸\99 '''$1 - $2''' จาก '''$3'''}} สำหรับ '''$4'''",
-'nonefound' => "'''à¸\84ำà¹\80à¸\95ือà¸\99''': à¸¡à¸µà¹\80à¸\9eียà¸\87à¸\9aาà¸\87à¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¸\97ีà¹\88à¸\88ะà¸\96ูà¸\81à¸\84à¹\89à¸\99โดยปริยาย
-ลอà¸\87à¹\80ลือà¸\81à¸\84ำà¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99à¸\81ารà¸\84à¹\89à¸\99หาà¸\94à¹\89วย ''all:'' à¸ªà¸³à¸«à¸£à¸±à¸\9aà¸\84à¹\89à¸\99à¹\80à¸\99ืà¹\89อหาà¸\97ัà¹\89à¸\87หมà¸\94 (รวมหà¸\99à¹\89าอภิà¸\9bราย à¹\81มà¹\88à¹\81à¸\9aà¸\9a à¸¯à¸¥à¸¯) à¸«à¸£à¸·à¸­à¹\80ลือà¸\81เนมสเปซที่ต้องการ",
-'search-nonefound' => 'à¹\84มà¹\88มีà¸\9cลลัà¸\9eà¸\98à¹\8cà¸\95ามà¸\84ำà¸\84à¹\89à¸\99à¸\97ีà¹\88à¸\81ำหà¸\99à¸\94',
+'showingresults' => "à¹\81สà¸\94à¸\87 $1 à¸£à¸²à¸¢à¸\81าร à¹\80ริà¹\88มà¸\95ัà¹\89à¸\87à¹\81à¸\95à¹\88รายการที่ '''$2'''",
+'showingresultsnum' => "à¹\81สà¸\94à¸\87 $3 à¸£à¸²à¸¢à¸\81าร à¹\80ริà¹\88มà¸\95ัà¹\89à¸\87à¹\81à¸\95à¹\88รายการที่  '''$2'''",
+'showingresultsheader' => "{{PLURAL:$5|à¸\9cลà¸\81ารà¸\84à¹\89à¸\99หา '''$1''' à¸\88าà¸\81 '''$3'''|à¸\9cลà¸\81ารà¸\84à¹\89à¸\99หา '''$1 - $2''' จาก '''$3'''}} สำหรับ '''$4'''",
+'nonefound' => "'''à¸\84ำà¹\80à¸\95ือà¸\99''': à¸¡à¸µà¹\80à¸\9eียà¸\87à¸\9aาà¸\87à¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¹\80à¸\97à¹\88าà¸\99ัà¹\89à¸\99à¸\97ีà¹\88à¸\88ะà¸\96ูà¸\81à¸\84à¹\89à¸\99หาโดยปริยาย
+ลอà¸\87à¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99à¸\81ารà¸\84à¹\89à¸\99หาà¸\94à¹\89วย ''all:'' à¹\80à¸\9eืà¹\88อà¸\84à¹\89à¸\99หาà¹\80à¸\99ืà¹\89อหาà¸\97ัà¹\89à¸\87หมà¸\94 (รวมหà¸\99à¹\89าอภิà¸\9bราย à¹\81มà¹\88à¹\81à¸\9aà¸\9a à¸¯à¸¥à¸¯) à¸«à¸£à¸·à¸­à¹\83à¸\8aà¹\89à¸\84ำà¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99à¹\80à¸\9bà¹\87à¸\99เนมสเปซที่ต้องการ",
+'search-nonefound' => 'à¹\84มà¹\88มีà¸\9cลลัà¸\9eà¸\98à¹\8cà¸\95รà¸\87à¸\81ัà¸\9aà¸\84ำà¸\84à¹\89à¸\99',
 'powersearch' => 'ค้นหาระดับสูง',
 'powersearch-legend' => 'ค้นหาระดับสูง',
 'powersearch-ns' => 'ค้นหาในเนมสเปซ:',
@@ -1191,14 +1221,14 @@ $1",
 'powersearch-togglelabel' => 'เลือก:',
 'powersearch-toggleall' => 'ทั้งหมด',
 'powersearch-togglenone' => 'ไม่เลือก',
-'search-external' => 'à¸\84à¹\89à¸\99หาà¸\88าà¸\81ภายà¸\99อà¸\81',
-'searchdisabled' => 'ระà¸\9aà¸\9aà¸\81ารà¸\84à¹\89à¸\99หาà¹\83à¸\99 {{SITENAME}} à¹\84มà¹\88à¹\80à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99 à¸\84ุà¸\93สามารà¸\96à¸\84à¹\89à¸\99หาà¹\83à¸\99à¸\81ูà¹\80à¸\81ิลหรือà¹\80à¸\8bิรà¹\8cà¸\8aà¹\80อà¸\99à¸\88ิà¸\99อืà¹\88à¸\99 à¹\82à¸\9bรà¸\94à¸\97ราà¸\9aวà¹\88าเนื้อหาของ {{SITENAME}} บนเซิร์ชเอนจินอาจเป็นข้อมูลเก่า',
+'search-external' => 'ค้นหาภายนอก',
+'searchdisabled' => 'à¸\81ารà¸\84à¹\89à¸\99หา {{SITENAME}} à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99 à¸\84ุà¸\93สามารà¸\96à¸\84à¹\89à¸\99หาà¸\9cà¹\88าà¸\99à¸\81ูà¹\80à¸\81ิลหรือà¹\80à¸\8bิรà¹\8cà¸\8aà¹\80อà¸\99à¸\88ิà¸\99อืà¹\88à¸\99à¹\83à¸\99à¹\80วลาà¹\84มà¹\88à¸\99าà¸\99 à¹\82à¸\9bรà¸\94à¸\97ราà¸\9aวà¹\88าà¸\94ัà¸\8aà¸\99ีเนื้อหาของ {{SITENAME}} บนเซิร์ชเอนจินอาจเป็นข้อมูลเก่า',
 
 # Quickbar
 'qbsettings' => 'แถบพิเศษ',
 'qbsettings-none' => 'ไม่มี',
-'qbsettings-fixedleft' => 'อยูà¹\88ทางซ้าย',
-'qbsettings-fixedright' => 'อยูà¹\88ทางขวา',
+'qbsettings-fixedleft' => 'à¸\95รึà¸\87à¹\84วà¹\89ทางซ้าย',
+'qbsettings-fixedright' => 'à¸\95รึà¸\87à¹\84วà¹\89ทางขวา',
 'qbsettings-floatingleft' => 'ด้านซ้าย',
 'qbsettings-floatingright' => 'ด้านขวา',
 
@@ -1216,7 +1246,7 @@ $1",
 'prefs-datetime' => 'วันที่และเวลา',
 'prefs-labs' => 'คุณสมบัติทดลอง',
 'prefs-user-pages' => 'หน้าผู้ใช้',
-'prefs-personal' => 'รายละà¹\80อียà¸\94ผู้ใช้',
+'prefs-personal' => 'à¹\82à¸\9eรà¹\84à¸\9fลà¹\8cผู้ใช้',
 'prefs-rc' => 'ปรับปรุงล่าสุด',
 'prefs-watchlist' => 'รายการเฝ้าดู',
 'prefs-watchlist-days' => 'จำนวนวันที่แสดงในรายการเฝ้าดู:',
@@ -1228,7 +1258,7 @@ $1",
 'prefs-resetpass' => 'เปลี่ยนรหัสผ่าน',
 'prefs-changeemail' => 'เปลี่ยนที่อยู่อีเมล',
 'prefs-setemail' => 'ตั้งที่อยู่อีเมล',
-'prefs-email' => 'à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าอีเมล',
+'prefs-email' => 'à¸\95ัวà¹\80ลือà¸\81อีเมล',
 'prefs-rendering' => 'รูปลักษณ์',
 'saveprefs' => 'บันทึก',
 'resetprefs' => 'ล้างการเปลี่ยนแปลงที่ยังไม่บันทึก',
@@ -1237,10 +1267,10 @@ $1",
 'prefs-edit-boxsize' => 'ขนาดหน้าจอกล่องแก้ไข',
 'rows' => 'แถว:',
 'columns' => 'คอลัมน์:',
-'searchresultshead' => 'สืà¸\9aà¸\84à¹\89à¸\99',
-'resultsperpage' => 'รายà¸\81ารต่อหน้า:',
-'stub-threshold' => 'à¸\82ีà¸\94à¹\81à¸\9aà¹\88à¸\87สำหรัà¸\9a <a href="#" class="stub">รูà¸\9bà¹\81à¸\9aà¸\9aà¹\82à¸\84รà¸\87</a> (à¸\84วามยาวà¸\9aà¸\97à¸\84วาม):',
-'stub-threshold-disabled' => 'à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99',
+'searchresultshead' => 'à¸\84à¹\89à¸\99หา',
+'resultsperpage' => 'à¸\81ารà¹\80à¸\9bิà¸\94à¸\94ูต่อหน้า:',
+'stub-threshold' => 'à¸\82ีà¸\94à¹\81à¸\9aà¹\88à¸\87สำหรัà¸\9a <a href="#" class="stub">ลิà¸\87à¸\81à¹\8cà¹\82à¸\84รà¸\87</a> (à¹\84à¸\9aà¸\95à¹\8c):',
+'stub-threshold-disabled' => 'ปิดใช้งาน',
 'recentchangesdays' => 'จำนวนวันที่แสดงในปรับปรุงล่าสุด:',
 'recentchangesdays-max' => 'มากสุด $1 วัน',
 'recentchangescount' => 'จำนวนการแก้ไขที่แสดงโดยปริยาย:',
@@ -1275,47 +1305,47 @@ $1",
 'prefs-custom-css' => 'สไตล์ชีตปรับแต่งเอง',
 'prefs-custom-js' => 'จาวาสคริปต์ปรับแต่งเอง',
 'prefs-common-css-js' => 'CSS / จาวาสคริปต์ที่ใช้ร่วมกันกับทุกหน้าตา:',
-'prefs-reset-intro' => 'à¸\84ุà¸\93สามารà¸\96à¹\83à¸\8aà¹\89หà¸\99à¹\89าà¸\99ีà¹\89à¸\95ัà¹\89à¸\87à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าà¸\82อà¸\87à¸\84ุà¸\93à¸\81ลัà¸\9aà¹\80à¸\9bà¹\87à¸\99à¸\84à¹\88าà¸\95ัà¹\89à¸\87à¸\95à¹\89à¸\99à¸\82อà¸\87à¹\84à¸\8bà¸\95à¹\8cใหม่
¹\80มืà¹\88อลà¹\89าà¸\87à¹\81ลà¹\89วà¸\88ะà¹\84มà¹\88สามารà¸\96ยà¹\89อà¸\99กลับได้',
+'prefs-reset-intro' => 'à¸\84ุà¸\93สามารà¸\96à¹\83à¸\8aà¹\89หà¸\99à¹\89าà¸\99ีà¹\89à¸\95ัà¹\89à¸\87à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าà¸\82อà¸\87à¸\84ุà¸\93à¸\81ลัà¸\9aà¹\84à¸\9bยัà¸\87à¸\84à¹\88าà¸\95ัà¹\89à¸\87à¸\95à¹\89à¸\99à¸\82อà¸\87à¹\80วà¹\87à¸\9aใหม่
¸\8bึà¹\88à¸\87à¹\84มà¹\88สามารà¸\96à¸\97ำกลับได้',
 'prefs-emailconfirm-label' => 'การยืนยันอีเมล:',
-'prefs-textboxsize' => 'à¸\82à¸\99าà¸\94à¸\82อà¸\87หà¸\99à¹\89าà¸\95à¹\88าà¸\87à¹\81à¸\81à¹\89à¹\84à¸\82',
+'prefs-textboxsize' => 'ขนาดหน้าต่างแก้ไข',
 'youremail' => 'อีเมล:',
 'username' => '{{GENDER:$1|ชื่อผู้ใช้}}:',
 'uid' => 'รหัสประจำตัว{{GENDER:$1|ผู้ใช้}}:',
 'prefs-memberingroups' => '{{GENDER:$2|สมาชิก}}ใน{{PLURAL:$1|กลุ่ม|กลุ่ม}}:',
-'prefs-registration' => 'วัà¸\99à¹\80วลาà¸\97ีà¹\88ลงทะเบียน:',
+'prefs-registration' => 'à¹\80วลาลงทะเบียน:',
 'yourrealname' => 'ชื่อจริง:',
 'yourlanguage' => 'ภาษา:',
 'yourvariant' => 'อักษรต่างรูปของเนื้อหา:',
 'yournick' => 'ลายเซ็น:',
-'prefs-help-signature' => 'à¸\84วามà¹\80หà¹\87à¸\99à¹\83à¸\99หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\84วรà¸\88ะลà¸\87ลายà¹\80à¸\8bà¹\87à¸\99à¸\94à¹\89วย "<nowiki>~~~~</nowiki>" à¸\8bึà¹\88à¸\87à¸\88ะà¸\96ูà¸\81à¹\81à¸\9bลà¸\87à¹\80à¸\9bà¹\87à¸\99ลายà¹\80à¸\8bà¹\87à¸\99และตราเวลา',
-'badsig' => 'ลายà¹\80à¸\8bà¹\87à¸\99à¸\97ีà¹\88à¹\83à¸\8aà¹\89à¸\9cิà¸\94à¸\9eลาà¸\94 à¸\81รุà¸\93าà¸\95รวà¸\88สอà¸\9aà¸\84ำสัà¹\88à¸\87เอชทีเอ็มแอล',
+'prefs-help-signature' => 'à¸\84วามà¹\80หà¹\87à¸\99à¹\83à¸\99หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\84วรลà¸\87ลายà¹\80à¸\8bà¹\87à¸\99à¸\94à¹\89วย "<nowiki>~~~~</nowiki>" à¸\8bึà¹\88à¸\87à¸\88ะà¸\96ูà¸\81à¹\81à¸\9bลà¸\87à¹\80à¸\9bà¹\87à¸\99ลายà¹\80à¸\8bà¹\87à¸\99à¸\82อà¸\87à¸\84ุà¸\93และตราเวลา',
+'badsig' => 'ลายà¹\80à¸\8bà¹\87à¸\99à¸\94ิà¸\9aà¹\84มà¹\88สมà¹\80หà¸\95ุสมà¸\9cล à¸\95รวà¸\88สอà¸\9aà¸\9bà¹\89ายระà¸\9aุเอชทีเอ็มแอล',
 'badsiglength' => 'ลายเซ็นของคุณยาวเกินไป ต้องยาวไม่เกิน $1 ตัวอักษร',
 'yourgender' => 'เพศ:',
 'gender-unknown' => 'ไม่ระบุ',
 'gender-male' => 'ชาย',
 'gender-female' => 'หญิง',
-'prefs-help-gender' => 'à¹\80à¸\9bà¹\87à¸\99à¸\82à¹\89อมูลà¹\80สริม: à¹\83à¸\8aà¹\89à¹\80à¸\9eืà¹\88อà¹\83หà¹\89à¸\8bอà¸\9fà¸\95à¹\8cà¹\81วรà¹\8cà¹\81ยà¸\81à¹\81ยะà¹\80à¸\9eศà¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\84à¸\94à¹\89 à¸\82à¹\89อมูลà¸\99ีà¹\89à¸\88ะà¹\80à¸\9bà¹\87à¸\99à¸\97ีà¹\88à¹\80à¸\9bิà¸\94à¹\80à¸\9cย',
+'prefs-help-gender' => 'à¹\80à¸\9bà¹\87à¸\99à¸\82à¹\89อมูลà¹\80สริม: à¹\83à¸\8aà¹\89à¹\80à¸\9eืà¹\88อà¹\83หà¹\89à¸\8bอà¸\9fà¸\95à¹\8cà¹\81วรà¹\8cà¹\81ยà¸\81à¹\81ยะà¹\80à¸\9eศà¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\84à¸\94à¹\89 à¸\82à¹\89อมูลà¸\99ีà¹\89à¸\88ะà¹\80à¸\9bิà¸\94à¹\80à¸\9cยà¸\95à¹\88อสาà¸\98ารà¸\93ะ',
 'email' => 'อีเมล',
-'prefs-help-realname' => 'à¹\84มà¹\88à¸\88ำà¹\80à¸\9bà¹\87à¸\99à¸\95à¹\89อà¸\87à¹\83à¸\8aà¹\89à¸\8aืà¹\88อà¸\88ริà¸\87 à¸\96à¹\89าà¸\84ุà¸\93à¹\80ลือà¸\81à¸\97ีà¹\88à¸\88ะà¹\83à¸\8aà¹\89à¸\8aืà¹\88อà¸\88ริà¸\87 à¸\88ะà¹\83à¸\8aà¹\89à¹\80à¸\9eืà¹\88อà¹\83หà¹\89à¹\80à¸\81ียรà¸\95ิà¹\81à¸\81à¹\88à¸\87าà¸\99à¸\82อà¸\87à¸\84ุà¸\93',
-'prefs-help-email' => 'à¹\84มà¹\88à¸\95à¹\89อà¸\87à¹\83สà¹\88à¸\97ีà¹\88อยูà¹\88อีà¹\80มล à¹\81à¸\95à¹\88à¸\88ำà¹\80à¸\9bà¹\87à¸\99สำหรัà¸\9aà¸\81ารà¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¹\80มืà¹\88อà¸\84ุà¸\93ลืมรหัสà¸\9cà¹\88าà¸\99à¸\82อà¸\87à¸\84ุà¸\93',
+'prefs-help-realname' => 'ไม่จำเป็นต้องใช้ชื่อจริง ถ้าคุณเลือกใช้ชื่อจริง จะใช้เพื่อให้เกียรติแก่งานของคุณ',
+'prefs-help-email' => 'à¹\84มà¹\88à¸\88ำà¹\80à¸\9bà¹\87à¸\99à¸\95à¹\89อà¸\87à¹\83สà¹\88à¸\97ีà¹\88อยูà¹\88อีà¹\80มล à¹\81à¸\95à¹\88à¸\88ำà¹\80à¸\9bà¹\87à¸\99สำหรัà¸\9aà¸\81ารà¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¹\80มืà¹\88อà¸\84ุà¸\93ลืมรหัสà¸\9cà¹\88าà¸\99',
 'prefs-help-email-others' => 'คุณยังสามารถเลือกให้ผู้อื่นติดต่อคุณโดยอีเมลผ่านลิงก์บนหน้าผู้ใช้หรือหน้าพูดคุยกับผู้ใช้ของคุณ
 ที่อยู่อีเมลของคุณไม่ถูกเปิดเผยเมื่อผู้ใช้อื่นติดต่อคุณ',
 'prefs-help-email-required' => 'ต้องการที่อยู่อีเมล',
 'prefs-info' => 'ข้อมูลเบื้องต้น',
-'prefs-i18n' => 'ระà¸\9aà¸\9aภาษาหรือà¹\80à¸\82à¸\95à¸\9eืà¹\89à¸\99à¸\97ีà¹\88',
+'prefs-i18n' => 'สาà¸\81ลวิวัà¸\95à¸\99à¹\8c',
 'prefs-signature' => 'ลายเซ็น',
 'prefs-dateformat' => 'รูปแบบวันที่',
 'prefs-timeoffset' => 'ส่วนต่างเวลา',
-'prefs-advancedediting' => 'à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าขั้นสูง',
-'prefs-advancedrc' => 'à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าขั้นสูง',
-'prefs-advancedrendering' => 'à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าขั้นสูง',
-'prefs-advancedsearchoptions' => 'à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าขั้นสูง',
-'prefs-advancedwatchlist' => 'à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าขั้นสูง',
-'prefs-displayrc' => 'à¸\84à¹\88าà¸\81ารà¹\81สà¸\94à¸\87à¸\9cล',
-'prefs-displaysearchoptions' => 'à¸\84à¹\88าà¸\81ารà¹\81สà¸\94à¸\87à¸\9cล',
-'prefs-displaywatchlist' => 'à¸\84à¹\88าà¸\81ารà¹\81สà¸\94à¸\87à¸\9cล',
-'prefs-diffs' => 'à¹\81à¸\95à¸\81ต่าง',
+'prefs-advancedediting' => 'à¸\95ัวà¹\80ลือà¸\81ขั้นสูง',
+'prefs-advancedrc' => 'à¸\95ัวà¹\80ลือà¸\81ขั้นสูง',
+'prefs-advancedrendering' => 'à¸\95ัวà¹\80ลือà¸\81ขั้นสูง',
+'prefs-advancedsearchoptions' => 'à¸\95ัวà¹\80ลือà¸\81ขั้นสูง',
+'prefs-advancedwatchlist' => 'à¸\95ัวà¹\80ลือà¸\81ขั้นสูง',
+'prefs-displayrc' => 'à¸\95ัวà¹\80ลือà¸\81à¸\9cลà¹\81สà¸\94à¸\87',
+'prefs-displaysearchoptions' => 'à¸\95ัวà¹\80ลือà¸\81à¸\9cลà¹\81สà¸\94à¸\87',
+'prefs-displaywatchlist' => 'à¸\95ัวà¹\80ลือà¸\81à¸\9cลà¹\81สà¸\94à¸\87',
+'prefs-diffs' => 'à¸\9cลต่าง',
 
 # User preference: e-mail validation using jQuery
 'email-address-validity-valid' => 'ที่อยู่อีเมลดูถูกต้อง',
@@ -1330,14 +1360,14 @@ $1",
 'userrights-editusergroup' => 'แก้ไขกลุ่มผู้ใช้',
 'saveusergroups' => 'ตกลง',
 'userrights-groupsmember' => 'สมาชิกในกลุ่ม:',
-'userrights-groupsmember-auto' => 'สมาà¸\8aิà¸\81à¹\82à¸\94ยà¸\99ัยของ:',
-'userrights-groups-help' => 'คุณสามารถเปลี่ยนแปลงกลุ่มที่ผู้ใช้รายนี้อยู่ใน:
-* à¸\81ลà¹\88อà¸\87à¸\97ีà¹\88à¸\96ูà¸\81à¹\80ลือà¸\81หมายà¸\84วามวà¹\88าผู้ใช้อยู่ในกลุ่มนั้น
-* à¸\81ลà¹\88อà¸\87à¸\97ีà¹\88à¹\84มà¹\88à¸\96ูà¸\81à¹\80ลือà¸\81หมายà¸\84วามวà¹\88าผู้ใช้ไม่ได้อยู่ในกลุ่มนั้น
-* à¹\80à¸\84รืà¹\88อà¸\87หมาย * à¸\8aีà¹\89วà¹\88าà¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¹\80อาà¸\81ลุà¹\88มà¸\99ัà¹\89à¸\99ออà¸\81à¹\84à¸\94à¹\89à¹\80มืà¹\88อà¹\83à¸\94à¸\81à¹\87à¸\95ามà¸\97ีà¹\88คุณเพิ่มกลุ่มนั้นไปแล้ว หรือกลับกัน',
+'userrights-groupsmember-auto' => 'สมาà¸\8aิà¸\81à¹\82à¸\94ยà¸\9bริยายของ:',
+'userrights-groups-help' => 'คุณสามารถเปลี่ยนแปลงกลุ่มที่ผู้ใช้รายนี้อยู่:
+* à¸\81ลà¹\88อà¸\87à¸\97ีà¹\88มีà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\96ูà¸\81 à¸«à¸¡à¸²à¸¢à¸\84วามวà¹\88า ผู้ใช้อยู่ในกลุ่มนั้น
+* à¸\81ลà¹\88อà¸\87à¸\97ีà¹\88à¹\84มà¹\88มีà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\96ูà¸\81 à¸«à¸¡à¸²à¸¢à¸\84วามวà¹\88า ผู้ใช้ไม่ได้อยู่ในกลุ่มนั้น
+* à¹\80à¸\84รืà¹\88อà¸\87หมาย * à¸\8aีà¹\89วà¹\88าà¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¸\99ำà¸\81ลุà¹\88มà¸\99ัà¹\89à¸\99ออà¸\81à¹\84à¸\94à¹\89à¹\80มืà¹\88อคุณเพิ่มกลุ่มนั้นไปแล้ว หรือกลับกัน',
 'userrights-reason' => 'เหตุผล:',
-'userrights-no-interwiki' => 'à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aสิà¸\97à¸\98ิà¹\83à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82สิà¸\97à¸\98ิà¸\82อà¸\87ผู้ใช้บนวิกิอื่น',
-'userrights-nodatabase' => 'ไม่มีฐานข้อมูล $1 อยู่ หรือ ฐานข้อมูลอยู่บนเครื่องอื่น',
+'userrights-no-interwiki' => 'à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aสิà¸\97à¸\98ิà¹\81à¸\81à¹\89à¹\84à¸\82สิà¸\97à¸\98ิผู้ใช้บนวิกิอื่น',
+'userrights-nodatabase' => 'ไม่มีฐานข้อมูล $1 อยู่ หรือฐานข้อมูลอยู่บนเครื่องอื่น',
 'userrights-nologin' => 'คุณต้อง[[Special:UserLogin|ล็อกอิน]]ด้วยบัญชีผู้ดูแลระบบก่อน จึงจะกำหนดสิทธิผู้ใช้ได้',
 'userrights-notallowed' => 'บัญชีของคุณไม่ได้รับอนุญาตให้เพิ่มหรือลดสิทธิของผู้ใช้',
 'userrights-changeable-col' => 'กลุ่มที่คุณสามารถเปลี่ยนได้',
@@ -1345,27 +1375,27 @@ $1",
 
 # Groups
 'group' => 'กลุ่ม:',
-'group-user' => 'ผู้ใช้ใหม่',
+'group-user' => 'ผู้ใช้',
 'group-autoconfirmed' => 'ผู้ใช้ทั่วไป',
 'group-bot' => 'บอต',
-'group-sysop' => 'ผู้ดูแล',
+'group-sysop' => 'ผู้ดูแลระบบ',
 'group-bureaucrat' => 'ผู้ดูแลสิทธิแต่งตั้ง',
-'group-suppress' => 'à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\94ัà¸\9aสูà¸\87',
+'group-suppress' => 'à¸\9cูà¹\89à¸\94ูà¹\81ลà¸\9bระวัà¸\95ิ',
 'group-all' => '(ทั้งหมด)',
 
-'group-user-member' => '{{GENDER:$1|ผู้ใช้ใหม่}}',
-'group-autoconfirmed-member' => 'ผู้ใช้ทั่วไป',
+'group-user-member' => '{{GENDER:$1|ผู้ใช้}}',
+'group-autoconfirmed-member' => '{{GENDER:$1|ผู้ใช้ทั่วไป}}',
 'group-bot-member' => '{{GENDER:$1|บอต}}',
 'group-sysop-member' => '{{GENDER:$1|ผู้ดูแลระบบ}}',
 'group-bureaucrat-member' => '{{GENDER:$1|ผู้ดูแลสิทธิแต่งตั้ง}}',
-'group-suppress-member' => '{{GENDER:$1|oversight}}',
+'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}}:à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\94ัà¸\9aสูà¸\87',
+'grouppage-suppress' => '{{ns:project}}:à¸\9cูà¹\89à¸\94ูà¹\81ลà¸\9bระวัà¸\95ิ',
 
 # Rights
 'right-read' => 'อ่านหน้า',
@@ -1373,7 +1403,7 @@ $1",
 'right-createpage' => 'สร้างหน้า (ที่ไม่ใช่หน้าอภิปราย)',
 'right-createtalk' => 'สร้างหน้าอภิปราย',
 'right-createaccount' => 'สร้างบัญชีผู้ใช้ใหม่',
-'right-minoredit' => 'ทำเครื่องหมายการแก้ไขเล็กน้อย',
+'right-minoredit' => 'à¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¹\80ลà¹\87à¸\81à¸\99à¹\89อย',
 'right-move' => 'ย้ายหน้า',
 'right-move-subpages' => 'ย้ายหน้าพร้อมหน้าย่อย',
 'right-move-rootuserpages' => 'ย้ายหน้าผู้ใช้หลัก',
@@ -1386,42 +1416,42 @@ $1",
 'right-upload_by_url' => 'อัปโหลดไฟล์จากยูอาร์แอล',
 'right-purge' => 'ล้างแคชของเว็บไซต์โดยไม่มีการยืนยัน',
 'right-autoconfirmed' => 'แก้ไขหน้าที่ถูกกึ่งล็อก',
-'right-bot' => 'à¸\81ำหà¸\99à¸\94วà¹\88าà¹\80à¸\9bà¹\87à¸\99à¸\81ระà¸\9aวà¸\99à¸\81ารอัà¸\95à¹\82à¸\99มัà¸\95ิ',
-'right-nominornewtalk' => 'à¹\84มà¹\88มีà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¹\80ลà¹\87à¸\81à¸\99à¹\89อยà¸\97ีà¹\88หà¸\99à¹\89าสà¸\99à¸\97à¸\99าà¸\97ีà¹\88à¸\97ำà¹\83หà¹\89à¸\81ารà¹\80à¸\95ือà¸\99ข้อความใหม่ปรากฏ',
+'right-bot' => 'กำหนดเป็นกระบวนการอัตโนมัติ',
+'right-nominornewtalk' => 'à¹\84มà¹\88มีà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¹\80ลà¹\87à¸\81à¸\99à¹\89อยà¹\83à¸\99หà¸\99à¹\89าอภิà¸\9bรายà¸\97ีà¹\88à¸\97ำà¹\83หà¹\89à¸\81ารà¹\81à¸\88à¹\89à¸\87ข้อความใหม่ปรากฏ',
 'right-apihighlimits' => 'ใช้ข้อจำกัดที่สูงขึ้นในคำสั่งเอพีไอ',
 'right-writeapi' => 'ใช้การเขียนเอพีไอ',
 'right-delete' => 'ลบหน้า',
 'right-bigdelete' => 'ลบหน้าที่มีประวัติขนาดใหญ่',
-'right-deletelogentry' => 'ลà¸\9aà¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99รายà¸\81ารปูมที่เจาะจง',
-'right-deleterevision' => 'ลà¸\9aà¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99รุà¹\88à¸\99à¸\97ีà¹\88à¹\80à¸\88าะà¸\88à¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\95à¹\88าà¸\87 à¹\86',
-'right-deletedhistory' => 'à¸\94ูรายà¸\81ารประวัติที่ถูกลบ โดยไม่มีข้อความที่เกี่ยวข้อง',
-'right-deletedtext' => 'à¹\80รียà¸\81à¸\94ูà¸\82à¹\89อà¸\84วามà¸\97ีà¹\88à¸\96ูà¸\81ลà¸\9aà¹\81ละà¸\84วามเปลี่ยนแปลงระหว่างรุ่นที่ถูกลบ',
+'right-deletelogentry' => 'ลà¸\9aà¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99หà¸\99à¹\88วยปูมที่เจาะจง',
+'right-deleterevision' => 'ลà¸\9aà¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99รุà¹\88à¸\99à¸\88ำà¹\80à¸\9eาะà¸\82อà¸\87หà¸\99à¹\89า',
+'right-deletedhistory' => 'à¸\94ูหà¸\99à¹\88วยประวัติที่ถูกลบ โดยไม่มีข้อความที่เกี่ยวข้อง',
+'right-deletedtext' => 'à¸\94ูà¸\82à¹\89อà¸\84วามà¸\97ีà¹\88à¸\96ูà¸\81ลà¸\9aà¹\81ละà¸\81ารเปลี่ยนแปลงระหว่างรุ่นที่ถูกลบ',
 'right-browsearchive' => 'ค้นหาหน้าที่ถูกลบ',
-'right-undelete' => 'à¹\80รียà¸\81คืนหน้า',
+'right-undelete' => 'à¸\81ูà¹\89คืนหน้า',
 'right-suppressrevision' => 'ดูและกู้คืนรุ่นที่ซ่อนจากผู้ดูแลระบบ',
 'right-suppressionlog' => 'ดูปูมส่วนตัว',
-'right-block' => 'à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89อืà¹\88à¸\99มิà¹\83หà¹\89แก้ไข',
-'right-blockemail' => 'à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89มิà¹\83ห้ส่งอีเมล',
-'right-hideuser' => 'à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\81ละà¸\8bà¹\88อà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89อืà¹\88à¸\99เห็น',
-'right-ipblock-exempt' => 'à¸\9cà¹\88าà¸\99à¸\81ารà¸\9aลà¹\87อà¸\81หมายà¹\80ลà¸\82à¹\84อà¸\9eี à¸\9aลà¹\87อà¸\81à¹\81à¸\9aà¸\9aอัà¸\95à¹\82à¸\99มัà¸\95ิ à¹\81ละà¸\9aลà¹\87อà¸\81à¹\80à¸\9bà¹\87à¸\99ช่วง',
-'right-proxyunbannable' => 'à¸\9cà¹\88าà¸\99à¸\81ารà¸\9aลà¹\87อà¸\81à¹\81à¸\9aà¸\9aอัตโนมัติของพร็อกซี',
-'right-unblockself' => 'ยà¸\81à¹\80ลิà¸\81à¸\81ารบล็อกตนเอง',
+'right-block' => 'à¸\9aลà¹\87อà¸\81มิà¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89อืà¹\88à¸\99แก้ไข',
+'right-blockemail' => 'à¸\9aลà¹\87อà¸\81มิà¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8a้ส่งอีเมล',
+'right-hideuser' => 'à¸\9aลà¹\87อà¸\81à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89 à¸\8bà¹\88อà¸\99à¹\84มà¹\88à¹\83หà¹\89สาà¸\98ารà¸\93ะเห็น',
+'right-ipblock-exempt' => 'อà¹\89อมà¸\81ารà¸\9aลà¹\87อà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี à¸\9aลà¹\87อà¸\81อัà¸\95à¹\82à¸\99มัà¸\95ิ à¹\81ละà¸\9aลà¹\87อà¸\81ช่วง',
+'right-proxyunbannable' => 'à¹\80ลีà¹\88ยà¸\87à¸\81ารà¸\9aลà¹\87อà¸\81อัตโนมัติของพร็อกซี',
+'right-unblockself' => 'à¸\9bลà¸\94บล็อกตนเอง',
 'right-protect' => 'เปลี่ยนระดับการล็อกและแก้ไขหน้าที่ถูกล็อก',
-'right-editprotected' => 'à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81ลà¹\87อà¸\81 (ที่ไม่ล็อกแบบสืบทอด)',
-'right-editinterface' => 'à¹\81à¸\81à¹\89à¹\84à¸\82อิà¸\99à¹\80à¸\95อรà¹\8cà¹\80à¸\9fà¸\8bà¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89',
-'right-editusercssjs' => 'แก้ไข CSS และ JS ของผู้ใช้คนอื่น',
-'right-editusercss' => 'แก้ไข CSS ของผู้ใช้คนอื่น',
-'right-edituserjs' => 'แก้ไข JS ของผู้ใช้คนอื่น',
-'right-rollback' => 'ยà¹\89อà¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89ลà¹\88าสุà¸\94à¸\97ีà¹\88à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¹\82à¸\94ยà¹\80à¸\89à¸\9eาะอยà¹\88าà¸\87รวà¸\94à¹\80รà¹\87ว',
+'right-editprotected' => 'หà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81ลà¹\87อà¸\81à¹\80à¸\95à¹\87มà¸\97ีà¹\88 (ที่ไม่ล็อกแบบสืบทอด)',
+'right-editinterface' => 'แก้ไขอินเตอร์เฟซผู้ใช้',
+'right-editusercssjs' => 'แก้ไขไฟล์ CSS และจาวาสคริปต์ของผู้ใช้อื่น',
+'right-editusercss' => 'แก้ไขไฟล์ CSS ของผู้ใช้อื่น',
+'right-edituserjs' => 'แก้ไขไฟล์จาวาสคริปต์ของผู้ใช้อื่น',
+'right-rollback' => 'ย้อนการแก้ไขของผู้ใช้ล่าสุดที่แก้ไขหน้าเฉพาะอย่างรวดเร็ว',
 'right-markbotedits' => 'ทำเครื่องหมายการย้อนว่าเป็นการแก้ไขโดยบอต',
-'right-noratelimit' => 'à¹\84มà¹\88มีà¸\9cลà¸\81ระà¸\97à¸\9aà¸\88าà¸\81à¸\81ารà¸\88ำà¸\81ัà¸\94สิà¸\97à¸\98ิà¸\95ามà¹\80วลา',
+'right-noratelimit' => 'à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aà¸\9cลà¸\81ระà¸\97à¸\9aà¸\88าà¸\81à¸\82ีà¸\94à¸\88ำà¸\81ัà¸\94อัà¸\95รา',
 'right-import' => 'นำเข้าหน้าจากวิกิอื่น',
 'right-importupload' => 'นำเข้าหน้าจากไฟล์ที่อัปโหลด',
 'right-patrol' => 'ทำเครื่องหมายการแก้ไขของผู้อื่นว่าตรวจสอบแล้ว',
-'right-autopatrol' => 'à¸\95ัà¹\89à¸\87à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\95à¸\99à¹\80อà¸\87วà¹\88าตรวจสอบแล้วอัตโนมัติ',
+'right-autopatrol' => 'à¹\83หà¹\89à¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\95à¸\99à¹\80อà¸\87à¹\80à¸\9bà¹\87à¸\99ตรวจสอบแล้วอัตโนมัติ',
 'right-patrolmarks' => 'ดูการเปลี่ยนแปลงล่าสุดของการทำเครื่องหมายตรวจสอบ',
 'right-unwatchedpages' => 'ดูรายการหน้าที่ไม่มีผู้เฝ้าดู',
-'right-mergehistory' => 'รวมà¸\9bระวัà¸\95ิà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89า',
+'right-mergehistory' => 'รวมประวัติหน้า',
 'right-userrights' => 'แก้ไขสิทธิผู้ใช้ทั้งหมด',
 'right-userrights-interwiki' => 'แก้ไขสิทธิผู้ใช้ของผู้ใช้บนวิกิอื่น',
 'right-siteadmin' => 'ล็อกและปลดล็อกฐานข้อมูล',
@@ -1430,8 +1460,8 @@ $1",
 'right-passwordreset' => 'ดูอีเมลตั้งรหัสผ่านใหม่',
 
 # Special:Log/newusers
-'newuserlogpage' => 'à¸\9bูมà¸\81ารสรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89',
-'newuserlogpagetext' => 'à¸\99ีà¹\88à¸\84ือà¸\9bูมà¸\81ารสรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89',
+'newuserlogpage' => 'ปูมการสร้างผู้ใช้',
+'newuserlogpagetext' => 'นี่คือปูมการสร้างผู้ใช้',
 
 # User rights log
 'rightslog' => 'ปูมสิทธิผู้ใช้',
@@ -1443,7 +1473,7 @@ $1",
 'action-createpage' => 'สร้างหน้า',
 'action-createtalk' => 'สร้างหน้าอภิปราย',
 'action-createaccount' => 'สร้างบัญชีผู้ใช้นี้',
-'action-minoredit' => 'เป็นการแก้ไขเล็กน้อย',
+'action-minoredit' => 'à¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¹\80ลà¹\87à¸\81à¸\99à¹\89อย',
 'action-move' => 'ย้ายหน้านี้',
 'action-move-subpages' => 'ย้ายหน้านี้ รวมทั้งหน้าย่อย',
 'action-move-rootuserpages' => 'ย้ายหน้าผู้ใช้หลัก',
@@ -1458,18 +1488,19 @@ $1",
 'action-deletedhistory' => 'ดูประวัติที่ถูกลบของหน้านี้',
 'action-browsearchive' => 'ค้นหาหน้าที่ถูกลบ',
 'action-undelete' => 'กู้คืนหน้านี้',
-'action-suppressrevision' => 'à¸\95รวà¸\88à¸\94ูและกู้คืนรุ่นที่ซ่อนอยู่นี้',
-'action-suppressionlog' => 'ดูปูมส่วนตัว',
+'action-suppressrevision' => 'à¸\97à¸\9aà¸\97วà¸\99และกู้คืนรุ่นที่ซ่อนอยู่นี้',
+'action-suppressionlog' => 'ดูปูมส่วนตัวนี้',
 'action-block' => 'บล็อกผู้ใช้รายนี้มิให้แก้ไข',
 'action-protect' => 'เปลี่ยนระดับการล็อกสำหรับหน้านี้',
+'action-rollback' => 'ย้อนการแก้ไขของผู้ใช้ล่าสุดที่แก้ไขหน้าเฉพาะอย่างรวดเร็ว',
 'action-import' => 'นำเข้าหน้านี้จากวิกิอื่น',
-'action-importupload' => 'à¸\99ำà¹\80à¸\82à¹\89าหà¸\99à¹\89าà¸\99ีà¹\89à¸\88าà¸\81à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88อัà¸\9bà¹\82หลà¸\94à¹\81ลà¹\89ว',
-'action-patrol' => 'ทำเครื่องหมายการแก้ไขของผู้ใช้อื่นว่าตรวจแล้ว',
-'action-autopatrol' => 'ทำเครื่องหมายการแก้ไขของคุณว่าตรวจแล้ว',
+'action-importupload' => 'à¸\99ำà¹\80à¸\82à¹\89าหà¸\99à¹\89าà¸\99ีà¹\89à¸\88าà¸\81à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8c',
+'action-patrol' => 'à¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89อืà¹\88à¸\99วà¹\88าà¸\95รวà¸\88สอà¸\9aà¹\81ลà¹\89ว',
+'action-autopatrol' => 'à¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\84ุà¸\93วà¹\88าà¸\95รวà¸\88สอà¸\9aà¹\81ลà¹\89ว',
 'action-unwatchedpages' => 'ดูรายการหน้าที่ไม่มีผู้เฝ้าดู',
 'action-mergehistory' => 'รวมประวัติหน้านี้',
 'action-userrights' => 'แก้ไขสิทธิผู้ใช้ทั้งหมด',
-'action-userrights-interwiki' => 'à¹\81à¸\81à¹\89à¹\84à¸\82สิà¸\97à¸\98ิà¸\9cูà¹\89à¹\83à¸\8aà¹\89สำหรัà¸\9aวิà¸\81ิà¸\99ีà¹\89',
+'action-userrights-interwiki' => 'à¹\81à¸\81à¹\89à¹\84à¸\82สิà¸\97à¸\98ิà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\9aà¸\99วิà¸\81ิอืà¹\88à¸\99',
 'action-siteadmin' => 'ล็อกหรือปลดล็อกฐานข้อมูล',
 'action-sendemail' => 'ส่งอีเมล',
 
@@ -1477,15 +1508,15 @@ $1",
 'nchanges' => '$1 การแก้ไข',
 'recentchanges' => 'ปรับปรุงล่าสุด',
 'recentchanges-legend' => 'ตัวเลือกปรับปรุงล่าสุด',
-'recentchanges-summary' => 'à¹\83à¸\99หà¸\99à¹\89าà¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99รายà¸\81ารลà¹\88าสุà¸\94à¸\97ีà¹\88มีà¸\81ารà¸\9bรัà¸\9aà¸\9bรุà¸\87',
-'recentchanges-feed-description' => 'à¸\9fีà¸\94à¸\99ีà¹\89à¹\81สà¸\94à¸\87à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87ลà¹\88าสุà¸\94',
-'recentchanges-label-newpage' => 'à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99à¸\81ารสรà¹\89าà¸\87หà¸\99à¹\89าà¹\83หมà¹\88',
+'recentchanges-summary' => 'à¹\83à¸\99หà¸\99à¹\89าà¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99รายà¸\81ารà¸\81ารà¸\9bรัà¸\9aà¸\9bรุà¸\87ลà¹\88าสุà¸\94à¸\9aà¸\99วิà¸\81ิà¸\99ีà¹\89',
+'recentchanges-feed-description' => 'à¸\95ิà¸\94à¸\95ามà¸\81ารà¸\9bรัà¸\9aà¸\9bรุà¸\87ลà¹\88าสุà¸\94à¹\83à¸\99วิà¸\81ิà¸\99ีà¹\89à¹\83à¸\99à¸\9fีà¸\94à¸\99ีà¹\89',
+'recentchanges-label-newpage' => 'การแก้ไขนี้สร้างหน้าใหม่',
 'recentchanges-label-minor' => 'เป็นการแก้ไขเล็กน้อย',
 'recentchanges-label-bot' => 'การแก้ไขนี้กระทำโดยบอต',
 'recentchanges-label-unpatrolled' => 'การแก้ไขนี้ยังไม่ได้ตรวจสอบ',
 'rcnote' => "รายการด้านล่างคือการแก้ไข {{PLURAL:$1|'''1''' รายการ|ล่าสุด '''$1''' รายการ}} ในช่วง '''$2''' วันที่ผ่านมา จนถึง $5, $4",
-'rcnotefrom' => "à¹\81สà¸\94à¸\87à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¸\95ัà¹\89à¸\87à¹\81à¸\95à¹\88 '''$2''' (à¹\81สà¸\94à¸\87 '''$1''' รายการ)",
-'rclistfrom' => 'แสดงการเปลี่ยนแปลงตั้งแต่ $1',
+'rcnotefrom' => "à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¸\95ัà¹\89à¸\87à¹\81à¸\95à¹\88 '''$2''' (มาà¸\81สุà¸\94 '''$1''' รายการ)",
+'rclistfrom' => 'à¹\81สà¸\94à¸\87à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¹\83หมà¹\88à¹\80ริà¹\88มà¸\95ัà¹\89à¸\87à¹\81à¸\95à¹\88 $1',
 'rcshowhideminor' => '$1การแก้ไขเล็กน้อย',
 'rcshowhidebots' => '$1บอต',
 'rcshowhideliu' => '$1ผู้ใช้ล็อกอิน',
@@ -1506,7 +1537,7 @@ $1",
 'rc_categories_any' => 'ใด ๆ',
 'rc-change-size-new' => '$1 ไบต์หลังปรับปรุง',
 'newsectionsummary' => '/* $1 */ หัวข้อใหม่',
-'rc-enhanced-expand' => 'à¹\81สà¸\94à¸\87รายละà¹\80อียà¸\94 (à¸\95à¹\89อà¸\87à¹\83à¸\8aà¹\89à¸\88าวาสà¸\84ริà¸\9bà¸\95à¹\8c)',
+'rc-enhanced-expand' => 'แสดงรายละเอียด (จาวาสคริปต์)',
 'rc-enhanced-hide' => 'ซ่อนรายละเอียด',
 'rc-old-title' => 'เดิมถูกสร้างในชื่อ "$1"',
 
@@ -1516,7 +1547,7 @@ $1",
 'recentchangeslinked-toolbox' => 'การปรับปรุงที่เกี่ยวโยง',
 'recentchangeslinked-title' => 'การปรับปรุงที่โยงมายัง "$1"',
 'recentchangeslinked-noresult' => 'ไม่มีการเปลี่ยนแปลงในหน้าที่ถูกโยงไป ในช่วงเวลาที่กำหนด',
-'recentchangeslinked-summary' => "หà¸\99à¹\89าà¸\99ีà¹\89à¹\81สà¸\94à¸\87รายการปรับปรุงล่าสุดของหน้าที่ถูกโยงไป (หรือไปยังหน้าต่าง ๆ ของหมวดหมู่ที่กำหนด) โดยหน้าที่อยู่ใน[[Special:Watchlist|รายการเฝ้าดู]]แสดงเป็น'''ตัวหนา'''",
+'recentchangeslinked-summary' => "หà¸\99à¹\89าà¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99รายการปรับปรุงล่าสุดของหน้าที่ถูกโยงไป (หรือไปยังหน้าต่าง ๆ ของหมวดหมู่ที่กำหนด) โดยหน้าที่อยู่ใน[[Special:Watchlist|รายการเฝ้าดู]]แสดงเป็น'''ตัวหนา'''",
 'recentchangeslinked-page' => 'ชื่อหน้า:',
 'recentchangeslinked-to' => 'แสดงการเปลี่ยนแปลงที่เชื่อมโยงมายังหน้านี้แทน',
 
@@ -1524,52 +1555,53 @@ $1",
 'upload' => 'อัปโหลดไฟล์',
 'uploadbtn' => 'อัปโหลดไฟล์',
 'reuploaddesc' => 'ยกเลิกการอัปโหลดและกลับไปยังแบบอัปโหลด',
-'upload-tryagain' => 'สà¹\88à¸\87à¸\84ำอà¸\98ิà¸\9aายà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\9bรัà¸\9aà¹\81à¸\95à¹\88à¸\87แล้ว',
+'upload-tryagain' => 'สà¹\88à¸\87à¸\84ำอà¸\98ิà¸\9aายà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\94ัà¸\94à¹\81à¸\9bรแล้ว',
 'uploadnologin' => 'ไม่ได้ล็อกอิน',
 'uploadnologintext' => 'ต้อง[[Special:UserLogin|ล็อกอิน]]ก่อนจึงจะอัปโหลดไฟล์ได้',
 'upload_directory_missing' => 'ไดเรกทอรีสำหรับอัปโหลด ($1) หายไป และเว็บเซิร์ฟเวอร์ไม่สามารถสร้างได้',
-'upload_directory_read_only' => 'à¹\84มà¹\88สามารà¸\96à¹\80à¸\81à¹\87à¸\9aà¸\82à¹\89อมูลà¹\83à¸\99à¹\84à¸\94à¹\80รà¸\81à¸\97อรี ($1) à¸\9bัà¸\8dหาà¹\80à¸\81ิà¸\94à¸\97ีà¹\88à¹\80วà¹\87à¸\9aà¹\80à¸\8bิรà¹\8cà¸\9fà¹\80วอรà¹\8c',
-'uploaderror' => 'à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\80à¸\81ิà¸\94à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94',
+'upload_directory_read_only' => 'à¹\80วà¹\87à¸\9aà¹\80à¸\8bิรà¹\8cà¸\9fà¹\80วอรà¹\8cà¹\84มà¹\88สามารà¸\96à¹\80à¸\81à¹\87à¸\9aà¸\82à¹\89อมูลà¹\83à¸\99à¹\84à¸\94à¹\80รà¸\81à¸\97อรี ($1)',
+'uploaderror' => 'การอัปโหลดผิดพลาด',
 'upload-recreate-warning' => "'''คำเตือน: ไฟล์ชื่อนั้นถูกลบหรือเปลี่ยนชื่อแล้ว'''
 
 ปูมการลบและปูมการย้ายของหน้านี้ถูกนำมาไว้ด้านล่างเพื่อความสะดวก:",
 'uploadtext' => "กรุณาใช้แบบด้านล่างในการอัปโหลดไฟล์
-สำหรัà¸\9aà¸\81ารà¸\94ูหรือà¸\81ารà¸\84à¹\89à¸\99หาà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¹\80à¸\84ยอัà¸\9bà¹\82หลà¸\94à¸\81à¹\88อà¸\99หà¸\99à¹\89าà¸\99ีà¹\89 à¹\83หà¹\89à¹\84à¸\9bà¸\97ีà¹\88[[Special:FileList|รายà¸\8aืà¹\88อไฟล์ที่ถูกอัปโหลด]] การอัปโหลดและการอัปโหลดซ้ำดูได้ที่[[Special:Log/upload|ปูมการอัปโหลด]] และการลบไฟล์ดูได้ที่[[Special:Log/delete|ปูมการลบ]]
+สำหรัà¸\9aà¸\81ารà¸\94ูหรือà¸\81ารà¸\84à¹\89à¸\99หาà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¹\80à¸\84ยอัà¸\9bà¹\82หลà¸\94à¸\81à¹\88อà¸\99หà¸\99à¹\89าà¸\99ีà¹\89 à¹\83หà¹\89à¹\84à¸\9bà¸\97ีà¹\88[[Special:FileList|รายà¸\81ารไฟล์ที่ถูกอัปโหลด]] การอัปโหลดและการอัปโหลดซ้ำดูได้ที่[[Special:Log/upload|ปูมการอัปโหลด]] และการลบไฟล์ดูได้ที่[[Special:Log/delete|ปูมการลบ]]
 
 ถ้าต้องการแทรกไฟล์ลงในหน้าหนึ่ง ๆ ให้ใช้คำสั่งหนึ่งในรูปแบบต่อไปนี้
 * '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' เพื่อใช้รูปขนาดเต็ม
 * '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|ข้อความอธิบาย]]</nowiki></code>''' เพื่อใช้รูปย่อขนาดกว้าง 200 พิกเซลในกล่องที่จัดชิดซ้าย โดยมี \"ข้อความอธิบาย\" เป็นคำบรรยายใต้ภาพ
 * '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' สำหรับการเชื่อมโยงไฟล์โดยตรง โดยไม่ปรากฏไฟล์นั้นออกมา",
-'upload-permitted' => 'à¸\8aà¸\99ิà¸\94à¸\82อà¸\87à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88อà¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¹\83à¸\8aà¹\89à¹\84à¸\94à¹\89: $1',
-'upload-preferred' => 'à¸\8aà¸\99ิà¸\94à¸\82อà¸\87à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\84วรà¹\83à¸\8aà¹\89: $1',
-'upload-prohibited' => 'à¸\8aà¸\99ิà¸\94à¸\82อà¸\87à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¹\84มà¹\88อà¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¹\83à¸\8aà¹\89: $1',
+'upload-permitted' => 'à¸\8aà¸\99ิà¸\94à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88อà¸\99ุà¸\8dาà¸\95: $1',
+'upload-preferred' => 'ชนิดไฟล์ที่ควรใช้: $1',
+'upload-prohibited' => 'à¸\8aà¸\99ิà¸\94à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¹\84มà¹\88อà¸\99ุà¸\8dาà¸\95: $1',
 'uploadlog' => 'ปูมการอัปโหลด',
 'uploadlogpage' => 'ปูมการอัปโหลด',
-'uploadlogpagetext' => 'รายการแสดงไฟล์ที่อัปโหลดล่าสุด',
+'uploadlogpagetext' => 'ด้านล่างเป็นรายการการอัปโหลดไฟล์ล่าสุด
+ดูภาพรวมที่ [[Special:NewFiles|แกลอรีไฟล์ใหม่]]',
 'filename' => 'ชื่อไฟล์',
 'filedesc' => 'รายละเอียดไฟล์',
 'fileuploadsummary' => 'รายละเอียดไฟล์:',
-'filereuploadsummary' => 'à¹\84à¸\9fลà¹\8cà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87:',
+'filereuploadsummary' => 'à¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¹\84à¸\9fลà¹\8c:',
 'filestatus' => 'สถานะลิขสิทธิ์:',
 'filesource' => 'แหล่งที่มา:',
 'uploadedfiles' => 'ไฟล์ที่อัปโหลดแล้ว',
 'ignorewarning' => 'บันทึกไฟล์โดยละเลยคำเตือน',
-'ignorewarnings' => 'à¹\84มà¹\88à¹\81สà¸\94à¸\87à¸\84ำà¹\80à¸\95ือà¸\99',
+'ignorewarnings' => 'ละà¹\80ลยà¸\84ำà¹\80à¸\95ือà¸\99à¸\97ัà¹\89à¸\87หมà¸\94',
 'minlength1' => 'ชื่อไฟล์ต้องมีตัวอักษรอย่างน้อยหนึ่งตัว',
-'illegalfilename' => 'à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8c  "$1" à¸¡à¸µà¸\95ัวอัà¸\81ษรà¸\97ีà¹\88à¹\84มà¹\88อà¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¸\9bราà¸\81à¸\8fà¹\83à¸\99à¸\8aืà¹\88อ à¸\81รุà¸\93าà¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¹\81ละอัปโหลดอีกครั้ง',
+'illegalfilename' => 'à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8c  "$1" à¸¡à¸µà¸­à¸±à¸\81à¸\82ระà¸\97ีà¹\88à¹\84มà¹\88อà¸\99ุà¸\8dาà¸\95à¹\83à¸\99à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89า à¸\81รุà¸\93าà¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¹\81ละลอà¸\87อัปโหลดอีกครั้ง',
 'filename-toolong' => 'ชื่อไฟล์ไม่อาจยาวกว่า 240 ไบต์',
 'badfilename' => 'ชื่อไฟล์ถูกเปลี่ยนเป็น "$1"',
-'filetype-mime-mismatch' => 'นามสกุลไฟล์ ".$1" ไม่ตรงกับชนิด MIME ของแฟ้มที่ตรวจพบ ($2)',
+'filetype-mime-mismatch' => 'นามสกุลไฟล์ ".$1" ไม่ตรงกับชนิดไมม์ของไฟล์ที่ตรวจพบ ($2)',
 'filetype-badmime' => 'ไม่อนุญาตให้อัปโหลดไฟล์ที่เป็นไมม์ชนิด "$1"',
-'filetype-bad-ie-mime' => 'ไม่สามารถอัปโหลดไฟล์นี้เนื่องจาก Internet Explorer จะตรวจจับว่าเป็น "$1" ซึ่งเป็นชนิดไฟล์ที่ไม่อนุญาตและอาจเป็นอันตราย',
+'filetype-bad-ie-mime' => 'ไม่สามารถอัปโหลดไฟล์นี้เนื่องจากอินเทอร์เน็ตเอกซ์พลอเรอร์จะตรวจจับว่าเป็น "$1" ซึ่งเป็นชนิดไฟล์ที่ไม่อนุญาตและอาจเป็นอันตราย',
 'filetype-unwanted-type' => "{{PLURAL:\$3|ไฟล์|ไฟล์}}ชนิด '''\".\$1\"''' เป็นไฟล์ที่ไม่สามารถอัปโหลดได้ ไฟล์ที่สามารถใช้ได้ ได้แก่ \$2",
 'filetype-banned-type' => '\'\'\'".$1"\'\'\' {{PLURAL: $4|เป็นชนิดไฟล์ที่ไม่อนุญาต|เป็นชนิดไฟล์ที่ไม่อนุญาต}}
-{{PLURAL: $3|ชนิดไฟล์|ชนิดไฟล์}}ที่อนุญาตคือ $2',
+{{PLURAL:$3|ชนิดไฟล์|ชนิดไฟล์}}ที่อนุญาตคือ $2',
 'filetype-missing' => 'นามสกุลไฟล์หายไป (เช่น ".jpg")',
-'empty-file' => 'à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\84ุà¸\93สà¹\88à¸\87มาà¸\99ัà¹\89à¸\99à¹\84มà¹\88มีà¸\82à¹\89อมูล',
+'empty-file' => 'à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\84ุà¸\93สà¹\88à¸\87มาà¸\99ัà¹\89à¸\99วà¹\88าà¸\87',
 'file-too-large' => 'ไฟล์ที่คุณส่งมามีขนาดใหญ่เกินไป',
 'filename-tooshort' => 'ชื่อไฟล์สั้นเกินไป',
-'filetype-banned' => 'à¹\84à¸\9fลà¹\8cà¸\9bระà¹\80ภà¸\97นี้ถูกห้าม',
+'filetype-banned' => 'à¹\84à¸\9fลà¹\8cà¸\8aà¸\99ิà¸\94นี้ถูกห้าม',
 'verification-error' => 'ไฟล์นี้ไม่ผ่านการพิสูจน์ยืนยันไฟล์',
 'hookaborted' => 'สิ่งที่คุณพยายามปรับเปลี่ยนถูกยกเลิกโดยส่วนขยาย',
 'illegal-filename' => 'ชื่อไฟล์นี้ไม่ได้รับอนุญาต',
@@ -1577,57 +1609,58 @@ $1",
 'unknown-error' => 'เกิดข้อผิดพลาดไม่ทราบสาเหตุ',
 'tmp-create-error' => 'ไม่สามารถสร้างไฟล์ชั่วคราว',
 'tmp-write-error' => 'เกิดข้อผิดพลาดในการเขียนไฟล์ชั่วคราว',
-'large-file' => 'ไฟล์ไม่ควรมีขนาดใหญ่กว่า $1 ไฟล์นี้มีขนาด $2',
-'largefileserver' => 'à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89มีà¸\82à¸\99าà¸\94à¹\83หà¸\8dà¹\88à¸\81วà¹\88าà¸\84à¹\88าà¸\97ีà¹\88อà¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¹\83à¸\8aà¹\89à¹\84à¸\94à¹\89',
-'emptyfile' => 'à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88อัà¸\9bà¹\82หลà¸\94มาà¹\80หมือà¸\99à¹\84à¸\9fลà¹\8cวà¹\88าà¸\87 à¸­à¸²à¸\88à¹\80à¸\81ิà¸\94à¸\88าà¸\81à¸\9bัà¸\8dหาà¸\9eิมà¸\9eà¹\8cà¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¸\9cิà¸\94 à¸\81รุà¸\93าà¸\95รวà¸\88สอà¸\9aà¹\84à¸\9fลà¹\8cอีà¸\81à¸\84รัà¹\89à¸\87 à¹\81ละà¹\81à¸\99à¹\88à¹\83à¸\88วà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\97ีà¹\88à¸\88ะอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89',
-'windows-nonascii-filename' => 'วิà¸\81ิà¸\99ีà¹\89à¹\84มà¹\88รอà¸\87รัà¸\9aà¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88มีà¸\95ัวอัà¸\81ษรพิเศษ',
+'large-file' => 'à¹\81à¸\99ะà¸\99ำวà¹\88าà¹\84à¸\9fลà¹\8cà¹\84มà¹\88à¸\84วรมีà¸\82à¸\99าà¸\94à¹\83หà¸\8dà¹\88à¸\81วà¹\88า $1 à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89มีà¸\82à¸\99าà¸\94 $2',
+'largefileserver' => 'à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89มีà¸\82à¸\99าà¸\94à¹\83หà¸\8dà¹\88à¸\81วà¹\88าà¸\97ีà¹\88à¹\80à¸\8bิรà¹\8cà¸\9fà¹\80วอรà¹\8cอà¸\99ุà¸\8dาà¸\95',
+'emptyfile' => 'à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\84ุà¸\93อัà¸\9bà¹\82หลà¸\94à¹\80หมือà¸\99à¹\80à¸\9bà¹\87à¸\99à¹\84à¸\9fลà¹\8cวà¹\88าà¸\87 à¸­à¸²à¸\88à¹\80à¸\81ิà¸\94à¸\88าà¸\81à¸\9bัà¸\8dหาà¸\9eิมà¸\9eà¹\8cà¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¸\9cิà¸\94 à¸\81รุà¸\93าà¸\95รวà¸\88สอà¸\9aวà¹\88า à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89à¸\88ริà¸\87 à¹\86',
+'windows-nonascii-filename' => 'วิà¸\81ิà¸\99ีà¹\89à¹\84มà¹\88รอà¸\87รัà¸\9aà¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88มีอัà¸\81à¸\82ระพิเศษ',
 'fileexists' => 'มีไฟล์ชื่อนี้อยู่แล้ว กรุณาตรวจสอบ <strong>[[:$1]]</strong> หากคุณไม่แน่ใจว่าต้องการเปลี่ยนแปลงไฟล์นี้หรือไม่ [[$1|thumb]]',
-'filepageexists' => 'หà¸\99à¹\89าà¸\84ำอà¸\98ิà¸\9aายสำหรัà¸\9aà¹\84à¸\9fลà¹\8cà¸\99ีà¹\89à¹\84à¸\94à¹\89à¸\96ูà¸\81สรà¹\89าà¸\87à¹\84วà¹\89à¹\81ลà¹\89วà¸\97ีà¹\88 <strong>[[:$1]]</strong> à¹\81à¸\95à¹\88à¹\84à¸\9fลà¹\8cà¸\8aืà¹\88อà¸\99ีà¹\89à¹\84มà¹\88มีอยูà¹\88à¹\83à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99
-สาระสำà¸\84ัà¸\8dà¸\97ีà¹\88à¸\84ุà¸\93à¸\9aัà¸\99à¸\97ึกจะไม่ปรากฏบนหน้าคำอธิบาย
-à¹\80à¸\9eืà¹\88อà¹\83หà¹\89สาระสำà¸\84ัà¸\8dปรากฏขึ้น คุณจำเป็นต้องแก้ไขด้วยตนเอง
+'filepageexists' => 'หน้าคำอธิบายสำหรับไฟล์นี้ได้ถูกสร้างแล้วที่ <strong>[[:$1]]</strong> แต่ไฟล์ชื่อนี้ไม่มีอยู่ในปัจจุบัน
+à¸\84ำอà¸\98ิà¸\9aายอยà¹\88าà¸\87ยà¹\88อà¸\97ีà¹\88à¸\84ุà¸\93à¸\81รอกจะไม่ปรากฏบนหน้าคำอธิบาย
+à¹\80à¸\9eืà¹\88อà¹\83หà¹\89à¸\84ำอà¸\98ิà¸\9aายอยà¹\88าà¸\87ยà¹\88อปรากฏขึ้น คุณจำเป็นต้องแก้ไขด้วยตนเอง
 [[$1|thumb]]',
-'fileexists-extension' => 'à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¹\82หลà¸\94มีà¸\8aืà¹\88อà¹\83à¸\81ลà¹\89à¹\80à¸\84ียà¸\87: [[$2|thumb]]
+'fileexists-extension' => 'มีà¹\84à¸\9fลà¹\8cà¸\8aืà¹\88อà¸\84ลà¹\89ายà¸\81ัà¸\99: [[$2|thumb]]
 * ชื่อไฟล์ที่กำลังอัปโหลด: <strong>[[:$1]]</strong>
-* ชื่อไฟล์ที่มีอยู่แล้ว: <strong>[[:$2]]</strong>
-à¸\81รุà¸\93าà¹\80ลือà¸\81à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¹\83หมà¹\88',
-'fileexists-thumbnail-yes' => "ไฟล์นี้ดูเหมือนจะเป็นภาพที่ถูกลดขนาดมา ''(รูปย่อ)''
+* ชื่อไฟล์ที่มีอยู่: <strong>[[:$2]]</strong>
+à¸\81รุà¸\93าà¹\80ลือà¸\81à¸\8aืà¹\88ออืà¹\88à¸\99',
+'fileexists-thumbnail-yes' => "ไฟล์นี้ดูเหมือนจะเป็นภาพที่ถูกลดขนาด ''(รูปย่อ)''
 [[$1|thumb]]
 กรุณาตรวจสอบไฟล์ <strong>[[:$1]]</strong>
-à¸\96à¹\89าà¸\95รวà¸\88สอà¸\9aà¹\81ลà¹\89วà¹\81ละà¸\9eà¸\9aวà¹\88าà¹\80à¸\9bà¹\87à¸\99ภาà¸\9eà¹\80à¸\94ียวà¸\81ัà¸\99à¸\81ัà¸\9aภาà¸\9eต้นฉบับ ไฟล์นั้นไม่จำเป็นต้องอัปโหลดเพิ่ม",
+à¸\96à¹\89าà¸\95รวà¸\88สอà¸\9aà¹\81ลà¹\89วà¹\81ละà¸\9eà¸\9aวà¹\88าà¹\80à¸\9bà¹\87à¸\99ภาà¸\9eà¸\82à¸\99าà¸\94à¹\80à¸\94ียวà¸\81ัà¸\9aต้นฉบับ ไฟล์นั้นไม่จำเป็นต้องอัปโหลดเพิ่ม",
 'file-thumbnail-no' => "ชื่อไฟล์ขึ้นต้นด้วย <strong>$1</strong>
-ภาพนี้ดูเหมือนว่าจะเป็นภาพที่ถูกลดขนาดมา ''(thumbnail)''
-ถ้าคุณมีไฟล์ต้นฉบับขนาดใหญ่กว่านี้ กรุณาอัปโหลดไฟล์ต้นฉบับ หรือเปลี่ยนชื่อไฟล์ด้วย",
-'fileexists-forbidden' => 'ไฟล์ชื่อนี้มีอยู่แล้วในระบบ และไม่สามารถอัปโหลดทับได้
-หากคุณยังคงต้องการอัปโหลดไฟล์ของคุณ กรุณาย้อนกลับและใช้ชื่อใหม่ [[ไฟล์:$1|thumb|center|$1]]',
+ภาพนี้ดูเหมือนว่าจะเป็นภาพที่ถูกลดขนาด ''(thumbnail)''
+ถ้าคุณมีภาพนี้ในความละเอียดเต็ม ให้อัปโหลดภาพนี้ มิฉะนั้นแล้วโปรดเปลี่ยนชื่อไฟล์",
+'fileexists-forbidden' => 'มีไฟล์ชื่อนี้แล้ว และไม่สามารถเขียนทับได้
+หากคุณยังต้องการอัปโหลดไฟล์ของคุณ กรุณาย้อนกลับและใช้ชื่อใหม่ 
+[[ไฟล์:$1|thumb|center|$1]]',
 'fileexists-shared-forbidden' => 'ไฟล์ที่ใช้ชื่อนี้มีอยู่แล้วในระบบเก็บไฟล์ในส่วนกลาง
 ถ้าคุณยังคงต้องการอัปโหลดไฟล์ของคุณ กรุณาย้อนกลับไปตั้งชื่อใหม่
 [[File:$1|thumb|center|$1]]',
 'file-exists-duplicate' => 'ไฟล์นี้ซ้ำกับ{{PLURAL:$1|ไฟล์|ไฟล์}}ต่อไปนี้:',
-'file-deleted-duplicate' => 'à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\95รà¸\87à¸\81ัà¸\9aà¸\8aืà¹\88อà¸\99ีà¹\89 ([[:$1]]) à¹\80à¸\84ยà¸\96ูà¸\81ลà¸\9aà¹\84à¸\9bà¸\81à¹\88อà¸\99หà¸\99à¹\89า
+'file-deleted-duplicate' => 'à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¹\80หมือà¹\84à¸\9fลà¹\8cà¸\99ีà¹\89 ([[:$1]]) à¹\80à¸\84ยà¸\96ูà¸\81ลà¸\9aà¹\84à¸\9bà¸\81à¹\88อà¸\99หà¸\99à¹\89าà¸\99ีà¹\89à¹\81ลà¹\89ว
 คุณควรตรวจสอบว่าประวัติการลบของไฟล์ก่อนดำเนินการอัปโหลดใหม่',
 'uploadwarning' => 'คำเตือนการอัปโหลด',
 'uploadwarning-text' => 'กรุณาแก้ไขคำอธิบายไฟล์ด้านล่างนี้ แล้วลองใหม่อีกครั้ง',
 'savefile' => 'บันทึกไฟล์',
 'uploadedimage' => 'อัปโหลด "[[$1]]"',
 'overwroteimage' => 'อัปโหลดรุ่นใหม่ของ "[[$1]]"',
-'uploaddisabled' => 'à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99อัปโหลด',
-'copyuploaddisabled' => 'à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\82à¸\94ย URL à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99à¹\84วà¹\89',
-'uploadfromurl-queued' => 'à¸\81ารอัà¸\9eà¹\82หลà¸\94à¸\82อà¸\87à¸\84ุà¸\93à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\88ัà¸\94à¹\83à¸\99คิวแล้ว',
-'uploaddisabledtext' => 'à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8cà¸\96ูà¸\81à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99',
-'php-uploaddisabledtext' => 'à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8cà¸\96ูà¸\81à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99à¹\83à¸\99 PHP
+'uploaddisabled' => 'à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99à¸\81ารอัปโหลด',
+'copyuploaddisabled' => 'à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\82à¸\94ยยูอารà¹\8cà¹\81อล',
+'uploadfromurl-queued' => 'à¸\81ารอัà¸\9bà¹\82หลà¸\94à¸\82อà¸\87à¸\84ุà¸\93à¸\96ูà¸\81à¸\88ัà¸\94คิวแล้ว',
+'uploaddisabledtext' => 'à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8c',
+'php-uploaddisabledtext' => 'à¹\80à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8cà¹\83à¸\99à¸\9eีà¹\80อà¸\8aà¸\9eี
 กรุณาตรวจสอบการตั้งค่า file_uploads',
 'uploadscripted' => 'ไฟล์นี้มีส่วนประกอบของโค้ดเอชทีเอ็มแอลหรือสคริปต์ ซึ่งอาจก่อให้เกิดความผิดพลาดในการแสดงผลของเว็บเบราว์เซอร์',
 'uploadvirus' => 'ไฟล์นี้มีไวรัส! รายละเอียด: $1',
 'upload-source' => 'ไฟล์ต้นทาง',
 'sourcefilename' => 'ชื่อไฟล์ต้นทาง:',
-'sourceurl' => 'URL ที่มา:',
-'destfilename' => 'à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร:',
+'sourceurl' => 'ยูอาร์แอลที่มา:',
+'destfilename' => 'à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¸\9bลายà¸\97าà¸\87:',
 'upload-maxfilesize' => 'ขนาดไฟล์ที่ใหญ่ที่สุดที่อนุญาต: $1',
 'upload-description' => 'คำอธิบายไฟล์',
 'upload-options' => 'ตัวเลือกอัปโหลด',
 'watchthisupload' => 'เฝ้าดูไฟล์นี้',
-'filewasdeleted' => 'à¹\84à¸\9fลà¹\8cà¹\83à¸\99à¸\8aืà¹\88อà¸\99ีà¹\89à¹\84à¸\94à¹\89à¸\96ูà¸\81อัà¸\9bà¹\82หลà¸\94à¸\81à¹\88อà¸\99หà¸\99à¹\89าà¹\81ละà¸\96ูà¸\81ลà¸\9aà¹\84à¸\9bà¹\81ลà¹\89ว à¸\81รุà¸\93าà¸\95รวà¸\88สอà¸\9a $1 à¸\81à¹\88อà¸\99à¸\97ีà¹\88à¸\88ะอัà¸\9bà¹\82หลà¸\94à¹\83หมà¹\88อีกครั้ง',
-'filename-bad-prefix' => "à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\84ุà¸\93à¸\81ำลัà¸\87à¸\88ะอัà¸\9bà¹\82หลà¸\94à¹\80à¸\82à¹\89ามาà¸\99ีà¹\89มีà¸\8aืà¹\88อà¸\97ีà¹\88à¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99à¸\94à¹\89วย '''\"\$1\"''' à¸\8bึà¹\88à¸\87à¹\80à¸\9bà¹\87à¸\99à¸\8aืà¹\88อà¸\97ีà¹\88à¹\84มà¹\88สืà¹\88อà¸\84วามหมายà¹\83à¸\94 à¹\86 à¸\97ีà¹\88à¹\82à¸\94ยà¸\9bà¸\81à¸\95ิà¹\81ลà¹\89วà¸\8aืà¹\88อà¸\99ีà¹\89à¸\88ะà¸\96ูà¸\81à¸\95ัà¹\89à¸\87à¹\82à¸\94ยà¸\81ลà¹\89อà¸\87à¸\96à¹\88ายรูà¸\9bà¸\94ิà¸\88ิà¸\97ัลอัà¸\95à¹\82à¸\99มัà¸\95ิ à¸\81รุà¸\93าà¸\95ัà¹\89à¸\87à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¹\83หมà¹\88à¸\97ีà¹\88สื่อความหมายกว่าเดิม",
+'filewasdeleted' => 'à¹\84à¸\9fลà¹\8cà¸\8aืà¹\88อà¸\99ีà¹\89à¸\96ูà¸\81อัà¸\9bà¹\82หลà¸\94à¸\81à¹\88อà¸\99หà¸\99à¹\89าà¹\81ละà¸\96ูà¸\81ลà¸\9aà¹\84à¸\9bà¹\81ลà¹\89ว à¸\81รุà¸\93าà¸\95รวà¸\88สอà¸\9a $1 à¸\81à¹\88อà¸\99อัà¸\9bà¹\82หลà¸\94อีกครั้ง',
+'filename-bad-prefix' => "à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¸\84ุà¸\93à¸\81ำลัà¸\87อัà¸\9bà¹\82หลà¸\94à¸\82à¹\89à¸\99à¸\95à¹\89à¸\99à¸\94à¹\89วย '''\"\$1\"''' à¸\8bึà¹\88à¸\87à¹\80à¸\9bà¹\87à¸\99à¸\8aืà¹\88อà¸\97ีà¹\88à¹\84มà¹\88สืà¹\88อà¸\84วามหมายà¹\83à¸\94 à¹\86 à¸\97ีà¹\88à¹\82à¸\94ยà¸\9bà¸\81à¸\95ิà¹\81ลà¹\89วà¸\81ลà¹\89อà¸\87à¸\96à¹\88ายรูà¸\9bà¸\94ิà¸\88ิà¸\97ัลà¸\95ัà¹\89à¸\87à¹\83หà¹\89อัà¸\95à¹\82à¸\99มัà¸\95ิ à¸\81รุà¸\93าà¸\95ัà¹\89à¸\87à¸\8aืà¹\88อà¹\84à¸\9fลà¹\8cà¹\83หมà¹\88à¹\83หà¹\89สื่อความหมายกว่าเดิม",
 'upload-success-subj' => 'อัปโหลดสำเร็จ',
 'upload-success-msg' => 'การอัปโหลดของคุณจาก [$2] สำเร็จแล้ว และสามารถใช้ไฟล์ได้ที่นี่: [[:{{ns:file}}:$1]]',
 'upload-failure-subj' => 'ปัญหาการอัปโหลด',
@@ -1635,25 +1668,30 @@ $1",
 
 $1',
 'upload-warning-subj' => 'คำเตือนการอัปโหลด',
-'upload-warning-msg' => 'à¸\9eà¸\9aà¸\9bัà¸\8dหาà¸\81ารอัà¸\9bà¹\82หลà¸\94à¸\82อà¸\87à¸\84ุà¸\93à¸\88าà¸\81 [$2] à¸\84ุà¸\93อาà¸\88à¸\81ลัà¸\9aà¹\84à¸\9bยัà¸\87[[Special:Upload/stash/$1|à¸\9fอรà¹\8cมอัปโหลด]]เพื่อแก้ไขปัญหานี้',
+'upload-warning-msg' => 'à¸\9eà¸\9aà¸\9bัà¸\8dหาà¸\81ารอัà¸\9bà¹\82หลà¸\94à¸\82อà¸\87à¸\84ุà¸\93à¸\88าà¸\81 [$2] à¸\84ุà¸\93อาà¸\88à¸\81ลัà¸\9aà¹\84à¸\9bยัà¸\87[[Special:Upload/stash/$1|à¹\81à¸\9aà¸\9aอัปโหลด]]เพื่อแก้ไขปัญหานี้',
 
 'upload-proto-error' => 'โพรโทคอลไม่ถูกต้อง',
 'upload-proto-error-text' => 'การอัปโหลดโดยตรงจากเว็บต้องการยูอาร์แอลที่ขึ้นต้นด้วย <code>http://</code> หรือ <code>ftp://</code>',
 'upload-file-error' => 'เกิดความผิดพลาดภายใน',
-'upload-file-error-text' => 'เกิดความผิดพลาดภายใน จากปัญหาการสร้างไฟล์ชั่วคราวที่เซิร์ฟเวอร์ กรุณาติดต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]]',
-'upload-misc-error' => 'à¹\80à¸\81ิà¸\94à¸\9bัà¸\8dหาอัà¸\9bà¹\82หลà¸\94',
-'upload-misc-error-text' => 'à¹\80à¸\81ิà¸\94à¸\9bัà¸\8dหาระหวà¹\88าà¸\87à¸\81ารอัà¸\9bà¹\82หลà¸\94 à¸\81รุà¸\93าà¸\95รวà¸\88สอà¸\9aวà¹\88ายูอารà¹\8cà¹\81อลà¸\99ัà¹\89à¸\99à¸\96ูà¸\81à¸\95à¹\89อà¸\87 à¸\96à¹\89ายัà¸\87à¸\84à¸\87มีà¸\9bัà¸\8dหาà¹\83หà¹\89à¸\95ิà¸\94à¸\95à¹\88อà¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9a',
-'upload-too-many-redirects' => 'URL ที่ระบุมีการเปลี่ยนทางมากเกินไป',
+'upload-file-error-text' => 'เกิดความผิดพลาดภายในขณะพยายามสร้างไฟล์ชั่วคราวบนเซิร์ฟเวอร์ กรุณาติดต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]]',
+'upload-misc-error' => 'à¹\80à¸\81ิà¸\94à¸\84วามà¸\9cิà¸\94à¸\9eลาà¸\94à¹\83à¸\99à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\82à¸\94ยà¹\84มà¹\88à¸\97ราà¸\9aสาà¹\80หà¸\95ุ',
+'upload-misc-error-text' => 'à¹\80à¸\81ิà¸\94à¸\84วามà¸\9cิà¸\94à¸\9eลาà¸\94à¹\84มà¹\88à¸\97ราà¸\9aสาà¹\80หà¸\95ุระหวà¹\88าà¸\87อัà¸\9bà¹\82หลà¸\94 à¸\81รุà¸\93าà¸\95รวà¸\88สอà¸\9aวà¹\88ายูอารà¹\8cà¹\81อลà¸\99ัà¹\89à¸\99à¸\96ูà¸\81à¸\95à¹\89อà¸\87à¹\81ละà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¹\84à¸\94à¹\89 à¹\81ละลอà¸\87อีà¸\81à¸\84รัà¹\89à¸\87 à¸\96à¹\89ายัà¸\87มีà¸\9bัà¸\8dหา à¹\83หà¹\89à¸\95ิà¸\94à¸\95à¹\88อ[[Special:ListUsers/sysop|à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9a]]',
+'upload-too-many-redirects' => 'ยูอาร์แอลที่ระบุมีการเปลี่ยนทางมากเกินไป',
 'upload-unknown-size' => 'ไม่ทราบขนาด',
-'upload-http-error' => 'เกิดข้อผิดพลาด HTTP: $1',
+'upload-http-error' => 'เกิดข้อผิดพลาดเอชทีทีพี: $1',
+'upload-copy-upload-invalid-domain' => 'การอัปโหลดสำเนาไม่สามารถทำได้จากโดเมนนี้',
 
 # File backend
 'backend-fail-backup' => 'ไม่สามารถสำรองข้อมูลไฟล์ $1.',
-'backend-fail-notexists' => 'à¹\84มà¹\88à¸\9eà¸\9aà¹\84à¸\9fลà¹\8c $1 à¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร',
+'backend-fail-notexists' => 'à¹\84มà¹\88มีà¹\84à¸\9fลà¹\8c $1',
 'backend-fail-delete' => 'ไม่สามารถลบไฟล์ $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" ได้',
 
@@ -1676,9 +1714,9 @@ $1',
 เซิร์ฟเวอร์ของคุณอาจไม่ได้ถูกตั้งให้ส่งข้อมูลนี้
 หรือเซิร์ฟเวอร์อาจเป็นแบบ CGI-based และไม่สนับสนุนข้อมูล img_auth
 ดูที่ https://www.mediawiki.org/wiki/Manual:Image_Authorization',
-'img-auth-notindir' => 'à¸\97ีà¹\88อยูà¹\88à¸\97ีà¹\88รà¹\89อà¸\87à¸\82อà¹\84มà¹\88à¹\84à¸\94à¹\89อยูà¹\88à¹\83à¸\99à¹\84à¸\94à¹\80รà¹\87à¸\81à¸\97อรีอัà¸\9eà¹\82หลà¸\94à¸\97ีà¹\88à¸\81ำหà¸\99à¸\94à¹\84à¹\89วà¹\89',
+'img-auth-notindir' => 'ที่อยู่ที่ร้องขอไม่ได้อยู่ในไดเร็กทอรีอัพโหลดที่กำหนดไว้',
 'img-auth-badtitle' => 'ไม่สามารถสร้างชื่อเรื่องที่ถูกต้องจาก "$1" ได้',
-'img-auth-nologinnWL' => 'à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89ลà¸\87à¸\8aืà¹\88อà¹\80à¸\82à¹\89าà¹\83à¸\8aà¹\89และ "$1" ไม่ได้อยู่ในรายชื่อผู้ใช้ที่ดี (whitelist)',
+'img-auth-nologinnWL' => 'à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89ลà¹\87อà¸\81อิà¸\99และ "$1" ไม่ได้อยู่ในรายชื่อผู้ใช้ที่ดี (whitelist)',
 'img-auth-nofile' => 'ไม่มีไฟล์ "$1"',
 'img-auth-isdir' => 'คุณกำลังพยายามเข้าถึงไดเร็กทอรี "$1"
 ซึ่งคุณสามารถเข้าถึงได้เฉพาะไฟล์เท่านั้น',
@@ -1705,11 +1743,11 @@ $1',
 'upload-curl-error28' => 'เวลาอัปโหลดถูกตัด',
 'upload-curl-error28-text' => 'เว็บไซต์นี้ใช้เวลานานเกินไปในการเชื่อมต่อ กรุณาตรวจสอบว่าเว็บนี้ยังใช้งานได้ตามปกติ หรืออาจจะรอสักครู่แล้วลองอัปโหลดใหม่',
 
-'license' => 'ลิà¸\82สิà¸\97à¸\98ิà¹\8c:',
-'license-header' => 'à¸\81ารอà¸\99ุà¸\8dาà¸\95à¹\82à¸\94ยà¹\80à¸\88à¹\89าà¸\82อà¸\87ลิà¸\82สิà¸\97à¸\98ิà¹\8c',
+'license' => 'à¸\81ารอà¸\99ุà¸\8dาà¸\95à¹\83à¸\8aà¹\89สิà¸\97à¸\98ิ:',
+'license-header' => 'à¸\81ารอà¸\99ุà¸\8dาà¸\95à¹\83à¸\8aà¹\89สิà¸\97à¸\98ิ',
 'nolicense' => 'ไม่ได้เลือก',
 'license-nopreview' => '(ไม่สามารถแสดงตัวอย่าง)',
-'upload_source_url' => ' (ยูอารà¹\8cà¹\81อลà¸\97ีà¹\88à¸\9aุà¸\84à¸\84ลà¸\97ัà¹\88วà¹\84à¸\9bสามารถเข้าถึงได้)',
+'upload_source_url' => ' (ยูอารà¹\8cà¹\81อลà¸\96ูà¸\81à¸\95à¹\89อà¸\87à¸\97ีà¹\88สาà¸\98ารà¸\93ะสามารถเข้าถึงได้)',
 'upload_source_file' => ' (ไฟล์จากคอมพิวเตอร์คุณ)',
 
 # Special:ListFiles
@@ -1744,19 +1782,23 @@ $1',
 'filehist-comment' => 'ความเห็น',
 'filehist-missing' => 'ไฟล์หายไป',
 'imagelinks' => 'การใช้ไฟล์',
-'linkstoimage' => '$1 หน้าลิงก์มายังไฟล์นี้:',
-'linkstoimage-more' => 'à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89มีà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87มาà¸\81à¸\81วà¹\88า $1 à¹\81หà¹\88à¸\87
-รายà¸\81ารà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\81สà¸\94à¸\87à¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87 $1 à¹\81หà¹\88à¸\87แรกที่มายังไฟล์นี้เท่านั้น
-à¸\94ูà¹\80à¸\9eิà¹\88มà¹\84à¸\94à¹\89à¸\97ีà¹\88[[Special:WhatLinksHere/$2|รายà¸\8aืà¹\88อเต็ม]]',
-'nolinkstoimage' => 'à¹\84มà¹\88มีหà¸\99à¹\89าà¸\97ีà¹\88ลิà¸\87à¸\81à¹\8cมาไฟล์นี้',
-'morelinkstoimage' => 'à¸\94ู[[Special:WhatLinksHere/$1|หà¸\99à¹\89าà¸\97ีà¹\88ลิà¸\87à¸\81à¹\8c]]มายังไฟล์นี้เพิ่มเติม',
-'linkstoimage-redirect' => '$1 (à¹\81à¸\9fà¹\89มเปลี่ยนทาง) $2',
-'duplicatesoffile' => '$1 ไฟล์ต่อไปนี้ เป็นไฟล์เดียวกับไฟล์นี้ ([[Special:FileDuplicateSearch/$2|รายละเอียดเพิ่ม]]):',
+'linkstoimage' => 'มี $1 หน้าเชื่อมโยงมายังไฟล์นี้:',
+'linkstoimage-more' => 'à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89มีหà¸\99à¹\89าà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87มาà¸\81วà¹\88า $1 à¸«à¸\99à¹\89า
+รายà¸\81ารà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\81สà¸\94à¸\87à¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87 $1 à¸«à¸\99à¹\89าแรกที่มายังไฟล์นี้เท่านั้น
+à¸\94ูà¹\80à¸\9eิà¹\88มà¹\84à¸\94à¹\89à¸\97ีà¹\88[[Special:WhatLinksHere/$2|รายà¸\81ารเต็ม]]',
+'nolinkstoimage' => 'à¹\84มà¹\88มีหà¸\99à¹\89าà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87มายัà¸\87ไฟล์นี้',
+'morelinkstoimage' => 'à¸\94ู[[Special:WhatLinksHere/$1|à¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87]]มายังไฟล์นี้เพิ่มเติม',
+'linkstoimage-redirect' => '$1 (à¹\84à¸\9fลà¹\8cเปลี่ยนทาง) $2',
+'duplicatesoffile' => '$1 ไฟล์ต่อไปนี้ เป็นไฟล์เดียวกับไฟล์นี้ ([[Special:FileDuplicateSearch/$2|รายละเอียดเพิ่มเติม]]):',
 'sharedupload' => 'ไฟล์นี้มาจาก $1 และอาจมีการใช้ในโครงการอื่น',
-'sharedupload-desc-there' => 'ไฟล์นี้มาจาก $1 และอาจถูกใช้บนโครงการอื่น ๆ
-กรุณาดู [หน้าคำอธิบายของไฟล์ $2] สำหรับข้อมูลเพิ่มเติม',
+'sharedupload-desc-there' => 'ไฟล์นี้มาจาก $1 และอาจถูกใช้บนโครงการอื่น
+กรุณาดู[หน้าคำอธิบายไฟล์ $2] สำหรับข้อมูลเพิ่มเติม',
 'sharedupload-desc-here' => 'ไฟล์นี้มาจาก $1 และอาจมีใช้ในโครงการอื่น
-คำอธิบายใน[$2 หน้าไฟล์]ได้แสดงไว้ข้างล่างนี้',
+คำอธิบายใน[$2 หน้าคำอธิบายไฟล์]แสดงไว้ข้างล่างนี้',
+'sharedupload-desc-edit' => 'ไฟล์นี้มาจาก $1 และอาจมีใช้ในโครงการอื่น
+หากคุณต้องการแก้ไขคำอธิบาย ให้ดำเนินการบน[$2 หน้าคำอธิบายไฟล์]',
+'sharedupload-desc-create' => 'ไฟล์นี้มาจาก $1 และอาจมีการใช้ไฟล์นี้ในโครงการอื่น
+หากคุณต้องการแก้ไขคำอธิบาย ให้ดำเนินการบน[$2 หน้าคำอธิบายไฟล์]',
 'filepage-nofile' => 'ไม่มีไฟล์ชื่อนี้',
 'filepage-nofile-link' => 'ไม่มีไฟล์ชื่อนี้ แต่คุณสามารถ[$1 อัปโหลด]ได้',
 'uploadnewversion-linktext' => 'อัปโหลดรุ่นใหม่ของไฟล์นี้',
@@ -1779,7 +1821,7 @@ $1',
 # File deletion
 'filedelete' => 'ลบ $1',
 'filedelete-legend' => 'ลบไฟล์',
-'filedelete-intro' => "à¸\84ุà¸\93à¸\81ำลัà¸\87à¸\88ะลà¸\9aà¹\84à¸\9fลà¹\8c '''[[Media:$1|$1]]''' à¹\84à¸\9bà¸\9eรà¹\89อมà¸\81ัà¸\9aà¸\9bระวัà¸\95ิของไฟล์นี้",
+'filedelete-intro' => "à¸\84ุà¸\93à¸\81ำลัà¸\87ลà¸\9aà¹\84à¸\9fลà¹\8c '''[[Media:$1|$1]]''' à¸\9eรà¹\89อมà¸\81ัà¸\9aà¸\9bระวัà¸\95ิà¸\97ัà¹\89à¸\87หมà¸\94ของไฟล์นี้",
 'filedelete-intro-old' => "คุณกำลังลบ '''[[Media:$1|$1]]''' รุ่น [$4 $3, $2]",
 'filedelete-comment' => 'เหตุผล:',
 'filedelete-submit' => 'ลบ',
@@ -1793,12 +1835,13 @@ $1',
 ** ละเมิดลิขสิทธิ์
 ** ไฟล์ซ้ำ',
 'filedelete-edit-reasonlist' => 'แก้ไขเหตุผลการลบ',
-'filedelete-maintenance' => 'à¸\9bิà¸\94à¸\81ารลà¸\9aà¹\81ละà¹\80รียà¸\81à¸\84ืà¸\99à¹\84à¸\9fลà¹\8cà¹\84วà¹\89à¸\8aัà¹\88วà¸\84ราว à¹\83à¸\99ระหวà¹\88าà¸\87à¸\81ารà¸\8bà¹\88อมà¸\9aำรุà¸\87',
+'filedelete-maintenance' => 'à¸\81ารลà¸\9aà¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99à¹\84à¸\9fลà¹\8cà¹\83à¸\8aà¹\89à¸\87าà¸\99à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\8aัà¹\88วà¸\84ราวระหวà¹\88าà¸\87à¸\81ารà¸\9aำรุà¸\87รัà¸\81ษา',
 'filedelete-maintenance-title' => 'ไม่สามารถลบไฟล์',
 
 # MIME search
 'mimesearch' => 'ค้นหาตามชนิดไมม์',
-'mimesearch-summary' => 'หน้านี้แสดงไฟล์ตามการแบ่งของชนิดไมม์ (MIME) ของแต่ละไฟล์ ใส่ค่า: contenttype/subtype เช่น <code>image/jpeg</code>.',
+'mimesearch-summary' => 'หน้านี้แสดงไฟล์ตามการแบ่งของชนิดไมม์ของแต่ละไฟล์ 
+ใส่ค่า: contenttype/subtype เช่น <code>image/jpeg</code>',
 'mimetype' => 'ชนิดไมม์:',
 'download' => 'ดาวน์โหลด',
 
@@ -1810,8 +1853,8 @@ $1',
 
 # Unused templates
 'unusedtemplates' => 'แม่แบบไม่ได้ใช้',
-'unusedtemplatestext' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¹\81สà¸\94à¸\87รายà¸\81ารà¸\9aà¸\97à¸\84วามà¸\97ัà¹\89à¸\87หมà¸\94à¹\83à¸\99à¹\80à¸\99มสà¹\80à¸\9bà¸\8b {{ns:template}} à¸\8bึà¹\88à¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81รวมอยูà¹\88à¹\83à¸\99หà¸\99à¹\89าอืà¹\88à¸\99 à¸\81à¹\88อà¸\99à¸\97ีà¹\88à¸\88ะลà¸\9aสà¹\88วà¸\99à¸\99ีà¹\89à¹\83หà¹\89à¸\97ำà¸\81ารà¸\95รวà¸\88สอà¸\9aหà¸\99à¹\89าà¸\97ีà¹\88ลิà¸\87à¸\81à¹\8cมาà¸\81à¹\88อà¸\99à¸\97ุà¸\81à¸\84รัà¹\89à¸\87',
-'unusedtemplateswlh' => 'ลิà¸\87à¸\81à¹\8cมา',
+'unusedtemplatestext' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¹\81สà¸\94à¸\87รายà¸\81ารหà¸\99à¹\89าà¸\97ัà¹\89à¸\87หมà¸\94à¹\83à¸\99à¹\80à¸\99มสà¹\80à¸\9bà¸\8b {{ns:template}} à¸\8bึà¹\88à¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81รวมอยูà¹\88à¹\83à¸\99หà¸\99à¹\89าอืà¹\88à¸\99 à¸­à¸¢à¹\88าลืมà¸\95รวà¸\88สอà¸\9aà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87มายัà¸\87à¹\81มà¹\88à¹\81à¸\9aà¸\9aอืà¹\88à¸\99à¸\81à¹\88อà¸\99ลà¸\9a',
+'unusedtemplateswlh' => 'à¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87อืà¹\88à¸\99',
 
 # Random page
 'randompage' => 'สุ่มหน้า',
@@ -1838,46 +1881,48 @@ $1',
 'statistics-views-total-desc' => 'ไม่นับรวมจำนวนการเข้าชมหน้าที่ไม่มีอยู่และหน้าพิเศษ',
 'statistics-views-peredit' => 'จำนวนการเข้าดูต่อการแก้ไข:',
 'statistics-users' => '[[Special:ListUsers|ผู้ใช้]]ลงทะเบียน',
-'statistics-users-active' => 'à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88ยัà¸\87à¹\81à¸\81à¹\89à¹\84à¸\82อยูà¹\88',
+'statistics-users-active' => 'à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88ยัà¸\87มีà¸\84วามà¹\80à¸\84ลืà¹\88อà¸\99à¹\84หว',
 'statistics-users-active-desc' => 'ผู้ใช้ที่ดำเนินปฏิบัติการในช่วง $1 วันที่ผ่านมา',
 'statistics-mostpopular' => 'หน้าที่มีการเข้าชมมากที่สุด',
 
-'disambiguations' => 'หà¸\99à¹\89าà¸\97ีà¹\88à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¸\81ัà¸\9aหน้าแก้ความกำกวม',
+'disambiguations' => 'หà¸\99à¹\89าà¸\97ีà¹\88à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¹\84à¸\9bยัà¸\87หน้าแก้ความกำกวม',
 'disambiguationspage' => 'Template:แก้กำกวม',
-'disambiguations-text' => "หà¸\99à¹\89าà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89มีอยà¹\88าà¸\87à¸\99à¹\89อยหà¸\99ึà¹\88à¸\87ลิà¸\87à¸\81à¹\8cà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¹\84à¸\9bยัà¸\87'''หà¸\99à¹\89าà¸\84วามà¸\81ำà¸\81วม'''
-à¸\8bึà¹\88à¸\87อาà¸\88à¸\95à¹\89อà¸\87ลิà¸\87à¸\81à¹\8cà¹\84à¸\9bยัà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¹\80หมาะสมแทน<br />
-หà¸\99à¹\89าà¹\83à¸\94à¸\97ีà¹\88à¹\83à¸\8aà¹\89à¹\81มà¹\88à¹\81à¸\9aà¸\9aà¸\97ีà¹\88ลิà¸\87à¸\81à¹\8cมาà¸\88าà¸\81 [[MediaWiki:Disambiguationspage]] à¸«à¸\99à¹\89าà¹\80หลà¹\88าà¸\99ัà¹\89à¸\99à¸\88ะà¸\96ูà¸\81à¸\99ัà¸\9aรวมเป็นหน้าความกำกวม",
+'disambiguations-text' => "หà¸\99à¹\89าà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89มีà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¹\84à¸\9bยัà¸\87'''หà¸\99à¹\89าà¸\84วามà¸\81ำà¸\81วม'''อยà¹\88าà¸\87à¸\99à¹\89อยหà¸\99ึà¹\88à¸\87à¹\81หà¹\88à¸\87
+à¸\8bึà¹\88à¸\87อาà¸\88à¸\95à¹\89อà¸\87à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¹\84à¸\9bยัà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¹\80หมาะสมà¸\81วà¹\88าแทน<br />
+หà¸\99à¹\89าà¹\83à¸\94à¸\97ีà¹\88à¹\83à¸\8aà¹\89à¹\81มà¹\88à¹\81à¸\9aà¸\9aà¸\97ีà¹\88à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87มาà¸\88าà¸\81 [[MediaWiki:Disambiguationspage]] à¸\88ะà¸\96ูà¸\81à¸\99ัà¸\9aเป็นหน้าความกำกวม",
 
 'doubleredirects' => 'หน้าเปลี่ยนทางซ้ำซ้อน',
-'doubleredirectstext' => 'หน้านี้แสดงรายการชื่อที่เปลี่ยนทางไปยังหน้าเปลี่ยนทางอื่น
-แต่ละแถวคือลิงก์ของการเปลี่ยนทางครั้งแรกและครั้งที่สอง พร้อมกับหน้าปลายทางของการเปลี่ยนทางครั้งที่สอง ซึ่งควรแก้ไขการเปลี่ยนทางครั้งแรกเป็นหน้าปลายทางดังกล่าว
-รายการที่ <del>ขีดฆ่า</del> คือรายการที่แก้ไขแล้ว',
-'double-redirect-fixed-move' => '[[$1]] ถูกเปลี่ยนชื่อแล้ว และเปลี่ยนทางไปยัง [[$2]]',
+'doubleredirectstext' => 'หน้านี้แสดงรายการหน้าที่เปลี่ยนทางไปยังหน้าเปลี่ยนทางอื่น
+แต่ละแถวมีการเชื่อมโยงไปยังการเปลี่ยนทางครั้งแรกและครั้งที่สอง เช่นเดียวกับเป้าหมายของการเปลี่ยนทางครั้งที่สอง ซึ่งมักเป็นหน้าเป้าหมาย "ที่แท้จริง" ที่การเปลี่ยนแปลงครั้งแรกควรชี้ไป
+หน่วยที่<del>ขีดฆ่า</del> คือ รายการที่ได้แก้ไขแล้ว',
+'double-redirect-fixed-move' => '[[$1]] ถูกเปลี่ยนชื่อแล้ว 
+ขณะนี้เปลี่ยนทางไปยัง [[$2]]',
 'double-redirect-fixed-maintenance' => 'การแก้ไขการเปลี่ยนทางซ้ำซ้อนจาก [[$1]] ไปยัง [[$2]]',
-'double-redirect-fixer' => 'Redirect fixer',
+'double-redirect-fixer' => 'ผู้ซ่อมหน้าเปลี่ยนทาง',
 
 'brokenredirects' => 'หน้าเปลี่ยนทางเสีย',
-'brokenredirectstext' => 'หà¸\99à¹\89าà¹\80à¸\9bลีà¹\88ยà¸\99à¸\97าà¸\87à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¹\84à¸\9bยัà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¹\84มà¹\88มี:',
+'brokenredirectstext' => 'หà¸\99à¹\89าà¹\80à¸\9bลีà¹\88ยà¸\99à¸\97าà¸\87à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¹\84à¸\9bยัà¸\87หà¸\99à¹\89าà¸\97ีà¹\88ยัà¸\87à¹\84มà¹\88à¸\96ูà¸\81สรà¹\89าà¸\87:',
 'brokenredirects-edit' => 'แก้ไข',
 'brokenredirects-delete' => 'ลบ',
 
 'withoutinterwiki' => 'หน้าที่ไม่มีลิงก์ข้ามภาษา',
 'withoutinterwiki-summary' => 'หน้าต่อไปนี้ไม่มีลิงก์ข้ามไปภาษาอื่น',
-'withoutinterwiki-legend' => 'à¸\84ำà¸\99ำหà¸\99à¹\89า',
+'withoutinterwiki-legend' => 'à¸\84ำà¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99',
 'withoutinterwiki-submit' => 'แสดง',
 
-'fewestrevisions' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82น้อยสุด',
+'fewestrevisions' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีรุà¹\88à¸\99น้อยสุด',
 
 # Miscellaneous special pages
 'nbytes' => '$1 ไบต์',
 'ncategories' => '$1 หมวดหมู่',
-'nlinks' => '$1 {{PLURAL:$1|ลิงก์|ลิงก์}}',
+'ninterwikis' => '$1 ลิงก์ข้ามโครงการ',
+'nlinks' => '$1 ลิงก์',
 'nmembers' => '$1 หน้า',
-'nrevisions' => '$1 à¸\84รัà¹\89à¸\87',
+'nrevisions' => '$1 à¸£à¸¸à¹\88à¸\99',
 'nviews' => '$1 ครั้ง',
 'nimagelinks' => 'ใช้ใน $1 {{PLURAL: $1|หน้า|หน้า}}',
 'ntransclusions' => 'ใช้ใน $1 {{PLURAL: $1|หน้า|หน้า}}',
-'specialpage-empty' => 'à¹\84มà¹\88มีหà¸\99à¹\89าà¸\97ีà¹\88à¹\80รียà¸\81à¸\94ู',
+'specialpage-empty' => 'à¹\84มà¹\88มีà¸\9cลลัà¸\9eà¸\98à¹\8cรายà¸\87าà¸\99à¸\99ีà¹\89',
 'lonelypages' => 'หน้าสุดทาง',
 'lonelypagestext' => 'หน้าต่อไปนี้ไม่มีการเชื่อมโยงหรือถูกรวมไว้ในหน้าอื่นใน {{SITENAME}}',
 'uncategorizedpages' => 'หน้าที่ไม่ได้จัดหมวดหมู่',
@@ -1889,30 +1934,30 @@ $1',
 'popularpages' => 'หน้าที่มีการเข้าดูมาก',
 'wantedcategories' => 'หมวดหมู่ที่ต้องการ',
 'wantedpages' => 'หน้าที่ต้องการ',
-'wantedpages-badtitle' => 'ชื่อเรื่อง $1 ไม่ถูกต้องในรายการผลลัพธ์',
+'wantedpages-badtitle' => 'ชื่อเรื่องไม่สมเหตุสมผลในเซตผลลัพธ์: $1',
 'wantedfiles' => 'ไฟล์ที่ต้องการ',
 'wantedtemplates' => 'แม่แบบที่ต้องการ',
-'mostlinked' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีà¸\81ารลิà¸\87à¸\81à¹\8cหามาà¸\81',
-'mostlinkedcategories' => 'หมวà¸\94หมูà¹\88à¸\97ีà¹\88มีà¸\81ารà¹\82ยà¸\87หามาà¸\81',
-'mostlinkedtemplates' => 'à¹\81มà¹\88à¹\81à¸\9aà¸\9aà¸\97ีà¹\88à¹\83à¸\8aà¹\89มาà¸\81',
-'mostcategories' => 'หน้าที่มีหมวดหมู่มาก',
-'mostimages' => 'ภาà¸\9eà¸\97ีà¹\88à¹\83à¸\8aà¹\89มาà¸\81',
-'mostinterwikis' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีลิà¸\87à¸\81à¹\8cà¸\82à¹\89ามภาษามากที่สุด',
-'mostrevisions' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82มาà¸\81',
-'prefixindex' => 'หà¸\99à¹\89าà¸\97ัà¹\89à¸\87หมà¸\94à¸\95ามà¸\94ัà¸\8aà¸\99ีคำขึ้นต้น',
-'prefixindex-namespace' => 'à¸\97ุà¸\81หà¸\99à¹\89าà¸\97ีà¹\88มีà¸\84ำà¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99 ($1 à¹\80à¸\99มสà¹\80à¸\9bà¸\8b)',
-'shortpages' => 'หน้าสั้นมาก',
-'longpages' => 'หน้ายาวมาก',
+'mostlinked' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87หามาà¸\81à¸\97ีà¹\88สุà¸\94',
+'mostlinkedcategories' => 'หมวà¸\94หมูà¹\88à¸\97ีà¹\88มีà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87หามาà¸\81à¸\97ีà¹\88สุà¸\94',
+'mostlinkedtemplates' => 'à¹\81มà¹\88à¹\81à¸\9aà¸\9aà¸\97ีà¹\88มีà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87หามาà¸\81à¸\97ีà¹\88สุà¸\94',
+'mostcategories' => 'หน้าที่มีหมวดหมู่มากที่สุด',
+'mostimages' => 'ภาà¸\9eà¸\97ีà¹\88มีà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87หามาà¸\81à¸\97ีà¹\88สุà¸\94',
+'mostinterwikis' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีลิà¸\87à¸\81à¹\8cà¸\82à¹\89ามà¹\82à¸\84รà¸\87à¸\81ารมากที่สุด',
+'mostrevisions' => 'หà¸\99à¹\89าà¸\97ีà¹\88มีรุà¹\88à¸\99มาà¸\81à¸\97ีà¹\88สุà¸\94',
+'prefixindex' => 'à¸\97ุà¸\81หà¸\99à¹\89าà¸\9eรà¹\89อมคำขึ้นต้น',
+'prefixindex-namespace' => 'à¸\97ุà¸\81หà¸\99à¹\89าà¸\9eรà¹\89อมà¸\84ำà¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99 (à¹\80à¸\99มสà¹\80à¸\9bà¸\8b $1)',
+'shortpages' => 'หน้าสั้น',
+'longpages' => 'หน้ายาว',
 'deadendpages' => 'หน้าสุดทาง',
-'deadendpagestext' => 'หà¸\99à¹\89าà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\84มà¹\88à¹\84à¸\94à¹\89ลิà¸\87à¸\81à¹\8cไปหน้าอื่นใน {{SITENAME}}',
-'protectedpages' => 'หน้าถูกล็อก',
-'protectedpages-indef' => 'à¸\81ารลà¹\87อà¸\81à¹\81à¸\9aà¸\9aà¹\84มà¹\88à¸\88ำà¸\81ัดเท่านั้น',
+'deadendpagestext' => 'หà¸\99à¹\89าà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\84มà¹\88à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87ไปหน้าอื่นใน {{SITENAME}}',
+'protectedpages' => 'หà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81ลà¹\87อà¸\81',
+'protectedpages-indef' => 'à¸\81ารลà¹\87อà¸\81à¹\81à¸\9aà¸\9aà¹\84มà¹\88มีà¸\81ำหà¸\99ดเท่านั้น',
 'protectedpages-cascade' => 'การล็อกแบบสืบทอดเท่านั้น',
-'protectedpagestext' => 'หà¸\99à¹\89าà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¸\96ูà¸\81ลà¹\87อà¸\81หà¹\89ามà¹\81à¸\81à¹\89à¹\84à¸\82หรือà¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อ',
-'protectedpagesempty' => 'à¹\84มà¹\88มีหà¸\99à¹\89าà¹\83à¸\94à¸\97ีà¹\88à¸\96ูà¸\81ลà¹\87อà¸\81à¸\95ามà¸\84à¹\88าà¸\97ีà¹\88à¹\80ลือà¸\81',
-'protectedtitles' => 'หัวà¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¹\84à¸\94à¹\89รัà¸\9aà¸\81ารป้องกัน',
-'protectedtitlestext' => 'หัวà¹\80รืà¹\88อà¸\87à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\84à¸\94à¹\89รัà¸\9aà¸\81ารป้องกันมิให้สร้าง',
-'protectedtitlesempty' => 'à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¹\84มà¹\88มีหัวà¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¹\84à¸\94à¹\89รัà¸\9aà¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\94à¹\89วยà¸\84à¹\88าà¸\95à¹\88อà¹\84à¸\9bนี้',
+'protectedpagestext' => 'หà¸\99à¹\89าà¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¸\96ูà¸\81ลà¹\87อà¸\81มิà¹\83หà¹\89ยà¹\89ายหรือà¹\81à¸\81à¹\89à¹\84à¸\82',
+'protectedpagesempty' => 'à¸\82à¸\93ะà¸\99ีà¹\89à¹\84มà¹\88มีหà¸\99à¹\89าà¹\83à¸\94à¸\96ูà¸\81ลà¹\87อà¸\81à¸\95ามà¸\9eารามิà¹\80à¸\95อรà¹\8cà¹\80หลà¹\88าà¸\99ีà¹\89',
+'protectedtitles' => 'à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¸\96ูà¸\81ป้องกัน',
+'protectedtitlestext' => 'à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¸\96ูà¸\81ป้องกันมิให้สร้าง',
+'protectedtitlesempty' => 'à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¹\84มà¹\88มีหัวà¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¹\84à¸\94à¹\89รัà¸\9aà¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\94à¹\89วยà¸\9eารามิà¹\80à¸\95อรà¹\8cà¹\80หลà¹\88านี้',
 'listusers' => 'รายนามผู้ใช้',
 'listusers-editsonly' => 'แสดงเฉพาะผู้ใช้ที่มีการแก้ไข',
 'listusers-creationsort' => 'เรียงลำดับตามวันสร้าง',
@@ -1924,22 +1969,22 @@ $1',
 'move' => 'เปลี่ยนชื่อ',
 'movethispage' => 'เปลี่ยนชื่อหน้านี้',
 'unusedimagestext' => 'ไฟล์ต่อไปนี้มีอยู่ แต่ไม่มีการเรียกใช้ในหน้าใด ๆ เลย
-หมายà¹\80หà¸\95ุวà¹\88า à¹\80วà¹\87à¸\9aà¹\84วà¸\95à¹\8cอืà¹\88à¸\99อาà¸\88ลิà¸\87à¸\81à¹\8cมายัà¸\87à¹\84à¸\9fลà¹\8cà¸\94à¹\89วยยูอารà¹\8cà¹\81อลà¹\82à¸\94ยà¸\95รà¸\87 à¸\89ะà¸\99ัà¹\89à¸\99à¸\88ึà¸\87อาà¸\88ยัà¸\87มีà¸\8aืà¹\88ออยู่ที่นี่แม้จะมีการใช้อย่างต่อเนื่อง',
-'unusedcategoriestext' => 'หมวดหมู่ต่อไปนี้ยังมีอยู่ถึงแม้ว่าจะไม่มีว่าไม่มีหน้าไหนหรือบทความไหนใช้ส่วนนี้',
-'notargettitle' => 'à¹\84มà¹\88à¸\9eà¸\9aหà¸\99à¹\89าà¸\9bลายà¸\97าà¸\87',
+หมายà¹\80หà¸\95ุวà¹\88า à¹\80วà¹\87à¸\9aà¹\84à¸\8bà¸\95à¹\8cอืà¹\88à¸\99อาà¸\88à¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87มายัà¸\87à¹\84à¸\9fลà¹\8cà¸\94à¹\89วยยูอารà¹\8cà¹\81อลà¹\82à¸\94ยà¸\95รà¸\87 à¸\89ะà¸\99ัà¹\89à¸\99à¸\88ึà¸\87à¸\8aืà¹\88ออาà¸\88ยัà¸\87à¹\81สà¸\94à¸\87รายà¸\81ารอยู่ที่นี่แม้จะมีการใช้อย่างต่อเนื่อง',
+'unusedcategoriestext' => 'หมวดหมู่ต่อไปนี้ยังมีอยู่ แม้ไม่มีหน้าอื่นหรือหมวดหมู่ใดใช้ส่วนนี้',
+'notargettitle' => 'à¹\84มà¹\88à¸\9eà¸\9aà¹\80à¸\9bà¹\89าหมาย',
 'notargettext' => 'คุณมิได้ระบุหน้าหรือผู้ใช้เป้าหมายที่จะดำเนินการฟังก์ชันนี้',
 'nopagetitle' => 'ไม่มีหน้าเป้าหมายดังกล่าว',
 'nopagetext' => 'หน้าเป้าหมายที่คุณระบุไม่มีอยู่',
 'pager-newer-n' => 'ใหม่กว่า $1',
 'pager-older-n' => 'เก่ากว่า $1',
-'suppress' => 'Oversight',
-'querypage-disabled' => 'หà¸\99à¹\89าà¸\9eิà¹\80ศษà¸\99ีà¹\89à¸\96ูà¸\81à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99à¸\94à¹\89วยà¹\80หà¸\95ุà¸\9cลà¸\94à¹\89าà¸\99à¸\9bระสิà¸\97à¸\98ิภาà¸\9e',
+'suppress' => 'ผู้ดูแลประวัติ',
+'querypage-disabled' => 'หà¸\99à¹\89าà¸\9eิà¹\80ศษà¸\99ีà¹\89à¸\96ูà¸\81à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81มีà¸\9bระสิà¸\97à¸\98ิภาà¸\9eà¸\95à¹\88ำ',
 
 # Book sources
-'booksources' => 'à¸\84à¹\89à¸\99หาหนังสือ',
-'booksources-search-legend' => 'ค้นหาหนังสือ',
+'booksources' => 'à¹\81หลà¹\88à¸\87หนังสือ',
+'booksources-search-legend' => 'à¸\84à¹\89à¸\99หาà¹\81หลà¹\88à¸\87หà¸\99ัà¸\87สือ',
 'booksources-go' => 'ค้นหา',
-'booksources-text' => 'รายà¸\81ารà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\81สà¸\94à¸\87à¹\80วà¹\87à¸\9aà¹\84à¸\8bà¸\95à¹\8cà¸\97ีà¹\88à¸\82ายหà¸\99ัà¸\87สือà¹\83หมà¹\88หรือหà¸\99ัà¸\87สือà¹\83à¸\8aà¹\89à¹\81ลà¹\89ว à¸\8bึà¹\88à¸\87อาà¸\88มีà¸\82à¹\89อมูลà¸\82อà¸\87หà¸\99ัà¸\87สือà¸\97ีà¹\88à¸\84ุà¸\93à¸\81ำลัà¸\87à¸\84à¹\89à¸\99หา:',
+'booksources-text' => 'à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9bà¹\87à¸\99รายà¸\81ารà¸\81ารà¹\80à¸\8aืà¹\88อมà¹\82ยà¸\87à¹\84à¸\9bยัà¸\87à¹\80วà¹\87à¸\9aà¹\84à¸\8bà¸\95à¹\8cอืà¹\88à¸\99à¸\97ีà¹\88à¸\82ายหà¸\99ัà¸\87สือà¹\83หมà¹\88à¹\81ละหà¸\99ัà¸\87สือà¹\83à¸\8aà¹\89à¹\81ลà¹\89ว à¹\81ละอาà¸\88มีสารสà¸\99à¹\80à¸\97ศà¹\80à¸\9eิà¹\88มà¹\80à¸\95ิมà¹\80à¸\81ีà¹\88ยวà¸\81ัà¸\9aหà¸\99ัà¸\87สือà¸\97ีà¹\88à¸\84ุà¸\93à¸\81ำลัà¸\87มอà¸\87หา:',
 'booksources-invalid-isbn' => 'รหัส ISBN ที่ให้ไว้ไม่ถูกต้อง กรุณาตรวจสอบจากต้นฉบับอีกครั้ง',
 
 # Special:Log
@@ -1948,24 +1993,24 @@ $1',
 'log' => 'ปูม',
 'all-logs-page' => 'ปูมสาธารณะทั้งหมด',
 'alllogstext' => 'การแสดงผลรวมปูมที่มีทั้งหมดของ {{SITENAME}}
-à¸\84ุà¸\93สามารà¸\96à¸\84à¹\89à¸\99หาà¹\83หà¹\89ละà¹\80อียà¸\94à¸\82ึà¹\89à¸\99à¹\82à¸\94ยà¹\80ลือà¸\81à¸\9bระà¹\80ภà¸\97à¸\9bูม à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร (ระวัà¸\87อัà¸\81ษรภาษาอัà¸\87à¸\81ฤษà¸\9eิมà¸\9eà¹\8cà¹\80ลà¹\87à¸\81à¹\83หà¸\8dà¹\88)',
+à¸\84ุà¸\93สามารà¸\96à¸\84à¹\89à¸\99หาà¹\83หà¹\89ละà¹\80อียà¸\94à¸\82ึà¹\89à¸\99à¹\82à¸\94ยà¹\80ลือà¸\81à¸\9bระà¹\80ภà¸\97à¸\9bูม à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร (à¹\84วà¸\95à¹\88ออัà¸\81ษรà¹\83หà¸\8dà¹\88à¹\80ลà¹\87à¸\81)',
 'logempty' => 'ไม่พบรายการตรงกันในปูม',
-'log-title-wildcard' => 'à¸\84à¹\89à¸\99หาà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¸\94à¹\89วยà¸\84ำà¸\82ึà¹\89à¸\99à¸\95à¹\89à¸\99',
-'showhideselectedlogentries' => 'à¹\81สà¸\94à¸\87/à¸\8bà¹\88อà¸\99รายà¸\81ารปูมที่เลือก',
+'log-title-wildcard' => 'à¸\84à¹\89à¸\99หาà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¸\94à¹\89วยà¸\82à¹\89อà¸\84วามà¸\99ีà¹\89',
+'showhideselectedlogentries' => 'à¹\81สà¸\94à¸\87/à¸\8bà¹\88อà¸\99หà¸\99à¹\88วยปูมที่เลือก',
 
 # Special:AllPages
 'allpages' => 'ทุกหน้า',
 'alphaindexline' => '$1 ถึง $2',
 'nextpage' => 'ถัดไป ($1)',
 'prevpage' => 'ก่อนหน้า ($1)',
-'allpagesfrom' => 'à¹\80ริà¹\88มà¹\81สà¸\94à¸\87à¸\9cลจาก:',
-'allpagesto' => 'à¸\88à¸\9aà¸\81ารà¹\81สà¸\94à¸\87à¸\9cลที่:',
+'allpagesfrom' => 'à¹\81สà¸\94à¸\87หà¸\99à¹\89าà¹\82à¸\94ยà¹\80ริà¹\88มจาก:',
+'allpagesto' => 'à¹\81สà¸\94à¸\87หà¸\99à¹\89าà¸\88à¸\9aที่:',
 'allarticles' => 'ทุกหน้า',
-'allinnamespace' => 'หน้าทุกหน้า ($1 เนมสเปซ)',
-'allnotinnamespace' => 'หน้าทุกหน้า (ไม่อยู่ใน $1 เนมสเปซ)',
+'allinnamespace' => 'หน้าทุกหน้า (เนมสเปซ $1)',
+'allnotinnamespace' => 'หน้าทุกหน้า (ไม่อยู่ในเนมสเปซ $1)',
 'allpagesprev' => 'ก่อนหน้า',
 'allpagesnext' => 'ถัดไป',
-'allpagessubmit' => 'à¸\84à¹\89à¸\99หา',
+'allpagessubmit' => 'à¸\94ู',
 'allpagesprefix' => 'แสดงหน้าที่ขึ้นต้นด้วย:',
 'allpagesbadtitle' => 'ชื่อเรื่องนี้ไม่ถูกต้อง อาจสะกดผิด ลิงก์มาจากภาษาอื่นหรือวิกิอื่น หรือมีตัวอักษรที่ไม่สามารถใช้เป็นชื่อเรื่องได้',
 'allpages-bad-ns' => '{{SITENAME}} ไม่มีเนมสเปซ "$1"',
@@ -1973,10 +2018,10 @@ $1',
 
 # Special:Categories
 'categories' => 'หมวดหมู่',
-'categoriespagetext' => '{{PLURAL:$1|หมวà¸\94หมูà¹\88à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89}}มีหà¸\99à¹\89าหรือสืà¹\88อà¸\95à¹\88าà¸\87
+'categoriespagetext' => '{{PLURAL:$1|หมวà¸\94หมูà¹\88à¸\99ีà¹\89|หมวà¸\94หมูà¹\88à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89}}มีหà¸\99à¹\89าหรือสืà¹\88อà¸\95à¹\88าà¸\87 
 [[Special:UnusedCategories|หมวดหมู่ที่ไม่ได้ใช้]]จะไม่แสดงในที่นี้
-ดูเพิ่มที่[[Special:WantedCategories|หมวดหมู่ที่ต้องการ]]',
-'categoriesfrom' => 'à¹\81สà¸\94à¸\87หมวà¸\94หมูà¹\88à¹\82à¸\94ยà¹\80ริà¹\88มà¸\88าà¸\81:',
+ดูเพิ่มที่ [[Special:WantedCategories|หมวดหมู่ที่ต้องการ]]',
+'categoriesfrom' => 'แสดงหมวดหมู่เริ่มจาก:',
 'special-categories-sort-count' => 'เรียงตามจำนวน',
 'special-categories-sort-abc' => 'เรียงตามตัวอักษร',
 
@@ -1986,69 +2031,70 @@ $1',
 'sp-deletedcontributions-contribs' => 'เรื่องที่เขียน',
 
 # Special:LinkSearch
-'linksearch' => 'à¸\84à¹\89à¸\99หาลิà¸\87à¸\81à¹\8cà¸\88าà¸\81ภายà¸\99อà¸\81à¹\80วà¹\87à¸\9aà¹\84à¸\8bà¸\95à¹\8c',
+'linksearch' => 'à¸\84à¹\89à¸\99หาลิà¸\87à¸\81à¹\8cภายà¸\99อà¸\81',
 'linksearch-pat' => 'รูปแบบการค้นหา:',
 'linksearch-ns' => 'เนมสเปซ:',
-'linksearch-ok' => 'สืà¸\9aà¸\84à¹\89à¸\99',
-'linksearch-text' => 'อัà¸\81à¸\82ระà¸\95ัวà¹\81à¸\97à¸\99à¹\80à¸\8aà¹\88à¸\99 "*.wikipedia.org" à¸ªà¸²à¸¡à¸²à¸£à¸\96à¹\83à¸\8aà¹\89ได้
+'linksearch-ok' => 'à¸\84à¹\89à¸\99หา',
+'linksearch-text' => 'สามารà¸\96à¹\83à¸\8aà¹\89à¸\95ัวà¹\81à¸\97à¸\99à¹\80à¸\8aà¹\88à¸\99 "*.wikipedia.org" ได้
 ต้องการโดเมนระดับบนสุดเป็นอย่างน้อย เช่น "*.org"<br />
-à¹\82à¸\9eรà¹\82à¸\97à¸\84อลà¸\97ีà¹\88รอà¸\87รัà¸\9a: <code>$1</code> (à¸\84à¹\88าà¹\82à¸\94ยà¸\9bริยายà¹\80à¸\9bà¹\89น http:// หากไม่ระบุโพรโทคอล)',
+à¹\82à¸\9eรà¹\82à¸\97à¸\84อลà¸\97ีà¹\88รอà¸\87รัà¸\9a: <code>$1</code> (à¸\84à¹\88าà¹\82à¸\94ยà¸\9bริยายà¹\80à¸\9bà¹\87น http:// หากไม่ระบุโพรโทคอล)',
 'linksearch-line' => '$1 ถูกลิงก์จาก $2',
-'linksearch-error' => 'à¹\80à¸\84รืà¹\88อà¸\87หมายà¹\81à¸\97à¸\99อัà¸\81à¸\82ระ (wildcard) à¸­à¸¢à¸¹à¹\88หà¸\99à¹\89าà¸\8aืà¹\88อà¹\82ฮสà¸\95à¹\8cà¹\84à¸\94à¹\89เท่านั้น',
+'linksearch-error' => 'อัà¸\81à¸\82ระà¸\95ัวà¹\81à¸\97à¸\99อยูà¹\88à¹\84à¸\94à¹\89à¹\80à¸\89à¸\9eาะหà¸\99à¹\89าà¸\8aืà¹\88อà¹\82ฮสà¸\95à¹\8cเท่านั้น',
 
 # Special:ListUsers
-'listusersfrom' => 'à¹\81สà¸\94à¸\87à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\82à¸\94ยà¹\80ริà¹\88มà¸\95à¹\89à¸\99จาก:',
+'listusersfrom' => 'à¹\81สà¸\94à¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\80ริà¹\88มจาก:',
 'listusers-submit' => 'แสดง',
-'listusers-noresult' => 'à¹\84มà¹\88à¸\9eà¸\9aà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร',
+'listusers-noresult' => 'à¹\84มà¹\88à¸\9eà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89',
 'listusers-blocked' => '(ถูกบล็อก)',
 
 # Special:ActiveUsers
-'activeusers' => 'รายà¸\81ารà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\9bระà¸\88ำ',
-'activeusers-intro' => 'à¸\99ีà¹\88à¸\84ือรายà¸\99ามà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88มีà¸\81ิà¸\88à¸\81รรมà¹\83à¸\94 à¹\86 à¹\83à¸\99 $1 วันที่ผ่านมา',
-'activeusers-count' => '{{PLURAL:$1|à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82ลà¹\88าสุà¸\94|à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82ล่าสุด $1 รายการ}} ในช่วง $3 วันที่ผ่านมา',
-'activeusers-from' => 'à¹\81สà¸\94à¸\87à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\82à¸\94ยเริ่มจาก:',
+'activeusers' => 'รายà¸\81ารà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88มีà¸\84วามà¹\80à¸\84ลืà¹\88อà¸\99à¹\84หว',
+'activeusers-intro' => 'à¸\99ีà¹\88à¸\84ือรายà¸\81ารà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88มีà¸\81ิà¸\88à¸\81รรมà¹\83à¸\94 à¹\86 à¹\83à¸\99à¸\8aà¹\88วà¸\87 $1 วันที่ผ่านมา',
+'activeusers-count' => '{{PLURAL:$1|à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\81ารลà¹\88าสุà¸\94|à¸\9bà¸\8fิà¸\9aัà¸\95ิà¸\81ารล่าสุด $1 รายการ}} ในช่วง $3 วันที่ผ่านมา',
+'activeusers-from' => 'à¹\81สà¸\94à¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89เริ่มจาก:',
 'activeusers-hidebots' => 'ซ่อนบอต',
 'activeusers-hidesysops' => 'ซ่อนผู้ดูแลระบบ',
-'activeusers-noresult' => 'à¹\84มà¹\88à¸\9eà¸\9aà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89',
+'activeusers-noresult' => 'ไม่พบผู้ใช้',
 
 # Special:ListGroupRights
-'listgrouprights' => 'สิทธิของกลุ่มผู้ใช้',
-'listgrouprights-summary' => 'รายชื่อกลุ่มผู้ใช้ต่อไปนี้ถูกกำหนดไว้บน {{SITENAME}} โดยมีสิทธิการเข้าถึงที่เกี่ยวข้อง และอาจมี[[{{MediaWiki:Listgrouprights-helppage}}|ข้อมูลเพิ่มเติม]]เกี่ยวกับสิทธิของแต่ละบุคคล',
-'listgrouprights-key' => '* <span class="listgrouprights-granted">สิทธิ์ที่ถูกให้</span>
-* <span class="listgrouprights-revoked">สิทธิ์ที่ถูกยกเลิก</span>',
+'listgrouprights' => 'สิทธิกลุ่มผู้ใช้',
+'listgrouprights-summary' => 'ด้านล่างเป็นรายการกลุ่มผู้ใช้ที่นิยามบนวิกินี้ และสิทธิการเข้าถึงที่เกี่ยวข้อง
+อาจมี[[{{MediaWiki:Listgrouprights-helppage}}|ข้อมูลเพิ่มเติม]]เกี่ยวกับสิทธิหนึ่ง ๆ',
+'listgrouprights-key' => '* <span class="listgrouprights-granted">สิทธิที่ได้รับแต่งตั้ง</span>
+* <span class="listgrouprights-revoked">สิทธิที่ถูกเพิกถอน</span>',
 'listgrouprights-group' => 'กลุ่ม',
 'listgrouprights-rights' => 'สิทธิ',
-'listgrouprights-helppage' => 'Help:สิà¸\97à¸\98ิà¸\82อà¸\87à¸\81ลุà¹\88ม',
-'listgrouprights-members' => '(รายà¸\8aืà¹\88อสมาชิก)',
-'listgrouprights-addgroup' => 'สามารà¸\96à¹\80à¸\9eิà¹\88ม{{PLURAL:$2|à¸\81ลุà¹\88มà¸\99ีà¹\89|à¸\81ลุà¹\88มà¹\80หลà¹\88าà¸\99ีà¹\89}}à¹\84à¸\94à¹\89: $1',
-'listgrouprights-removegroup' => 'สามารà¸\96ลà¸\9a{{PLURAL:$2|à¸\81ลุà¹\88มà¸\99ีà¹\89|à¸\81ลุà¹\88มà¹\80หลà¹\88าà¸\99ีà¹\89}}à¹\84à¸\94à¹\89: $1',
-'listgrouprights-addgroup-all' => 'สามารà¸\96à¹\80à¸\9eิà¹\88มà¸\81ลุà¹\88มà¸\97ัà¹\89à¸\87หมà¸\94à¹\84à¸\94à¹\89',
-'listgrouprights-removegroup-all' => 'สามารà¸\96ลà¸\9aà¸\81ลุà¹\88มà¸\97ัà¹\89à¸\87หมà¸\94à¹\84à¸\94à¹\89',
-'listgrouprights-addgroup-self' => 'à¹\80à¸\9eิà¹\88ม{{PLURAL:$2|à¸\81ลุà¹\88ม|à¸\81ลุà¹\88ม}}à¹\80à¸\82à¹\89าà¹\84à¸\9bà¹\83à¸\99à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89: $1',
-'listgrouprights-removegroup-self' => 'ลà¸\9a{{PLURAL:$2|à¸\81ลุà¹\88ม|à¸\81ลุà¹\88ม}}ออà¸\81à¸\88าà¸\81à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89: $1',
-'listgrouprights-addgroup-self-all' => 'à¹\80à¸\9eิà¹\88มà¸\97ุà¸\81à¸\81ลุà¹\88มà¹\80à¸\82à¹\89าà¹\84à¸\9bà¹\83à¸\99à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89นี้',
-'listgrouprights-removegroup-self-all' => 'ลà¸\9aà¸\97ุà¸\81à¸\81ลุà¹\88มออà¸\81à¸\88าà¸\81à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89นี้',
+'listgrouprights-helppage' => 'Help:สิทธิกลุ่ม',
+'listgrouprights-members' => '(รายà¸\81ารสมาชิก)',
+'listgrouprights-addgroup' => 'à¹\80à¸\9eิà¹\88ม{{PLURAL:$2|à¸\81ลุà¹\88มà¸\99ีà¹\89|à¸\81ลุà¹\88มà¹\80หลà¹\88าà¸\99ีà¹\89}}: $1',
+'listgrouprights-removegroup' => 'à¸\99ำ{{PLURAL:$2|à¸\81ลุà¹\88มà¸\99ีà¹\89|à¸\81ลุà¹\88มà¹\80หลà¹\88าà¸\99ีà¹\89}}ออà¸\81: $1',
+'listgrouprights-addgroup-all' => 'à¹\80à¸\9eิà¹\88มà¸\81ลุà¹\88มà¸\97ัà¹\89à¸\87หมà¸\94',
+'listgrouprights-removegroup-all' => 'à¸\99ำà¸\81ลุà¹\88มà¸\97ัà¹\89à¸\87หมà¸\94ออà¸\81',
+'listgrouprights-addgroup-self' => 'à¹\80à¸\9eิà¹\88ม{{PLURAL:$2|à¸\81ลุà¹\88ม|à¸\81ลุà¹\88ม}}à¹\80à¸\82à¹\89าà¹\84à¸\9bà¹\83à¸\99à¸\9aัà¸\8dà¸\8aี: $1',
+'listgrouprights-removegroup-self' => 'ลà¸\9a{{PLURAL:$2|à¸\81ลุà¹\88ม|à¸\81ลุà¹\88ม}}ออà¸\81à¸\88าà¸\81à¸\9aัà¸\8dà¸\8aี: $1',
+'listgrouprights-addgroup-self-all' => 'à¹\80à¸\9eิà¹\88มà¸\97ุà¸\81à¸\81ลุà¹\88มà¹\80à¸\82à¹\89าà¹\84à¸\9bà¹\83à¸\99à¸\9aัà¸\8dà¸\8aีนี้',
+'listgrouprights-removegroup-self-all' => 'à¸\99ำà¸\97ุà¸\81à¸\81ลุà¹\88มออà¸\81à¸\88าà¸\81à¸\9aัà¸\8dà¸\8aีนี้',
 
 # E-mail user
-'mailnologin' => 'à¹\84มà¹\88มีà¸\81ารสà¹\88à¸\87อีà¹\80มล',
-'mailnologintext' => 'à¸\95à¹\89อà¸\87à¸\81ารà¸\97ำ[[Special:UserLogin|ลà¹\87อà¸\81อิà¸\99]]à¹\81ละà¸\95ัà¹\89à¸\87à¸\84à¹\88าอีà¹\80มลà¹\83à¸\99สà¹\88วà¸\99[[Special:Preferences|à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88า]] à¹\80à¸\9eืà¹\88อà¸\88ะสà¹\88à¸\87อีà¹\80มลหาà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\84à¸\99อื่น',
+'mailnologin' => 'à¹\84มà¹\88มีà¸\97ีà¹\88อยูà¹\88สà¹\88à¸\87',
+'mailnologintext' => 'à¸\84ุà¸\93à¸\95à¹\89อà¸\87[[Special:UserLogin|ลà¹\87อà¸\81อิà¸\99]]à¹\81ละมีà¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\97ีà¹\88สมà¹\80หà¸\95ุสมà¸\9cลà¹\83à¸\99[[Special:Preferences|à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88า]]à¸\82อà¸\87à¸\84ุà¸\93 à¹\83à¸\99à¸\81ารสà¹\88à¸\87อีà¹\80มลหาà¸\9cูà¹\89à¹\83à¸\8aà¹\89อื่น',
 'emailuser' => 'ส่งอีเมลหาผู้ใช้นี้',
 'emailuser-title-target' => 'ส่งอีเมลหา{{GENDER:$1|ผู้ใช้}}',
 'emailuser-title-notarget' => 'อีเมลผู้ใช้',
 'emailpage' => 'อีเมลผู้ใช้',
-'emailpagetext' => 'à¸\84ุà¸\93สามารà¸\96à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\9fอรà¹\8cมà¸\94à¹\89าà¸\99ลà¹\88าà¸\87สà¹\88à¸\87อีà¹\80มลหา{{GENDER:$1|à¸\9cูà¹\89à¹\83à¸\8aà¹\89}}à¸\99ีà¹\89
+'emailpagetext' => 'คุณสามารถใช้แบบด้านล่างส่งอีเมลหา{{GENDER:$1|ผู้ใช้}}นี้
 ที่อยู่อีเมลที่คุณกรอกใน[[Special:Preferences|การตั้งค่าส่วนตัวของคุณ]]จะปรากฏเป็นที่อยู่ "จาก" ของอีเมล ซึ่งผู้รับสามารถตอบกลับคุณได้โดยตรง',
 'usermailererror' => 'การส่งอีเมลผิดพลาด:',
 'defemailsubject' => 'อีเมล {{SITENAME}} จากผู้ใช้ "$1"',
-'usermaildisabled' => 'สà¹\88à¸\87อีà¹\80มลหาà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\9bิà¸\94à¸\81ารà¹\83à¸\8aà¹\89à¸\87าà¸\99',
-'usermaildisabledtext' => 'à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96สà¹\88à¸\87อีà¹\80มลà¹\84à¸\9bหาà¸\9cูà¹\89à¹\83à¸\8aà¹\89อืà¹\88à¸\99à¸\9aà¸\99วิà¸\81ิà¸\99ีà¹\89',
+'usermaildisabled' => 'à¸\9bิà¸\94à¹\83à¸\8aà¹\89à¸\87าà¸\99à¸\81ารสà¹\88à¸\87อีà¹\80มลหาà¸\9cูà¹\89à¹\83à¸\8aà¹\89',
+'usermaildisabledtext' => 'คุณไม่สามารถส่งอีเมลหาผู้ใช้อื่นบนวิกินี้',
 'noemailtitle' => 'ไม่มีที่อยู่อีเมล',
 'noemailtext' => 'ผู้ใช้คนนี้ระบุที่อยู่อีเมลไม่ถูกต้อง',
 'nowikiemailtitle' => 'ไม่อนุญาตให้ใช้อีเมล',
 'nowikiemailtext' => 'ผู้ใช้คนนี้เลือกไม่รับอีเมลจากผู้ใช้อื่น',
 'emailnotarget' => 'ไม่มีชื่อผู้ใช้ของผู้รับหรือชื่อผู้ใช้ไม่ถูกต้อง',
 'emailtarget' => 'กรอกชื่อผู้ใช้ของผู้รับ',
-'emailusername' => 'ชื่อผู้ใช้ :',
+'emailusername' => 'ชื่อผู้ใช้:',
 'emailusernamesubmit' => 'ส่ง',
 'email-legend' => 'ส่งอีเมลถึงผู้ใช้ {{SITENAME}} อีกคน',
 'emailfrom' => 'จาก:',
@@ -2067,7 +2113,7 @@ $1',
 'usermessage-editor' => 'ตัวส่งข้อความของระบบ',
 
 # Watchlist
-'watchlist' => 'รายการเฝ้าดูของฉัน',
+'watchlist' => 'รายการเฝ้าดู',
 'mywatchlist' => 'รายการเฝ้าดู',
 'watchlistfor2' => 'สำหรับ $1 $2',
 'nowatchlist' => 'ไม่มีรายการในรายการเฝ้าดูของคุณ',
@@ -2075,7 +2121,7 @@ $1',
 'watchnologin' => 'ไม่ได้ล็อกอิน',
 'watchnologintext' => 'ต้อง[[Special:UserLogin|ล็อกอิน]]เพื่อแก้ไขรายการเฝ้าดูของคุณ',
 'addwatch' => 'เพิ่มเข้ารายการเฝ้าดู',
-'addedwatchtext' => 'หà¸\99à¹\89า "[[:$1]]" à¸\96ูà¸\81à¹\80à¸\9eิà¹\88มà¹\80à¸\82à¹\89า[[Special:Watchlist|รายà¸\81ารà¹\80à¸\9dà¹\89าà¸\94ู]]à¸\82อà¸\87à¸\84ุà¸\93 à¸\96à¹\89ามีà¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¹\83à¸\99หà¸\99à¹\89าà¸\99ีà¹\89 à¹\81ละหà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\97ีà¹\88à¹\80à¸\81ีà¹\88ยวà¸\82à¹\89อà¸\87à¸\88ะà¹\81สà¸\94à¸\87รายการด้านล่าง',
+'addedwatchtext' => 'หà¸\99à¹\89า "[[:$1]]" à¹\84à¸\94à¹\89à¹\80à¸\9eิà¹\88มลà¸\87à¹\83à¸\99[[Special:Watchlist|รายà¸\81ารà¹\80à¸\9dà¹\89าà¸\94ู]]à¸\82อà¸\87à¸\84ุà¸\93à¹\81ลà¹\89ว à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¹\83à¸\99หà¸\99à¹\89าà¸\99ีà¹\89หรือหà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\97ีà¹\88à¹\80à¸\81ีà¹\88ยวà¸\82à¹\89อà¸\87à¸\88ะà¹\81สà¸\94à¸\87à¹\83à¸\99รายการด้านล่าง',
 'removewatch' => 'นำออกจากรายการเฝ้าดู',
 'removedwatchtext' => 'หน้า "[[:$1]]" ถูกนำออกจาก[[Special:Watchlist|รายการเฝ้าดูของคุณ]]',
 'watch' => 'เฝ้าดู',
@@ -2083,31 +2129,38 @@ $1',
 'unwatch' => 'เลิกเฝ้าดู',
 'unwatchthispage' => 'เลิกเฝ้าดูหน้านี้',
 'notanarticle' => 'ไม่ใช่หน้าเนื้อหา',
-'notvisiblerev' => 'รุà¹\88à¸\99à¸\94ัà¸\87à¸\81ลà¹\88าวà¸\96ูà¸\81ลà¸\9aà¹\80รียà¸\9aรà¹\89อยแล้ว',
-'watchnochange' => 'à¹\84มà¹\88มีหà¸\99à¹\89าà¸\97ีà¹\88à¸\84ุà¸\93à¹\80à¸\9dà¹\89าà¸\94ูà¸\96ูà¸\81à¹\81à¸\81à¹\89à¹\84à¸\82ในระยะเวลาที่แสดง',
+'notvisiblerev' => 'รุà¹\88à¸\99ลà¹\88าสุà¸\94à¹\82à¸\94ยà¸\9cูà¹\89à¹\83à¸\8aà¹\89อีà¸\81à¸\84à¸\99à¸\96ูà¸\81ลà¸\9aแล้ว',
+'watchnochange' => 'à¹\84มà¹\88มีà¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\97ีà¹\88à¸\84ุà¸\93à¹\80à¸\9dà¹\89าà¸\94ูในระยะเวลาที่แสดง',
 'watchlist-details' => 'มี $1 หน้าในรายการเฝ้าดูของคุณ ไม่รวมหน้าอภิปราย',
 'wlheader-enotif' => '* แจ้งเตือนผ่านอีเมลถูกเปิดใช้งาน',
 'wlheader-showupdated' => "* หน้าที่มีการเปลี่ยนแปลงตั้งแต่การเข้าชมครั้งล่าสุดของคุณแสดงใน'''ตัวหนา'''",
 'watchmethod-recent' => 'ตรวจสอบการปรับปรุงล่าสุดกับหน้าเฝ้าดู',
 'watchmethod-list' => 'ตรวจสอบหน้าเฝ้าดูกับการแก้ไขล่าสุด',
 'watchlistcontains' => 'รายการเฝ้าดูของคุณมี $1 หน้า',
-'iteminvalidname' => "à¹\80à¸\81ิà¸\94à¸\9bัà¸\8dหาà¸\8aืà¹\88อà¹\84มà¹\88à¸\96ูà¸\81à¸\95à¹\89อà¸\87à¸\81ัà¸\9a '$1'...",
-'wlnote' => "à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82{{PLURAL:$1|สุà¸\94à¸\97à¹\89าย|ล่าสุด '''$1''' รายการ}} ใน{{PLURAL:$2|ชั่วโมง|ช่วง '''$2''' ชั่วโมง}}ที่ผ่านมา จนถึง $3, $4",
-'wlshowlast' => 'แสดงล่าสุดใน $1 ชั่วโมง $2 วัน $3',
+'iteminvalidname' => "à¹\80à¸\81ิà¸\94à¸\9bัà¸\8dหาà¸\81ัà¸\9aรายà¸\81าร '$1' à¸\8aืà¹\88อà¹\84มà¹\88à¸\96ูà¸\81à¸\95à¹\89อà¸\87...",
+'wlnote' => "à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82{{PLURAL:$1|ลà¹\88าสุà¸\94|ล่าสุด '''$1''' รายการ}} ใน{{PLURAL:$2|ชั่วโมง|ช่วง '''$2''' ชั่วโมง}}ที่ผ่านมา จนถึง $3, $4",
+'wlshowlast' => 'แสดง $1 ชั่วโมง $2 วันล่าสุด $3',
 'watchlist-options' => 'ตัวเลือกรายการเฝ้าดู',
 
 # Displayed when you click the "watch" button and it is in the process of watching
 'watching' => 'เฝ้าดู...',
 'unwatching' => 'เลิกเฝ้าดู...',
+'watcherrortext' => 'เกิดข้อผิดพลาดขณะเปลี่ยนแปลงการตั้งค่ารายการเฝ้าดูของคุณ เพราะ "$1"',
 
 'enotif_mailer' => 'แจ้งการแก้ไขจาก {{SITENAME}}',
 'enotif_reset' => 'ทำเครื่องหมายว่าชมทุกหน้าแล้ว',
 'enotif_impersonal_salutation' => 'ผู้ใช้งาน {{SITENAME}}',
-'enotif_subject_deleted' => '{{SITENAME}} หน้า $1 ถูกลบแล้วโดย {{gender:$2|$2}}',
-'enotif_subject_created' => '{{SITENAME}} หน้า $1 ถูกสร้างแล้วโดย {{gender:$2|$2}}',
-'enotif_subject_moved' => '{{SITENAME}} หน้า $1 ได้ย้ายแล้วโดย {{gender:$2|$2}}',
-'enotif_subject_changed' => '{{SITENAME}} หน้า $1 ได้เปลี่ยนแล้วโดย {{gender:$2|$2}}',
-'enotif_lastvisited' => 'ดู $1 สำหรับการเปลี่ยนแปลงทั้งหมดตั้งแต่ครั้งล่าสุดที่คุณเข้าชม',
+'enotif_subject_deleted' => 'หน้า $1 บน {{SITENAME}} ถูกลบโดย {{gender:$2|$2}}',
+'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_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',
 'enotif_body' => 'เรียน $WATCHINGUSERNAME
@@ -2143,14 +2196,14 @@ $UNWATCHURL
 'deletepage' => 'ลบหน้า',
 'confirm' => 'ยืนยัน',
 'excontent' => "เนื้อหาเดิม: '$1'",
-'excontentauthor' => "à¹\80à¸\99ืà¹\89อหาà¹\80à¸\94ิม: '$1' (à¹\81ละมีà¸\9cูà¹\89à¹\80à¸\82ียà¸\99à¸\84à¸\99à¹\80à¸\94ียว à¸\84ือ '[[Special:Contributions/$2|$2]]')",
+'excontentauthor' => "เนื้อหาเดิม: '$1' (และผู้เขียนคนเดียว คือ '[[Special:Contributions/$2|$2]]')",
 'exbeforeblank' => "เนื้อหาก่อนถูกทำว่างคือ: '$1'",
 'exblank' => 'หน้าว่าง',
 'delete-confirm' => 'ลบ "$1"',
 'delete-legend' => 'ลบ',
-'historywarning' => 'คำเตือน: หน้าที่คุณกำลังจะลบ มีประวัติการแก้ไขโดยประมาณ $1 {{PLURAL:$1|รุ่น}}:',
+'historywarning' => "'''คำเตือน:'''' หน้าที่คุณกำลังลบมีประวัติการแก้ไขประมาณ $1 {{PLURAL:$1|รุ่น}}:",
 'confirmdeletetext' => 'คุณกำลังลบหน้า รวมทั้งประวัติทั้งหมดของหน้า
-à¸\81รุà¸\93ายืà¸\99ยัà¸\99วà¹\88าà¸\84ุà¸\93à¹\80à¸\88à¸\95à¸\99า à¹\81ละà¸\84ุà¸\93à¹\80à¸\82à¹\89าà¹\83à¸\88à¸\9cลà¸\81ระà¸\97à¸\9a à¹\81ละà¸\81ารà¸\81ระà¸\97ำà¸\99ีà¹\89สอà¸\94à¸\84ลà¹\89อà¸\87à¸\81ัà¸\9a[[{{MediaWiki:Policy-url}}|à¸\99à¹\82ยà¸\9aาย]]',
+กรุณายืนยันว่าคุณเจตนา เข้าใจผลกระทบ และการกระทำนี้สอดคล้องกับ[[{{MediaWiki:Policy-url}}|นโยบาย]]',
 'actioncomplete' => 'ปฏิบัติการสำเร็จ',
 'actionfailed' => 'ปฏิบัติการล้มเหลว',
 'deletedtext' => '"$1" ถูกลบ
@@ -2187,56 +2240,60 @@ $UNWATCHURL
 'rollback-success' => 'ย้อนรุ่นที่แก้ไขโดย $1 ไปยังรุ่นล่าสุดโดย $2',
 
 # Edit tokens
-'sessionfailure-title' => 'Session นี้ล้มเหลว',
-'sessionfailure' => 'เหมือนจะมีปัญหาเกี่ยวการล็อกอินในช่วงเวลานี้ เกิดจากทางระบบป้องกันการลักลอบการขโมยล็อกอิน กรุณาย้อนกลับไปหน้าก่อนหน้า และลองโหลดใหม่อีกครั้ง',
+'sessionfailure-title' => 'ช่วงเวลาสื่อสารล้มเหลว',
+'sessionfailure' => 'ดูเหมือนมีปัญหากับช่วงเวลาสื่อสารล็อกอินของคุณ
+การกระทำนี้ถูกยกเลิกเป็นการป้องกันการลักลอบช่วงเวลาสื่อสารไว้ก่อน 
+กลับไปหน้าที่แล้ว โหลดหน้าใหม่ แล้วลองอีกครั้ง',
 
 # Protect
 'protectlogpage' => 'ปูมการล็อก',
-'protectlogtext' => 'à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¸\99ีà¹\89à¸\84ือรายà¸\81ารà¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99หน้า
-à¸\94ู[[Special:ProtectedPages|รายà¸\81ารหà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81à¸\9bà¹\89อà¸\87à¸\81ัà¸\99]]สำหรัà¸\9aà¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99หà¸\99à¹\89าในปัจจุบัน',
-'protectedarticle' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99 "[[$1]]"',
-'modifiedarticleprotection' => 'à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81สำหรัà¸\9a "[[$1]]"',
-'unprotectedarticle' => 'ยà¸\81à¹\80ลิà¸\81à¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99จาก "[[$1]]" แล้ว',
+'protectlogtext' => 'à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9bà¹\87à¸\99รายà¸\81ารà¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¸\81ารลà¹\87อà¸\81หน้า
+à¸\94ู[[Special:ProtectedPages|รายà¸\81ารหà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81ลà¹\87อà¸\81]]สำหรัà¸\9aà¸\81ารลà¹\87อà¸\81หà¸\99à¹\89าà¸\97ีà¹\88มีà¸\9cลอยูà¹\88ในปัจจุบัน',
+'protectedarticle' => 'ลà¹\87อà¸\81 "[[$1]]"',
+'modifiedarticleprotection' => 'à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81à¸\82อà¸\87 "[[$1]]"',
+'unprotectedarticle' => 'ยà¸\81à¹\80ลิà¸\81à¸\81ารลà¹\87อà¸\81จาก "[[$1]]" แล้ว',
 'movedarticleprotection' => 'ย้ายการตั้งค่าการล็อกจาก "[[$2]]" ไปยัง "[[$1]]"',
 'protect-title' => 'กำลังล็อกหน้า "$1"',
-'protect-title-notallowed' => 'à¸\94ูระà¸\94ัà¸\9aà¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99ของ "$1"',
+'protect-title-notallowed' => 'à¸\94ูระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81ของ "$1"',
 'prot_1movedto2' => '[[$1]] ถูกเปลี่ยนชื่อเป็น [[$2]]',
-'protect-badnamespace-title' => 'à¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¸\9bà¹\89อà¸\87à¸\81ัà¸\99ไม่ได้',
+'protect-badnamespace-title' => 'à¹\80à¸\99มสà¹\80à¸\9bà¸\8bลà¹\87อà¸\81ไม่ได้',
 'protect-badnamespace-text' => 'หน้าในเนมสเปซนี้ไม่สามารถป้องกันได้',
+'protect-norestrictiontypes-text' => 'หน้านี้ไม่สามารถถูกล็อก เพราะไม่มีประเภทการจำกัดที่ใช้ได้',
+'protect-norestrictiontypes-title' => 'หน้าที่ล็อกไม่ได้',
 'protect-legend' => 'ยืนยันการล็อก',
 'protectcomment' => 'เหตุผล:',
 'protectexpiry' => 'หมดอายุ:',
 'protect_expiry_invalid' => 'เวลาหมดอายุไม่ถูกต้อง',
 'protect_expiry_old' => 'เวลาหมดอายุผ่านมาแล้ว',
-'protect-unchain-permissions' => 'à¸\9bลà¸\94ลà¹\87อà¸\81à¸\95ัวà¹\80ลือà¸\81à¸\9bà¹\89อà¸\87à¸\81ัà¸\99อื่น ๆ',
-'protect-text' => "à¸\94ูà¹\81ละà¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81สำหรัà¸\9aหà¸\99à¹\89า '''$1'''.",
-'protect-locked-blocked' => "à¹\84มà¹\88สามารà¸\96à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81หà¸\99à¹\89าà¸\82à¸\93ะà¸\97ีà¹\88à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81à¹\84à¸\94à¹\89 à¸\94ูระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81à¸\82อà¸\87หà¸\99à¹\89า '''$1''':",
-'protect-locked-dblock' => "à¹\84มà¹\88สามารà¸\96à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81หà¸\99à¹\89าà¹\84à¸\94à¹\89à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\90าà¸\99à¸\82à¹\89อมูลà¸\96ูà¸\81ลà¹\87อà¸\81 à¸\94ูระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81à¸\82อà¸\87หà¸\99à¹\89า '''$1''':",
-'protect-locked-access' => "à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81หà¸\99à¹\89าà¹\84à¸\94à¹\89 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\84ุà¸\93à¹\84มà¹\88มีสิà¸\97à¸\98ิ  à¸\94ูระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81à¸\82อà¸\87หà¸\99à¹\89า '''$1''':",
-'protect-cascadeon' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¸\96ูà¸\81ลà¹\87อà¸\81à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87{{PLURAL:$1|หà¸\99à¹\89า|หà¸\99à¹\89า}}à¸\97ีà¹\88à¸\96ูà¸\81ล็อกแบบสืบทอด
+'protect-unchain-permissions' => 'à¸\9bลà¸\94ลà¹\87อà¸\81à¸\95ัวà¹\80ลือà¸\81à¸\81ารลà¹\87อà¸\81อื่น ๆ',
+'protect-text' => "à¸\97ีà¹\88à¸\99ีà¹\88à¸\84ุà¸\93สามารà¸\96à¸\94ูà¹\81ละà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81à¸\82อà¸\87หà¸\99à¹\89า '''$1''' à¹\84à¸\94à¹\89",
+'protect-locked-blocked' => "à¹\84มà¹\88สามารà¸\96à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81หà¸\99à¹\89าà¸\82à¸\93ะà¸\97ีà¹\88à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81à¹\84à¸\94à¹\89 à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าà¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\82อà¸\87หà¸\99à¹\89า '''$1''' à¸\84ือ:",
+'protect-locked-dblock' => "à¹\84มà¹\88สามารà¸\96à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81à¹\84à¸\94à¹\89à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\90าà¸\99à¸\82à¹\89อมูลà¸\96ูà¸\81ลà¹\87อà¸\81 à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าà¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\82อà¸\87หà¸\99à¹\89า '''$1''' à¸\84ือ:",
+'protect-locked-access' => "à¸\9aัà¸\8dà¸\8aีà¸\82อà¸\87à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aอà¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81หà¸\99à¹\89า à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88าà¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\82อà¸\87หà¸\99à¹\89า '''$1''' à¸\84ือ:",
+'protect-cascadeon' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¸\96ูà¸\81ลà¹\87อà¸\81à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87{{PLURAL:$1|หà¸\99à¹\89า|หà¸\99à¹\89า}}à¸\97ีà¹\88à¹\80à¸\9bิà¸\94à¸\81ารล็อกแบบสืบทอด
 คุณสามารถเปลี่ยนระดับการล็อกได้ แต่จะไม่มีผลต่อการล็อกแบบสืบทอด',
 'protect-default' => 'อนุญาตผู้ใช้ทั้งหมด',
-'protect-fallback' => 'à¸\88ำà¹\80à¸\9bà¹\87à¸\99à¸\95à¹\89อà¸\87à¹\83à¸\8aà¹\89สิà¸\97à¸\98ิà¹\83à¸\99à¸\81าร "$1"',
-'protect-level-autoconfirmed' => 'à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\83หมà¹\88à¹\81ละà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\84มà¹\88ลà¸\87à¸\97ะà¹\80à¸\9aียà¸\99',
-'protect-level-sysop' => 'เฉพาะผู้ดูแลระบบ',
+'protect-fallback' => 'อà¸\99ุà¸\8dาà¸\95à¹\80à¸\89à¸\9eาะà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88มีสิà¸\97à¸\98ิ "$1"',
+'protect-level-autoconfirmed' => 'อà¸\99ุà¸\8dาà¸\95à¹\80à¸\89à¸\9eาะà¸\9cูà¹\89à¹\83à¸\8aà¹\89ยืà¸\99ยัà¸\99อัà¸\95à¹\82à¸\99มัà¸\95ิ',
+'protect-level-sysop' => 'อà¸\99ุà¸\8dาà¸\95à¹\80à¸\89à¸\9eาะà¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9a',
 'protect-summary-cascade' => 'สืบทอด',
 'protect-expiring' => 'หมดอายุ $1 (UTC)',
 'protect-expiring-local' => 'หมดอายุ $1',
-'protect-expiry-indefinite' => 'à¸\95ลอà¸\94à¸\81าล',
+'protect-expiry-indefinite' => 'à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94',
 'protect-cascade' => 'ล็อกหน้าที่เป็นส่วนหนึ่งของหน้านี้ (ล็อกแบบสืบทอด)',
-'protect-cantedit' => 'à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89 à¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aสิà¸\97à¸\98ิà¹\83à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82สิà¹\88à¸\87à¸\99ัà¹\89à¸\99',
+'protect-cantedit' => 'à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¹\80à¸\9bลีà¹\88ยà¸\99ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81à¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89 à¹\80à¸\9eราะà¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aอà¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¹\81à¸\81à¹\89à¹\84à¸\82ระà¸\94ัà¸\9aà¸\81ารลà¹\87อà¸\81',
 'protect-othertime' => 'ระยะเวลาอื่น:',
 'protect-othertime-op' => 'ระยะเวลาอื่น',
 'protect-existing-expiry' => 'ระยะเวลาการป้องกัน: $3, $2',
-'protect-otherreason' => 'เหตุผลอื่นเพิ่มเติม:',
-'protect-otherreason-op' => 'สาà¹\80หà¸\95ุอื่น',
+'protect-otherreason' => 'เหตุผลอื่น/เพิ่มเติม:',
+'protect-otherreason-op' => 'à¹\80หà¸\95ุà¸\9cลอื่น',
 'protect-dropdown' => '* เหตุผลการป้องกันทั่วไป
 ** การก่อกวนจำนวนมาก
 ** สแปมจำนวนมาก
 ** สงครามการแก้ไขที่ไม่สร้างสรรค์
 ** หน้าที่มีการเข้าชมมาก',
 'protect-edit-reasonlist' => 'สาเหตุการป้องกันการแก้ไข',
-'protect-expiry-options' => '1 à¸\8aัà¹\88วà¹\82มà¸\87:1 hour,1 à¸§à¸±à¸\99:1 day,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¸\95ลอà¸\94à¸\81าล:infinite',
+'protect-expiry-options' => '1 à¸\8aัà¹\88วà¹\82มà¸\87:1 hour,1 à¸§à¸±à¸\99:1 day,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94:infinite',
 'restriction-type' => 'อนุญาต',
 'restriction-level' => 'ระดับการล็อก',
 'minimum-size' => 'ขนาดอย่างน้อย',
@@ -2250,33 +2307,37 @@ $UNWATCHURL
 'restriction-upload' => 'อัปโหลด',
 
 # Restriction levels
-'restriction-level-sysop' => 'ลà¹\87อà¸\81à¹\80à¸\95à¹\87มà¸\97ีà¹\88',
-'restriction-level-autoconfirmed' => 'ลà¹\87อà¸\81à¸\9cูà¹\89à¹\84มà¹\88ลà¹\87อà¸\81อิà¸\99',
-'restriction-level-all' => 'ระดับ',
+'restriction-level-sysop' => 'ลà¹\87อà¸\81สมà¸\9aูรà¸\93à¹\8c',
+'restriction-level-autoconfirmed' => 'à¸\81ึà¹\88à¸\87ลà¹\87อà¸\81',
+'restriction-level-all' => 'à¸\97ุà¸\81ระà¸\94ัà¸\9a',
 
 # Undelete
 'undelete' => 'ดูหน้าที่ถูกลบ',
 'undeletepage' => 'ดูและกู้คืนหน้าที่ถูกลบ',
-'undeletepagetitle' => "'''ต่อไปนี้เป็นรุ่นการแก้ไขของ [[:$1|$1]] ที่ถูกลบ'''",
-'viewdeletedpage' => 'หน้าที่ถูกลบ',
-'undeletepagetext' => '{{PLURAL:$1|หน้า|หน้า}}ต่อไปนี้ถูกลบไปแล้ว แต่ยังคงอยู่ในกรุซึ่งสามารถเรียกคืนได้ กรุข้อมูลอาจถูกลบเป็นระยะ',
-'undelete-fieldset-title' => 'กู้คืนรุ่นต่าง ๆ',
+'undeletepagetitle' => "'''ต่อไปนี้เป็นรุ่นการแก้ไขที่ถูกลบของ [[:$1|$1]]'''",
+'viewdeletedpage' => 'ดูหน้าที่ถูกลบ',
+'undeletepagetext' => '{{PLURAL:$1||$1 }}หน้าต่อไปนี้ถูกลบไปแล้ว แต่เนื้อหายังคงอยู่ในกรุและสามารถกู้คืนได้ 
+กรุอาจถูกลบเป็นระยะได้',
+'undelete-fieldset-title' => 'กู้คืนรุ่น',
 'undeleteextrahelp' => "ถ้าต้องการกู้ประวัติของหน้าคืนทั้งหมด ไม่ต้องเลือกกล่องใดเลย แล้วกดปุ่ม '''''กู้คืน'''''
 ถ้าต้องการกู้ประวัติคืนเฉพาะบางส่วน ให้เลือกกล่องที่มีประวัติส่วนที่ต้องการกู้ แล้วกด'''''กู้คืน'''''
 กด '''''ล้างค่า''''' เพื่อลบค่าในกล่องความเห็นและกล่องตัวเลือกทั้งหมด",
 'undeleterevisions' => '$1 รุ่นการแก้ไขถูกเก็บไว้',
 'undeletehistory' => 'เมื่อคุณกู้หน้าใดหน้าหนึ่ง รุ่นทั้งหมดจะถูกกู้คืนไปยังประวัติ หากมีหน้าใหม่ในชื่อเดียวกันถูกสร้างขึ้นหลังจากการลบ รุ่นที่กู้คืนนั้นจะปรากฏในประวัติที่มีมาก่อน',
-'undeleterevdel' => 'จะกู้คืนไม่ได้หากการกู้คืนนั้นส่งผลให้รุ่นล่าสุดของหน้าหรือไฟล์ถูกลบไปบางส่วน ในกรณีเช่นนั้น คุณต้องไม่เลือกหรือแสดงรุ่นใหม่สุดที่ถูกลบไปก่อน',
-'undeletehistorynoadmin' => 'หน้านี้ถูกลบก่อนหน้านี้ โดยสาเหตุการลบและรายชื่อผู้ร่วมแก้ไขก่อนหน้าแสดงผลด้านล่าง สำหรับข้อมูลที่ถูกลบจะดูได้เฉพาะผู้ดูแลระบบ',
+'undeleterevdel' => 'จะกู้คืนไม่ได้หากการกู้คืนนั้นส่งผลให้รุ่นล่าสุดของหน้าหรือไฟล์ถูกลบไปบางส่วน 
+ในกรณีเช่นนั้น คุณต้องไม่เลือกหรือแสดงรุ่นใหม่สุดที่ถูกลบไปก่อน',
+'undeletehistorynoadmin' => 'หน้านี้ถูกลบไปแล้ว
+มีสาเหตุการลบแสดงไว้ในคำอธิบายอย่างย่อข้างล่าง ร่วมกับรายละเอียดผู้ใช้ที่เคยแก้ไขหน้านี้ก่อนลบ
+ข้อความแท้จริงของรุ่นที่ถูกลบดูได้เฉพาะผู้ดูแลระบบ',
 'undelete-revision' => 'รุ่นที่ถูกลบของหน้า $1 (ตั้งแต่ $4 เมื่อ $5) โดย $3:',
 'undeleterevision-missing' => 'รุ่นไม่ถูกต้องหรือสูญหาย
 คุณอาจมีลิงก์เสีย หรือรุ่นอาจถูกกู้คืนหรือนำออกจากกรุ',
 'undelete-nodiff' => 'ไม่พบรุ่นก่อนหน้า',
 'undeletebtn' => 'กู้คืน',
 'undeletelink' => 'ดู/กู้คืน',
-'undeleteviewlink' => 'à¹\80รียà¸\81à¸\94ู',
-'undeletereset' => 'ลà¹\89าà¸\87à¸\84à¹\88า',
-'undeleteinvert' => 'à¸\81ลัà¸\9aà¸\84à¹\88าà¸\97ีà¹\88เลือก',
+'undeleteviewlink' => 'ดู',
+'undeletereset' => 'à¸\95ัà¹\89à¸\87à¹\83หมà¹\88',
+'undeleteinvert' => 'à¸\81ลัà¸\9aà¸\81ารเลือก',
 'undeletecomment' => 'เหตุผล:',
 'undeletedrevisions' => '$1 รุ่นการแก้ไขถูกกู้คืน',
 'undeletedrevisions-files' => '$1 รุ่น และ $2 ไฟล์ถูกกู้คืน',
@@ -2289,19 +2350,20 @@ $1',
 'undelete-header' => 'ดู [[Special:Log/delete|ปูมการลบ]] สำหรับหน้าที่ถูกลบล่าสุด',
 'undelete-search-title' => 'ค้นหาหน้าที่ถูกลบ',
 'undelete-search-box' => 'ค้นหาหน้าที่ถูกลบ',
-'undelete-search-prefix' => 'à¸\84à¹\89à¸\99หาหà¸\99à¹\89าà¸\97ีà¹\88à¹\80ริà¹\88มต้นด้วย:',
-'undelete-search-submit' => 'สืà¸\9aà¸\84à¹\89à¸\99',
+'undelete-search-prefix' => 'à¸\84à¹\89à¸\99หาหà¸\99à¹\89าà¸\97ีà¹\88à¸\82ึà¹\89à¸\99ต้นด้วย:',
+'undelete-search-submit' => 'à¸\84à¹\89à¸\99หา',
 'undelete-no-results' => 'ไม่พบหน้าที่ตรงกันในกรุการลบ',
-'undelete-filename-mismatch' => 'ไม่สามารถกู้คืนไฟล์ $1: ชื่อไฟล์ไม่ถูกต้อง',
-'undelete-bad-store-key' => 'ไม่สามารถกู้คืนไฟล์ $1: ไม่มีไฟล์ก่อนที่จะถูกลบ',
-'undelete-cleanup-error' => 'เกิดปัญหาการลบไฟล์เก่า "$1"',
-'undelete-missing-filearchive' => 'ไม่สามารถกู้คืนไฟล์เก่ารุ่น $1 เพราะไม่มีไฟล์อยู่ในฐานข้อมูล ไฟล์อาจถูกกู้คืนไปแล้ว',
-'undelete-error' => 'เกิดข้อผิดพลาด ไม่สามารถลบหน้าเวปได้',
-'undelete-error-short' => 'เกิดปัญหาในการกู้คืนไฟล์: $1',
-'undelete-error-long' => 'เกิดความผิดพลาดระหว่างการลบไฟล์:
+'undelete-filename-mismatch' => 'ไม่สามารถกู้คืนรุ่นไฟล์ที่มีตราเวลา $1: ชื่อไฟล์ไม่ตรง',
+'undelete-bad-store-key' => 'ไม่สามารถกู้คืนรุ่นไฟล์ที่มีตราเวลา $1: ไฟล์สูญหายก่อนถูกลบ',
+'undelete-cleanup-error' => 'เกิดความผิดพลาดในการลบไฟล์กรุที่ไม่ใช้แล้ว "$1"',
+'undelete-missing-filearchive' => 'ไม่สามารถกู้คืนไฟล์เก่าหมายเลข $1 เพราะไม่มีในฐานข้อมูล 
+ไฟล์อาจถูกกู้คืนไปแล้ว',
+'undelete-error' => 'เกิดข้อผิดพลาดในการกู้คืนหน้า',
+'undelete-error-short' => 'เกิดข้อผิดพลาดในการกู้คืนไฟล์: $1',
+'undelete-error-long' => 'เกิดข้อผิดพลาดขณะกู้คืนไฟล์:
 
 $1',
-'undelete-show-file-confirm' => 'à¹\81à¸\99à¹\88à¹\83à¸\88หรือà¹\84มà¹\88วà¹\88าà¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\81ารà¸\88ะà¸\94ูรุà¹\88à¸\99à¸\97ีà¹\88à¸\96ูà¸\81ลà¸\9aà¹\84à¸\9b à¸ªà¸³à¸«à¸£à¸±à¸\9aไฟล์ "<nowiki>$1</nowiki>" ตั้งแต่ $2 เมื่อ $3',
+'undelete-show-file-confirm' => 'à¸\84ุà¸\93à¹\81à¸\99à¹\88à¹\83à¸\88หรือวà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\94ูรุà¹\88à¸\99à¸\97ีà¹\88à¸\96ูà¸\81ลà¸\9aà¸\82อà¸\87ไฟล์ "<nowiki>$1</nowiki>" ตั้งแต่ $2 เมื่อ $3',
 'undelete-show-file-submit' => 'ใช่',
 
 # Namespace form on various pages
@@ -2322,8 +2384,8 @@ $1',
 'month' => 'จากเดือน (และก่อนหน้า):',
 'year' => 'จากปี (และก่อนหน้า):',
 
-'sp-contributions-newbies' => 'à¹\81สà¸\94à¸\87à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89ใหม่เท่านั้น',
-'sp-contributions-newbies-sub' => 'สำหรัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89ใหม่',
+'sp-contributions-newbies' => 'à¹\81สà¸\94à¸\87à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\9aัà¸\8dà¸\8aีใหม่เท่านั้น',
+'sp-contributions-newbies-sub' => 'สำหรัà¸\9aà¸\9aัà¸\8dà¸\8aีใหม่',
 'sp-contributions-newbies-title' => 'เรื่องที่เขียนโดยบัญชีใหม่',
 'sp-contributions-blocklog' => 'ปูมการบล็อก',
 'sp-contributions-deleted' => 'การแก้ไขที่ถูกลบ',
@@ -2336,7 +2398,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'ปัจจุบันเลขที่อยู่ไอพีนี้ถูกบล็อก
 ปูมการบล็อกล่าสุดแสดงด้านล่างนี้เพื่อการอ้างอิง:',
 'sp-contributions-search' => 'ค้นหาการแก้ไข',
-'sp-contributions-username' => 'หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้:',
+'sp-contributions-username' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้:',
 'sp-contributions-toponly' => 'แสดงเฉพาะการแก้ไขรุ่นล่าสุด',
 'sp-contributions-submit' => 'สืบค้น',
 
@@ -2366,9 +2428,9 @@ $1',
 'blockip' => 'บล็อกผู้ใช้',
 'blockip-title' => 'ระงับผู้ใช้',
 'blockip-legend' => 'บล็อกผู้ใช้',
-'blockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9eืà¹\88อà¸\9aลà¹\87อà¸\81สิà¸\97à¸\98ิà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¸\82อà¸\87หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้โดยเจาะจง การบล็อกนี้ควรดำเนินการเพื่อป้องกันการก่อกวนเท่านั้น และให้สอดคล้องกับ[[{{MediaWiki:Policy-url}}|นโยบาย]]
+'blockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9eืà¹\88อà¸\9aลà¹\87อà¸\81สิà¸\97à¸\98ิà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¸\82อà¸\87à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้โดยเจาะจง การบล็อกนี้ควรดำเนินการเพื่อป้องกันการก่อกวนเท่านั้น และให้สอดคล้องกับ[[{{MediaWiki:Policy-url}}|นโยบาย]]
 กรอกเหตุผลโดยเจาะจงด้านล่าง (เช่น อ้างถึงหน้าที่ถูกก่อกวน)',
-'ipadressorusername' => 'หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้',
+'ipadressorusername' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้',
 'ipbexpiry' => 'หมดอายุ',
 'ipbreason' => 'เหตุผล:',
 'ipbreasonotherlist' => 'เลือกสาเหตุ',
@@ -2380,32 +2442,33 @@ $1',
 ** คุกคามผู้อื่น
 ** ก่อกวนผู้อื่น
 ** ชื่อผู้ใช้ที่ไม่สุภาพหรือไม่ควรใช้',
-'ipb-hardblock' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89ลà¹\87อà¸\81อิà¸\99à¹\81à¸\81à¹\89à¹\84à¸\82à¸\88าà¸\81หมายà¹\80ลà¸\82ไอพีนี้',
+'ipb-hardblock' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89ลà¹\87อà¸\81อิà¸\99à¹\81à¸\81à¹\89à¹\84à¸\82à¸\88าà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีนี้',
 'ipbcreateaccount' => 'ป้องกันการสร้างบัญชี',
 'ipbemailban' => 'ป้องกันมิให้ผู้ใช้ส่งอีเมล',
-'ipbenableautoblock' => 'à¸\9aลà¹\87อà¸\81หมายà¹\80ลà¸\82à¹\84อà¸\9eีลà¹\88าสุà¸\94à¸\97ีà¹\88à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\83à¸\8aà¹\89 à¸\97ัà¹\89à¸\87à¸\97ุà¸\81หมายà¹\80ลà¸\82ไอพีที่ผู้นั้นพยายามใช้แก้ไขโดยอัตโนมัติ',
+'ipbenableautoblock' => 'à¸\9aลà¹\87อà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีลà¹\88าสุà¸\94à¸\97ีà¹\88à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\83à¸\8aà¹\89 à¸\97ัà¹\89à¸\87à¸\97ุà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีที่ผู้นั้นพยายามใช้แก้ไขโดยอัตโนมัติ',
 'ipbsubmit' => 'บล็อกผู้ใช้นี้',
 'ipbother' => 'เวลาอื่น',
-'ipboptions' => '2 à¸\8aัà¹\88วà¹\82มà¸\87:2 hours,1 à¸§à¸±à¸\99:1 day,3 à¸§à¸±à¸\99:3 days,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¸\95ลอà¸\94à¸\81าล:infinite',
+'ipboptions' => '2 à¸\8aัà¹\88วà¹\82มà¸\87:2 hours,1 à¸§à¸±à¸\99:1 day,3 à¸§à¸±à¸\99:3 days,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94:infinite',
 'ipbotheroption' => 'เลือกเวลา',
 'ipbotherreason' => 'เหตุผลอื่น',
 'ipbhidename' => 'ซ่อนผู้ใช้จากปูมการบล็อก และรายการผู้ที่ถูกบล็อก',
 'ipbwatchuser' => 'เฝ้าดูหน้าผู้ใช้และหน้าคุยกับผู้ใช้ของผู้ใช้รายนี้',
-'ipb-disableusertalk' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยของตัวเองขณะถูกบล็อก',
+'ipb-disableusertalk' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\84ุยà¸\81ัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89ของตัวเองขณะถูกบล็อก',
 'ipb-change-block' => 'บล็อกผู้ใช้อีกครั้งด้วยการตั้งค่าเหล่านี้',
 'ipb-confirm' => 'ยืนยันการบล็อก',
-'badipaddress' => 'หมายเลขไอพีไม่ถูกต้อง',
-'blockipsuccesssub' => 'บล็อกสำเร็จ',
-'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] ถูกบล็อก<br />
-ดู[[Special:BlockList|รายการบล็อก]]เพื่อทบทวนการบล็อก',
-'ipb-blockingself' => 'คุณกำลังทำการบล็อกตัวคุณเอง คุณแน่ใจแล้วหรือว่าต้องการทำเช่นนั้น',
+'badipaddress' => 'เลขที่อยู่ไอพีไม่ถูกต้อง',
+'blockipsuccesssub' => 'บล็อกเรียบร้อย',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] ได้ถูกบล็อกแล้ว<br />
+ดู[[Special:BlockList|รายการบล็อก]]เพื่อทบทวนการบล็อกดังกล่าว',
+'ipb-blockingself' => 'คุณกำลังบล็อกตัวเอง! แน่ใจแล้วหรือว่าต้องการทำอย่างนั้น',
+'ipb-confirmhideuser' => 'คุณกำลังบล็อกผู้ใช้โดยเป็นผู้ใช้ "ซ่อนผู้ใช้" ซึ่งจะระงับชื่อผู้ใช้ในรายการและหน่วยปูมทั้งหมด คุณแน่ใจหรือว่าต้องการดำเนินการเช่นนั้น',
 'ipb-edit-dropdown' => 'แก้ไขสาเหตุการบล็อก',
 'ipb-unblock-addr' => 'เลิกบล็อก $1',
-'ipb-unblock' => 'à¹\80ลิà¸\81à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหมายà¹\80ลà¸\82ไอพี',
+'ipb-unblock' => 'à¹\80ลิà¸\81à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือà¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพี',
 'ipb-blocklist' => 'ดูการบล็อกปัจจุบัน',
 'ipb-blocklist-contribs' => 'ผลงานเขียนโดย $1',
 'unblockip' => 'ปลดบล็อกผู้ใช้',
-'unblockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87สำหรัà¸\9aà¸\84ืà¸\99สิà¸\97à¸\98ิà¸\81ารà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¹\81à¸\81à¹\88หมายà¹\80ลà¸\82ไอพี หรือชื่อผู้ใช้ที่เคยถูกบล็อก',
+'unblockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87สำหรัà¸\9aà¸\84ืà¸\99สิà¸\97à¸\98ิà¸\81ารà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¹\81à¸\81à¹\88à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพี หรือชื่อผู้ใช้ที่เคยถูกบล็อก',
 'ipusubmit' => 'ยกเลิกการบล็อกนี้',
 'unblocked' => '[[User:$1|$1]] ถูกบล็อก',
 'unblocked-range' => '$1 ถูกปลดบล็อกแล้ว',
@@ -2416,6 +2479,7 @@ $1',
 'blocklist-userblocks' => 'ซ่อนบล็อกบัญชี',
 'blocklist-tempblocks' => 'ซ่อนบล็อกชั่วคราว',
 'blocklist-addressblocks' => 'ซ่อนบล็อกไอพีเดียว',
+'blocklist-rangeblocks' => 'ซ่อนการบล็อกช่วง',
 'blocklist-timestamp' => 'ตราเวลา',
 'blocklist-target' => 'เป้าหมาย',
 'blocklist-expiry' => 'หมดอายุ',
@@ -2425,7 +2489,7 @@ $1',
 'ipblocklist-submit' => 'สืบค้น',
 'ipblocklist-localblock' => 'การสกัดกั้นภายในวิกินี้',
 'ipblocklist-otherblocks' => '{{PLURAL:$1|การสกัดกั้น}}อื่นๆ',
-'infiniteblock' => 'à¸\95ลอà¸\94à¸\81าล',
+'infiniteblock' => 'à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94',
 'expiringblock' => 'หมดอายุ $1 เวลา $2',
 'anononlyblock' => 'ไม่ล็อกอินเท่านั้น',
 'noautoblockblock' => 'ยกเลิกการบล็อกอัตโนมัติ',
@@ -2433,13 +2497,13 @@ $1',
 'emailblock' => 'บล็อกการส่งอีเมล',
 'blocklist-nousertalk' => 'ไม่สามารถแก้ไขหน้าอภิปรายของตนเอง',
 'ipblocklist-empty' => 'รายการบล็อกว่าง',
-'ipblocklist-no-results' => 'หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้ที่ต้องการไม่ได้ถูกบล็อก',
+'ipblocklist-no-results' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้ที่ต้องการไม่ได้ถูกบล็อก',
 'blocklink' => 'บล็อก',
 'unblocklink' => 'เลิกบล็อก',
 'change-blocklink' => 'เปลี่ยนการบล็อก',
 'contribslink' => 'เรื่องที่เขียน',
 'emaillink' => 'ส่งอีเมล',
-'autoblocker' => 'à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81อัà¸\95à¹\82à¸\99มัà¸\95ิà¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81หมายà¹\80ลà¸\82ไอพีของคุณล่าสุดถูกใช้โดย "[[User:$1|$1]]" เหตุผลที่ให้แก่การบล็อก $1 คือ: "$2"',
+'autoblocker' => 'à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81อัà¸\95à¹\82à¸\99มัà¸\95ิà¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณล่าสุดถูกใช้โดย "[[User:$1|$1]]" เหตุผลที่ให้แก่การบล็อก $1 คือ: "$2"',
 'blocklogpage' => 'ปูมการบล็อก',
 'blocklog-showlog' => 'ผู้ใช้นี้ถูกสกัดกั้นมาก่อน
 ปูมการสกัดกั้นแสดงไว้ด้านล่างนี้เพื่อการอ้างอิง:',
@@ -2467,16 +2531,16 @@ $1',
 'ipb-otherblocks-header' => '{{PLURAL:$1|การบล็อก}}อื่น ๆ',
 'unblock-hideuser' => 'คุณไม่สามารถยกเลิกการบล็อคผู้ใช้งานรายนี้ได้, เนื่องจากชื่อผู้ใช้ของผู้ใช้งานถูกซ่อนอยู่',
 'ipb_cant_unblock' => 'ปัญหา: หมายเลขบล็อก $1 ไม่พบ อาจเกิดจากได้ถูกยกเลิกการบล็อกแล้ว',
-'ipb_blocked_as_range' => 'มีà¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¸«à¸¡à¸²à¸¢à¹\80ลà¸\82à¹\84อà¸\9eี $1 à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\81ละà¹\84มà¹\88สามารà¸\96ยà¸\81à¹\80ลิà¸\81à¸\81ารระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\84à¸\94à¹\89.  à¸­à¸¢à¹\88าà¸\87à¹\84รà¸\81à¹\87à¸\95าม à¹\84อà¸\9eีà¸\99ีà¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\83à¸\99à¸\90าà¸\99ะà¸\97ีà¹\88à¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87หมายà¹\80ลà¸\82à¹\84อà¸\9eีà¹\83à¸\99à¸\8aà¹\88วà¸\87 $2 ซึ่งสามารถยกเลิกการระงับได้',
-'ip_range_invalid' => 'à¸\8aà¹\88วà¸\87ไอพีไม่ถูกต้อง',
+'ipb_blocked_as_range' => 'มีà¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี $1 à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\81ละà¹\84มà¹\88สามารà¸\96ยà¸\81à¹\80ลิà¸\81à¸\81ารระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\84à¸\94à¹\89.  à¸­à¸¢à¹\88าà¸\87à¹\84รà¸\81à¹\87à¸\95าม à¹\84อà¸\9eีà¸\99ีà¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\83à¸\99à¸\90าà¸\99ะà¸\97ีà¹\88à¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¹\83à¸\99à¸\9eิสัย $2 ซึ่งสามารถยกเลิกการระงับได้',
+'ip_range_invalid' => 'à¸\9eิสัยไอพีไม่ถูกต้อง',
 'ip_range_toolarge' => 'ขนาดบล็อกมีขนาดใหญ่กว่า / $1 จะไม่ได้รับอนุญาต',
 'blockme' => 'บล็อกฉัน',
 'proxyblocker' => 'บล็อกพร็อกซี',
 'proxyblocker-disabled' => 'ฟังก์ชั่นนี้ไม่สามารถใช้ได้',
-'proxyblockreason' => 'หมายà¹\80ลà¸\82ไอพีของคุณถูกบล็อกเนื่องจากเป็นพร็อกซีเปิด กรุณาติดต่อผู้ให้บริการอินเทอร์เน็ตที่คุณใช้งานอยู่เกี่ยวกับปัญหานี้',
+'proxyblockreason' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณถูกบล็อกเนื่องจากเป็นพร็อกซีเปิด กรุณาติดต่อผู้ให้บริการอินเทอร์เน็ตที่คุณใช้งานอยู่เกี่ยวกับปัญหานี้',
 'proxyblocksuccess' => 'บล็อกสำเร็จ',
-'sorbsreason' => 'หมายà¹\80ลà¸\82ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์',
-'sorbs_create_account_reason' => 'หมายà¹\80ลà¸\82ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์ ดังนั้นคุณไม่สามารถสร้างชื่อบัญชีผู้ใช้ได้',
+'sorbsreason' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์',
+'sorbs_create_account_reason' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์ ดังนั้นคุณไม่สามารถสร้างชื่อบัญชีผู้ใช้ได้',
 'cant-block-while-blocked' => 'คุณไม่สามารถบล็อกผู้ใช้อื่นในขณะที่คุณกำลังถูกบล็อก',
 'cant-see-hidden-user' => 'ผู้ใช้ที่คุณกำลังพยายามระงับนั้นได้ถูกระงับหรือซ่อนเดิมอยู่แล้ว เนื่องจากคุณไม่มีสิทธิซ่อนผู้ใช้ คุณจึงไม่สามารถดูหรือแก้ไขการระงับผู้ใช้ได้',
 'ipbblocked' => 'คุณไม่สามารถบล็อกหรือปลดบล็อกผู้ใช้คนอื่น เนื่องจากคุณกำลังถูกบล็อก',
@@ -2503,12 +2567,13 @@ $1',
 # Move page
 'move-page' => 'ย้าย $1',
 'move-page-legend' => 'เปลี่ยนชื่อ',
-'movepagetext' => "à¸\81ารà¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¸\88ะà¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อหà¸\99à¹\89า à¸\8bึà¹\88à¸\87à¸\88ะà¸\97ำà¹\83หà¹\89à¸\9bระวัà¸\95ิà¸\97ัà¹\89à¸\87หมà¸\94ยà¹\89ายไปยังชื่อใหม่
+'movepagetext' => "à¸\81ารà¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¸\88ะสà¹\88à¸\87à¸\9cลà¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อหà¸\99à¹\89า à¹\81ละยà¹\89ายà¸\9bระวัà¸\95ิà¸\97ัà¹\89à¸\87หมà¸\94ไปยังชื่อใหม่
 ชื่อเรื่องเก่าจะกลายเป็นหน้าเปลี่ยนทางไปยังชื่อเรื่องใหม่
-ให้แน่ใจว่า ตรวจสอบ[[Special:DoubleRedirects|หน้าเปลี่ยนทางซ้ำซ้อน]]หรือ[[Special:BrokenRedirects|หน้าเปลี่ยนทางที่เสีย]]
-คุณจะเป็นผู้รับผิดชอบเพื่อให้แน่ใจว่าลิงก์ต่าง ๆ ยังชี้ไปยังที่ที่สมควร
+คุณสามารถปรับให้หน้าเปลี่ยนทางที่ชี้ไปยังชื่อเรื่องเดิมได้อัตโนมัติ
+แต่หากคุณเลือกไม่ทำเช่นนั้น ให้แน่ใจว่าตรวจสอบ[[Special:DoubleRedirects|หน้าเปลี่ยนทางซ้ำซ้อน]]หรือ[[Special:BrokenRedirects|หน้าเปลี่ยนทางที่เสีย]]
+คุณเป็นผู้รับผิดชอบเพื่อให้แน่ใจว่าลิงก์ต่าง ๆ ยังชี้ไปยังที่ที่สมควร
 
-à¹\82à¸\9bรà¸\94à¸\97ราà¸\9aวà¹\88าหà¸\99à¹\89าà¸\94ัà¸\87à¸\81ลà¹\88าวà¸\88ะ'''à¹\84มà¹\88'''à¸\96ูà¸\81ยà¹\89าย à¸\96à¹\89ามีหà¸\99à¹\89าà¸\97ีà¹\88à¹\83à¸\8aà¹\89à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¹\83หมà¹\88อยูà¹\88à¹\81ลà¹\89ว à¹\80วà¹\89à¸\99à¹\81à¸\95à¹\88à¹\80à¸\9bà¹\87à¸\99หà¸\99à¹\89าวà¹\88าà¸\87หรือหน้าเปลี่ยนทาง และไม่มีประวัติการแก้ไขในอดีต
+à¹\82à¸\9bรà¸\94à¸\97ราà¸\9aวà¹\88าหà¸\99à¹\89าà¸\94ัà¸\87à¸\81ลà¹\88าวà¸\88ะ'''à¹\84มà¹\88'''à¸\96ูà¸\81ยà¹\89าย à¸\96à¹\89ามีหà¸\99à¹\89าà¸\97ีà¹\88à¹\83à¸\8aà¹\89à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¹\83หมà¹\88อยูà¹\88à¹\81ลà¹\89ว à¹\80วà¹\89à¸\99à¹\81à¸\95à¹\88หà¸\99à¹\89าà¸\99ัà¹\89à¸\99à¹\80à¸\9bà¹\87à¸\99หน้าเปลี่ยนทาง และไม่มีประวัติการแก้ไขในอดีต
 ซึ่งหมายความว่า คุณสามารถเปลี่ยนชื่อหน้ากลับเป็นชื่อเดิมได้หากคุณทำผิดพลาด และคุณไม่สามารถเขียนทับหน้าที่มีอยู่แล้วได้
 
 '''คำเตือน!'''
@@ -2592,9 +2657,9 @@ $1',
 
 # Export
 'export' => 'ส่งออกหน้า',
-'exporttext' => 'คุณสามารถส่งออก (export) ข้อความต้นฉบับและประวัติการแก้ไขของหน้าใดๆ มากกว่าหนึ่งหน้าในคราวเดียว ออกมาในรูปแบบ XML ซึ่งสามารถนำไปใส่เข้าไว้ในเว็บไซต์วิกิแห่งอื่นที่ใช้ซอฟต์แวร์มีเดียวิกิได้ ผ่านทางคำสั่ง[[Special:Import|การนำเข้าหน้า]]
+'exporttext' => 'คุณสามารถส่งออกข้อความและประวัติการแก้ไขของหน้าใด ๆ หรือชุดหน้าในคราวเดียว ออกมาในรูปแบบ XML ซึ่งสามารถนำไปใส่เข้าไว้ในวิกิแห่งอื่นที่ใช้ซอฟต์แวร์มีเดียวิกิได้ ผ่านคำสั่ง[[Special:Import|การนำเข้าหน้า]]
 
-à¸\81ารà¸\88ะสà¹\88à¸\87ออà¸\81หà¸\99à¹\89าà¸\99ัà¹\89à¸\99สามารà¸\96à¸\97ำà¹\84à¸\94à¹\89à¹\82à¸\94ยà¹\83สà¹\88à¸\8aืà¹\88อหัวà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร à¸¥à¸\87à¹\83à¸\99à¸\81ลà¹\88อà¸\87à¸\82à¹\89อà¸\84วามà¸\94à¹\89าà¸\99ลà¹\88าà¸\87 à¸«à¸\99ึà¹\88à¸\87à¸\8aืà¹\88อà¸\95à¹\88อหà¸\99ึà¹\88à¸\87à¸\9aรรà¸\97ัà¸\94 à¸\88าà¸\81à¸\99ัà¹\89à¸\99à¹\80ลือà¸\81วà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\97ัà¹\89à¸\87รุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¹\81ละรุà¹\88à¸\99à¹\80à¸\81à¹\88าà¹\86 à¸\97ัà¹\89à¸\87หมà¸\94à¸\9eรà¹\89อมà¸\81ัà¸\9aà¸\9bระวัà¸\95ิà¸\82อà¸\87หà¸\99à¹\89าà¸\99ัà¹\89à¸\99 à¸«à¸£à¸·à¸­à¸\95à¹\89อà¸\87à¸\81ารà¹\80à¸\9eียà¸\87à¹\81à¸\95à¹\88à¹\80à¸\99ืà¹\89อหารุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\9eรà¹\89อมà¸\81ัà¸\9aรายละà¹\80อียà¸\94à¸\82อà¸\87รุà¹\88à¸\99à¸\99ัà¹\89à¸\99เท่านั้น
+à¸\81ารà¸\88ะสà¹\88à¸\87ออà¸\81หà¸\99à¹\89าà¸\99ัà¹\89à¸\99สามารà¸\96à¸\97ำà¹\84à¸\94à¹\89à¹\82à¸\94ยà¹\83สà¹\88à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร à¸¥à¸\87à¹\83à¸\99à¸\81ลà¹\88อà¸\87à¸\82à¹\89อà¸\84วามà¸\94à¹\89าà¸\99ลà¹\88าà¸\87 à¸«à¸\99ึà¹\88à¸\87à¸\8aืà¹\88อà¸\95à¹\88อหà¸\99ึà¹\88à¸\87à¸\9aรรà¸\97ัà¸\94 à¸\88าà¸\81à¸\99ัà¹\89à¸\99à¹\80ลือà¸\81วà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\97ัà¹\89à¸\87รุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¹\81ละรุà¹\88à¸\99à¹\80à¸\81à¹\88าà¸\97ัà¹\89à¸\87หมà¸\94à¸\9eรà¹\89อมà¸\81ัà¸\9aà¸\9bระวัà¸\95ิà¸\82อà¸\87หà¸\99à¹\89าà¸\99ัà¹\89à¸\99 à¸«à¸£à¸·à¸­à¸\95à¹\89อà¸\87à¸\81ารà¹\80à¸\9eียà¸\87à¹\80à¸\99ืà¹\89อหารุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\9eรà¹\89อมà¸\81ัà¸\9aสารสà¸\99à¹\80à¸\97ศà¸\82อà¸\87à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\84รัà¹\89à¸\87สุà¸\94à¸\97à¹\89ายเท่านั้น
 
 ในกรณีที่ต้องการเฉพาะรุ่นปัจจุบัน คุณสามารถใช้ในรูปแบบของลิงก์ เช่น [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] สำหรับหน้า "[[{{MediaWiki:Mainpage}}]]"',
 'exportall' => 'ส่งออกข้อมูลทุกหน้า',
@@ -2613,7 +2678,7 @@ $1',
 # Namespace 8 related
 'allmessages' => 'ข้อความของระบบ',
 'allmessagesname' => 'ชื่อ',
-'allmessagesdefault' => 'ข้อความตั้งต้น',
+'allmessagesdefault' => 'à¸\82à¹\89อà¸\84วามà¸\95ามà¸\84à¹\88าà¸\95ัà¹\89à¸\87à¸\95à¹\89à¸\99',
 'allmessagescurrent' => 'ข้อความปัจจุบัน',
 'allmessagestext' => 'รายการข้อความของระบบ อยู่ในเนมสเปซมีเดียวิกิ
 กรุณาไปที่ [//www.mediawiki.org/wiki/Localisation มีเดียวิกิ] และ [//translatewiki.new translatewiki.net] ถ้าคุณยังอยากที่จะแปลข้อความของระบบมีเดียวิกิ',
@@ -2799,7 +2864,7 @@ $1',
 'notacceptable' => 'เซิร์ฟเวอร์ของวิกิไม่สามารถให้ข้อมูลในรูปแบบที่ไคลเอนต์สามารถอ่านได้',
 
 # Attribution
-'anonymous' => '{{PLURAL:$1|ผู้ใช้}}นิรนามของ {{SITENAME}}',
+'anonymous' => 'ผู้ใช้นิรนามของ{{SITENAME}}',
 'siteuser' => 'ผู้ใช้ $1 จาก {{SITENAME}}',
 'anonuser' => 'ผู้ใช้นิรนามจาก {{SITENAME}} $1',
 'lastmodifiedatby' => 'แก้ไขล่าสุดเมื่อเวลา $2 $1 โดย $3',
@@ -2817,6 +2882,7 @@ $1',
 'spambot_username' => 'กวาดล้างมีเดียวิกิสแปม',
 'spam_reverting' => 'ย้อนกลับไปรุ่นก่อนหน้าที่ไม่มีลิงก์ไปยังเว็บ $1',
 'spam_blanking' => 'รุ่นการปรับปรุงทุกรุ่นประกอบไปด้วยลิงก์ไปยังเว็บ $1 (ทำหน้าว่าง)',
+'spam_deleting' => 'ทุกรุ่นที่มีลิงก์ไปยัง $1 กำลังลบ',
 
 # Info page
 'pageinfo-title' => 'ข้อมูลสำหรับ "$1"',
@@ -2850,6 +2916,7 @@ $1',
 'pageinfo-redirectsto' => 'เปลี่ยนทางไปยัง',
 'pageinfo-contentpage' => 'นับเป็นหน้าเนื้อหา',
 'pageinfo-contentpage-yes' => 'ใช่',
+'pageinfo-protect-cascading-yes' => 'ใช่',
 'pageinfo-category-info' => 'ข้อมูลหมวดหมู่',
 'pageinfo-category-pages' => 'จำนวนหน้า',
 'pageinfo-category-subcats' => 'จำนวนหมวดหมู่ย่อย',
@@ -2879,7 +2946,7 @@ $1',
 
 # Patrol log
 'patrol-log-page' => 'ปูมการตรวจสอบ',
-'patrol-log-header' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¸\84ือà¸\9aัà¸\99à¸\97ึà¸\81รุ่นการแก้ไขที่กำหนดว่าตรวจสอบแล้ว',
+'patrol-log-header' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¸\84ือà¸\9bูมรุ่นการแก้ไขที่กำหนดว่าตรวจสอบแล้ว',
 'log-show-hide-patrol' => '$1 ปูมการตรวจสอบ',
 
 # Image deletion
@@ -2908,6 +2975,7 @@ $1',
 'file-info-size-pages' => '$1 × $2 พิกเซล, ขนาดไฟล์: $3, ประเภท MIME: $4, $5 {{PLURAL:$5|หน้า|หน้า}}',
 'file-nohires' => 'ไม่มีความละเอียดสูงกว่านี้',
 'svg-long-desc' => 'ไฟล์ SVG, $1 × $2 พิกเซล พอเป็นพิธี, ขนาดไฟล์: $3',
+'svg-long-error' => 'ไฟล์ SVG ไม่ถูกต้อง: $1',
 'show-big-image' => 'ความละเอียดสูงสุด',
 'show-big-image-other' => 'อื่นๆ {{PLURAL:$2|resolution|resolutions}}: $1.',
 'show-big-image-size' => '$1 × $2 พิกเซล',
@@ -2926,7 +2994,7 @@ $1',
 'showhidebots' => '($1 บอต)',
 'noimages' => 'ไม่มีให้ดู',
 'ilsubmit' => 'สืบค้น',
-'bydate' => 'วันที่',
+'bydate' => 'à¸\95ามวัà¸\99à¸\97ีà¹\88',
 'sp-newimages-showfrom' => 'แสดงภาพใหม่เริ่มต้นจาก $2, $1',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
@@ -3501,7 +3569,7 @@ $5
 'specialpages-group-highuse' => 'หน้าที่มีการใช้งานสูง',
 'specialpages-group-pages' => 'รายชื่อหน้า',
 'specialpages-group-pagetools' => 'เครื่องมือเกี่ยวกับหน้าต่าง ๆ',
-'specialpages-group-wiki' => 'à¹\80à¸\84รืà¹\88อà¸\87มือà¹\81ละà¸\82à¹\89อมูลวิà¸\81ิ',
+'specialpages-group-wiki' => 'à¸\82à¹\89อมูลà¹\81ละà¹\80à¸\84รืà¹\88อà¸\87มือ',
 'specialpages-group-redirects' => 'เปลี่ยนทางหน้าพิเศษ',
 'specialpages-group-spam' => 'เครื่องมือเกี่ยวกับสแปม',
 
@@ -3599,7 +3667,6 @@ $5
 'logentry-newusers-create' => 'บัญชีผู้ใช้ $1 ถูกสร้างขึ้น',
 'logentry-newusers-create2' => 'บัญชีผู้ใช้ $3 ถูกสร้างขึ้นโดย $1',
 'logentry-newusers-autocreate' => 'บัญชี $1 ถูกสร้างขึ้นอัตโนมัติ',
-'newuserlog-byemail' => 'รหัสผ่านถูกส่งทางอีเมล',
 'rightsnone' => '(ไม่มี)',
 
 # Feedback
index 07ac792..d07b794 100644 (file)
@@ -1840,7 +1840,7 @@ Goldanylýan protokollar: <code>$1</code>',
 'usermessage-editor' => 'Ulgam habarçysy',
 
 # Watchlist
-'watchlist' => 'Gözegçilik sanawym',
+'watchlist' => 'Gözegçilik sanawy',
 'mywatchlist' => 'Gözegçilik sanawy',
 'watchlistfor2' => '$1 üçin  $2',
 'nowatchlist' => 'Gözegçilik sanawyňyzda hiçhili sahypa ýok.',
@@ -2090,7 +2090,7 @@ $1',
 'blanknamespace' => '(Baş)',
 
 # Contributions
-'contributions' => 'Ulanyjynyň goşantlary',
+'contributions' => '{{GENDER:$1|Ulanyjy}} goşantlary',
 'contributions-title' => '$1 üçin ulanyjy goşantlary',
 'mycontris' => 'Goşantlar',
 'contribsub2' => '$1 ($2)',
@@ -3152,7 +3152,6 @@ Faýlyň adyny "{{ns:file}}:" pristawkasyz giriziň.',
 # New logging system
 'revdelete-restricted' => 'administratorlara goýlan çäklendirmeler',
 'revdelete-unrestricted' => 'administratorlardan aýyrylan çäklendirmeler',
-'newuserlog-byemail' => 'parol e-poçta bilen iberildi',
 'rightsnone' => '(hiç biri)',
 
 # Search suggestions
index 3d46a16..27ded0f 100644 (file)
@@ -369,7 +369,7 @@ $messages = array(
 'viewcount' => 'Namataan na pahinang ito nang {{PLURAL:$1|isang|$1}} beses.',
 'protectedpage' => 'Pahinang nakasanggalang',
 'jumpto' => 'Tumalon sa:',
-'jumptonavigation' => 'paglilibot (nabigasyon)',
+'jumptonavigation' => 'paglilibot',
 'jumptosearch' => 'paghahanap',
 'view-pool-error' => 'Paumanhin, ngunit masyado pong abala ang mga serbidor sa sandaling ito.
 Masyadong maraming tagagamit ay sinusubukang tingnan ang pahinang ito.
@@ -440,9 +440,9 @@ Tingnan ang [[Special:Version|pahina ng bersiyon]].',
 'feed-invalid' => 'Hindi tanggap na uri ng serbisyo ng pagpaparating.',
 'feed-unavailable' => 'Walang serbisyo mula sa sindikasyong pangpaglalathala',
 'site-rss-feed' => 'Kargang RSS ng $1',
-'site-atom-feed' => 'Kargang Atom ng $1',
+'site-atom-feed' => 'Sindikasyong Atom ng $1',
 'page-rss-feed' => 'Kargang RSS ng "$1"',
-'page-atom-feed' => 'Kargang Atom ng "$1"',
+'page-atom-feed' => 'Sindikasyong Atom ng "$1"',
 'feed-atom' => 'Atom',
 'feed-rss' => 'RSS',
 'red-link-title' => '$1 (hindi umiiral ang pahina)',
@@ -567,6 +567,9 @@ Ang tagapangasiwang nagkandado nito ay nag-alok ng ganitong paliwanag: "$3".',
 
 Maaari kang tumuloy sa paggamit ng {{SITENAME}} nang hindi nakikilala (anonimo), o maaaring kang <span class='plainlinks'>[$1 lumagda/tumala muli]</span> bilang kapareho o ibang tagagamit.
 Tandaan na may ilang pahinang maaaring magpatuloy na nagpapakitang parang nakalagda ka pa rin, hanggang sa linisin mo ang iyong baunang pambasa-basa (''browser cache'').",
+'welcomeuser' => 'Mabuhay, $1!',
+'welcomecreation-msg' => 'Nilikha na ang iyong kuwenta.
+Huwag kalimutang baguhin ang iyong [[Special:Preferences|mga kagustuhan sa {{SITENAME}}]].',
 'yourname' => 'Bansag:',
 'yourpassword' => 'Hudyat:',
 'yourpasswordagain' => 'Hudyat mo uli:',
@@ -949,6 +952,7 @@ Umiiral na ito.',
 'defaultmessagetext' => 'Nakatakdang teksto ng mensahe',
 
 # Content models
+'content-model-wikitext' => 'wikiteksto',
 'content-model-text' => 'purong teksto',
 
 # Parser/template warnings
@@ -1312,7 +1316,7 @@ Hindi ito maibabalik sa dating gawi.',
 'prefs-emailconfirm-label' => 'Kumpirmasyon ng e-liham:',
 'prefs-textboxsize' => 'Sukat ng bintana ng pagbabago',
 'youremail' => 'E-liham:',
-'username' => 'Bansag:',
+'username' => '{{GENDER:$1|Bansag}}:',
 'uid' => 'ID ng tagagamit:',
 'prefs-memberingroups' => 'Kasapi ng {{PLURAL:$1|na pangkat|na mga pangkat}}:',
 'prefs-memberingroups-type' => '$1',
@@ -2432,7 +2436,7 @@ $1',
 'undelete-revisionrow' => '$1 $2 ($3) $4 . . $5 $6 $7',
 
 # Namespace form on various pages
-'namespace' => 'Espasyo ng pangalan:',
+'namespace' => 'Ngalan-espasyo:',
 'invert' => 'Baligtarin and pinili',
 'tooltip-invert' => 'Tsekan ang kahong ito upang ikubli ang mga pagbabago sa mga pahina sa loob ng napiling mga puwang ng pangalan (at ang kaugnay na puwang ng pangalan kung may tsek)',
 'namespace_association' => 'Kaugnay na mga puwang na pampangalan',
@@ -2565,8 +2569,8 @@ Tingnan ang [[Special:BlockList|talaan ng mga hinadlangan]] upang suriin ang mga
 'blocklist-nousertalk' => 'hindi mo mababago ang iyong pansariling pahina ng usapan',
 'ipblocklist-empty' => 'Walang laman ang talaan ng pagharang/paghadlang.',
 'ipblocklist-no-results' => 'Nakaharang ang hiniling na IP address o bansag.',
-'blocklink' => 'harangin/hadlangan',
-'unblocklink' => 'tanggalin ang pagharang/paghadlang',
+'blocklink' => 'harangin',
+'unblocklink' => 'tanggalin ang pagharang',
 'change-blocklink' => 'baguhin ang pagharang/paghadlang',
 'contribslink' => 'ambag',
 'emaillink' => 'ipadala ang e-liham',
@@ -2862,7 +2866,7 @@ Sagipin mo ito sa iyong kompyuter at papaitaas na ikarga ito rito.',
 'tooltip-pt-logout' => 'Umalis sa pagkakalagda',
 'tooltip-ca-talk' => 'Usapan tungkol sa nilalaman ng pahinang ito',
 'tooltip-ca-edit' => 'Maaaring baguhin ang pahinang ito. Paki gamit ang buton ng paunang tingin bago itala.',
-'tooltip-ca-addsection' => 'Magsimula ng isang bagong seksyon',
+'tooltip-ca-addsection' => 'Magsimula ng isang bagong seksiyon',
 'tooltip-ca-viewsource' => 'Nakaprotekta ang pahinang ito. Makikita mo lamang ang pinagmulan (source) nito.',
 'tooltip-ca-history' => 'Nakaraang bersyon ng pahinang ito.',
 'tooltip-ca-protect' => 'Iprotekta ang pahinang ito',
@@ -2886,12 +2890,12 @@ Sagipin mo ito sa iyong kompyuter at papaitaas na ikarga ito rito.',
 'tooltip-t-whatlinkshere' => 'Tala ng lahat ng pahina ng mga wiking nakakawing dito',
 'tooltip-t-recentchangeslinked' => 'Kamakailang mga pagbabago na nakakawing mula sa pahinang ito',
 'tooltip-feed-rss' => 'Subo/Kargang RSS para sa pahinang ito',
-'tooltip-feed-atom' => 'Subo/kargang Atom para sa pahinang ito',
+'tooltip-feed-atom' => 'Sindikasyong Atom para sa pahinang ito',
 'tooltip-t-contributions' => 'Tunghayan ang tala ng mga ambag ng tagagamit na ito',
 'tooltip-t-emailuser' => 'Magpadala ng isang e-liham sa tagagamit na ito',
 'tooltip-t-upload' => 'Magkarga ng mga talaksan',
 'tooltip-t-specialpages' => 'Tala ng lahat ng mga natatanging pahina',
-'tooltip-t-print' => 'Nalilimbag na bersyon ng pahinang ito',
+'tooltip-t-print' => 'Bersiyong maililimbag ng pahinang ito',
 'tooltip-t-permalink' => 'Palagiang kawing sa bersyong ito ng pahina',
 'tooltip-ca-nstab-main' => 'Tingnan ang pahina ng nilalaman',
 'tooltip-ca-nstab-user' => 'Tingnan ang pahina ng tagagamit',
@@ -3060,7 +3064,7 @@ Maaaring manganib ang iyong sistema kapag ipinagana mo ito.",
 'widthheight' => '$1 × $2',
 'widthheightpage' => '$1 × $2, $3 {{PLURAL:$3|pahina|mga pahina}}',
 'file-info' => 'sukat ng talaksan: $1, tipo ng MIME: $2',
-'file-info-size' => '$1 × $2 piksel, sukat ng talaksan: $3, tipo ng MIME: $4',
+'file-info-size' => '$1 × $2 piksel, laki ng talaksan: $3, uri ng MIME: $4',
 'file-info-size-pages' => '$1 × $2 mga piksel, sukat ng talaksan: $3, uri ng MIME: $4, $5 {{PLURAL:$5|pahina|mga pahina}}',
 'file-nohires' => 'Walang makuhang mas mataas na resolusyon (kalinawan).',
 'svg-long-desc' => 'Talaksang SVG, nasa mga bilang na $1 × $2 mga piksel, sukat ng talaksan: $3',
@@ -3963,7 +3967,7 @@ Ipinapakita ang mga larawan sa buong kalinawan, tuwirang sinisimulan ang ibang u
 
 # Special:Tags
 'tags' => 'Tanggap na mga tatak ng pagbabago',
-'tag-filter' => '[[Special:Tags|Tatakan]] ang pansala:',
+'tag-filter' => 'Pansala ng [[Special:Tags|tatak]]:',
 'tag-filter-submit' => 'Pansala',
 'tags-title' => 'Mga tatak',
 'tags-intro' => 'Itinatala ng pahinang ito ang mga tatak na maaaring ipantatak ng sopwer sa isang pagbabago, at ang kanilang kahulugan.',
@@ -4041,7 +4045,6 @@ Ipinapakita ang mga larawan sa buong kalinawan, tuwirang sinisimulan ang ibang u
 'logentry-newusers-create' => 'Lumikha si $1 ng isang kuwenta ng tagagamit',
 'logentry-newusers-create2' => 'Lumikha si $1 ng isang kuwenta ng tagagamit na $3',
 'logentry-newusers-autocreate' => 'Kusang nalikha ang akawnt na $1',
-'newuserlog-byemail' => 'Ipinadala ang hudyat sa pamamagitan ng e-liham',
 'rightsnone' => '(wala)',
 
 # Feedback
index e9d5c1b..bb33363 100644 (file)
@@ -784,7 +784,7 @@ $messages = array(
 'emailuser' => 'Номә бә иштирокәкә',
 
 # Watchlist
-'watchlist' => 'ЧÑ\8bмÑ\8b Ð½оғо доә сијоһи',
+'watchlist' => 'Ð\9dоғо доә сијоһи',
 'mywatchlist' => 'Чәшәвәно кардә сијоһи',
 'watchlistfor2' => 'Бо $1 $2',
 'watch' => 'Думотоно егыниеј',
index a9b015f..99682ec 100644 (file)
@@ -123,7 +123,7 @@ $specialPageAliases = array(
        'Listusers'                 => array( 'KullanıcıListesi', 'KullanıcıListele' ),
        'Lockdb'                    => array( 'DBKilitle', 'VeritabanıKilitle' ),
        'Log'                       => array( 'Günlük', 'Günlükler', 'Kayıt', 'Kayıtlar' ),
-       'Lonelypages'               => array( 'YalnızSayfalar' ),
+       'Lonelypages'               => array( 'YalnızSayfalar', 'YetimSayfalar' ),
        'Longpages'                 => array( 'UzunSayfalar' ),
        'MergeHistory'              => array( 'GeçmişBirleştir' ),
        'MIMEsearch'                => array( 'MIMEArama' ),
@@ -776,7 +776,7 @@ Tarayıcınızın önbelleğini temizleyene kadar bazı sayfalar sanki hâlâ ot
 'gotaccount' => "Çoktan kayıt oldunuz mu? '''$1'''.",
 'gotaccountlink' => 'Oturum açın',
 'userlogin-resetlink' => 'Giriş bilgilerinizi mi unuttunuz?',
-'createaccountmail' => 'e-posta ile',
+'createaccountmail' => 'Geçici bir rastgele şifre kullan ve şifreyi aşağıda belirtilen e-posta adresine gönder',
 'createaccountreason' => 'Sebep:',
 'badretype' => 'Girdiğiniz şifreler birbirleriyle uyuşmuyor.',
 'userexists' => 'Girdiğiniz kullanıcı adı zaten kullanımda.
@@ -907,6 +907,7 @@ Geçici şifre: $2',
 'changeemail-oldemail' => 'Mevcut E-posta adresi:',
 'changeemail-newemail' => 'Yeni E-posta adresi:',
 'changeemail-none' => '(yok)',
+'changeemail-password' => '{{SITENAME}} parolanız:',
 'changeemail-submit' => "E-posta'yı değiştir",
 'changeemail-cancel' => 'İptal',
 
@@ -1058,9 +1059,10 @@ Ayrıca buraya katkıda bulunarak, bu katkının kendiniz tarafından yazıldı
 Ayrıca bu ekleyeceğiniz yazıyı sizin yazdığınızı ya da serbest kopyalama izni veren bir kaynaktan kopyaladığınızı bize taahhüt etmektesiniz (ayrıntılar için referans: $1).',
 'longpageerror' => "'''Hata: Girdiğiniz metnin uzunluğu kabul edilebilir en fazla uzunluk olan {{PLURAL:$2|bir kilobayt|$2 kilobayt}}tan fazladır ve {{PLURAL:$1|bir kilobayt|$1 kilobayt}} büyüklüğündedir.'''
 Değişikliğiniz kaydedilemez.",
-'readonlywarning' => "'''DİKKAT: Bakım nedeni ile veritabanı şu anda kilitlidir. Bu sebeple değişiklikleriniz şu anda kaydedilememektedir. Yazdıklarınızı başka bir editöre alıp saklayabilir ve daha sonra tekrar buraya getirip kaydedebilirsiniz'''
+'readonlywarning' => "'''Uyarı: Bakım nedeniyle veritabanı şu anda kilitlenmiştir. Bu yüzden şu anda düzenlemelerinizi kaydetmek mümkün değildir.''' 
+Yaptığınız düzenlemeleri daha sonra kaydetmek isterseniz, yaptığınız düzenlemeleri bir metin dosyasına ya da herhangi bir şeye kopyala yapıştır yaparak saklayınız.
 
-Kilitleyen hizmetli şu açıklamayı eklemiştir: $1",
+Kilitlemeyi yapan yetkili şu açıklamayı eklemiştir: $1",
 'protectedpagewarning' => "'''Uyarı: Bu sayfa koruma altına alınmıştır ve yalnızca hizmetli olanlar tarafından değiştirilebilir.'''
 Son günlük girdisi referans amaçlı aşağıda verilmiştir:",
 'semiprotectedpagewarning' => "'''Not:''' Bu sayfa sadece kayıtlı kullanıcı olanlar tarafından değiştirilebilir.
@@ -2205,7 +2207,7 @@ Ayrıca [[Special:WantedCategories|İstenen kategoriler]]'e bakınız.",
 'linksearch-ok' => 'Ara',
 'linksearch-text' => '"*.wikipedia.org" gibi jokerler kullanılabilir.
 En az bir üst-seviye alan gerekir, örneğin "*.org".<br />
-Desteklenen iletişim kuralları: <code>$1</code> (bunların hiçbirini aramanıza eklemeyin).',
+Desteklenen {{PLURAL:$2|iletişim kuralı|iletişim kuralları}}: <code>$1</code> (herhangi bir iletişim kuralı belirtmezseniz http:// otomatik olarak eklenir).',
 'linksearch-line' => "$1'e $2'den bağlantı verilmiş",
 'linksearch-error' => 'Jokerler sadece ana makine adının başında görünebilir.',
 
@@ -2218,7 +2220,7 @@ Desteklenen iletişim kuralları: <code>$1</code> (bunların hiçbirini aramanı
 # Special:ActiveUsers
 'activeusers' => 'Aktif kullanıcı listesi',
 '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|değişiklik|değişiklik}}',
+'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',
@@ -2250,8 +2252,8 @@ Bireysel haklarla ilgili [[{{MediaWiki:Listgrouprights-helppage}}|daha fazla bil
 'emailuser-title-target' => 'Bu {{GENDER:$1|kullanıcıya}} e-posta gönder',
 'emailuser-title-notarget' => 'Kullanıcı e-posta',
 'emailpage' => 'Kullanıcıya e-posta gönder',
-'emailpagetext' => 'Bu kullanıcıya e-posta mesajı göndermek için aşağıdaki formu kullanabilirsiniz.
-[[Special:Preferences|Kullanıcı tercihlerinizde]] girdiğiniz e-posta adresiniz, e-postanın "From (Kimden)" adresinde görünecektir, bu yüzden alıcı size direk cevap verebilecektir.',
+'emailpagetext' => 'Bu {{GENDER:$1|kullanıcıya}} e-posta iletisi göndermek için aşağıdaki formu kullanabilirsiniz.
+[[Special:Preferences|Kullanıcı tercihlerinizde]] girdiğiniz e-posta adresiniz, e-postanın "From (Kimden)" adresinde görünecektir, bu yüzden alıcı size doğrudan yanıt verebilecektir.',
 'usermailererror' => 'E-posta hizmeti hata verdi:',
 'defemailsubject' => '"$1" kullanıcısından {{SITENAME}} e-postası',
 'usermaildisabled' => 'Kullanıcı e-postası devre dışı',
@@ -2281,7 +2283,7 @@ Bireysel haklarla ilgili [[{{MediaWiki:Listgrouprights-helppage}}|daha fazla bil
 'usermessage-editor' => 'Sistem habercisi',
 
 # Watchlist
-'watchlist' => 'İzleme listem',
+'watchlist' => 'İzleme listesi',
 'mywatchlist' => 'İzleme listesi',
 'watchlistfor2' => '$1 için $2',
 'nowatchlist' => 'İzleme listesinde hiçbir madde bulunmuyor.',
@@ -2289,13 +2291,8 @@ Bireysel haklarla ilgili [[{{MediaWiki:Listgrouprights-helppage}}|daha fazla bil
 'watchnologin' => 'Oturum açık değil.',
 'watchnologintext' => 'İzleme listenizi değiştirebilmek için [[Special:UserLogin|oturum açmalısınız]].',
 'addwatch' => 'İzleme listesine ekle',
-'addedwatchtext' => '"<nowiki>$1</nowiki>" adlı sayfa [[Special:Watchlist|izleme listenize]] kaydedildi.
-
-Gelecekte, bu sayfaya ve ilgili tartışma sayfasına yapılacak değişiklikler burada listelenecektir.
-
-Kolayca seçilebilmeleri için de [[Special:RecentChanges|son değişiklikler listesi]] başlığı altında koyu harflerle listeleneceklerdir.
-
-Sayfayı izleme listenizden çıkarmak istediğinizde "sayfayı izlemeyi durdur" bağlantısına tıklayabilirsiniz.',
+'addedwatchtext' => '"[[:$1]]" sayfası [[Special:Watchlist|izleme listenize]] eklenmiştir.
+Bundan sonra, bu sayfaya ve ilgili tartışma sayfasına yapılacak değişiklikler burada listelenecek.',
 'removewatch' => 'İzleme listesinden kaldır',
 'removedwatchtext' => '"[[:$1]]" sayfası [[Special:Watchlist|izleme listenizden]] silinmiştir.',
 'watch' => 'İzle',
@@ -2324,30 +2321,41 @@ Sayfayı izleme listenizden çıkarmak istediğinizde "sayfayı izlemeyi durdur"
 'enotif_mailer' => '{{SITENAME}} Bildirim Postası',
 'enotif_reset' => 'Tüm sayfaları ziyaret edilmiş olarak işaretle',
 'enotif_impersonal_salutation' => '{{SITENAME}} kullanıcı',
+'enotif_subject_deleted' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|silindi}}.',
+'enotif_subject_created' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|açıldı}}.',
+'enotif_subject_moved' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|taşındı}}.',
+'enotif_subject_restored' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|geri getirildi}}.',
+'enotif_subject_changed' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|değiştirildi}}.',
+'enotif_body_intro_deleted' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|silindi}}, bakınız: $3.',
+'enotif_body_intro_created' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|açıldı}}, mevcut revizyon için bakınız: $3.',
+'enotif_body_intro_moved' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|taşındı}}, mevcut revizyon için bakınız: $3.',
+'enotif_body_intro_restored' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|geri getirildi}}, mevcut revizyon için bakınız: $3.',
+'enotif_body_intro_changed' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|değiştirildi}}, mevcut revizyon için bakınız: $3.',
 'enotif_lastvisited' => "Son ziyaretinizden bu yana olan tüm değişiklikleri görmek için $1'e bakın.",
 'enotif_lastdiff' => 'Bu değişikliği görmek için, $1 sayfasına bakınız.',
 'enotif_anon_editor' => 'anonim kullanıcı $1',
 'enotif_body' => 'Sayın $WATCHINGUSERNAME,
 
-{{SITENAME}} bünyesindeki $PAGETITLE başlıklı sayfa $PAGEEDITDATE tarihinde $PAGEEDITOR tarafından $CHANGEDORCREATED. Sayfanın son haline $PAGETITLE_URL adresinden ulaşabilirsiniz.
+$PAGEINTRO $NEWPAGE
 
-$NEWPAGE
+Editörün girdiği özet: $PAGESUMMARY $PAGEMINOREDIT
 
-Değişikliği yapan kullanıcının açıklaması: $PAGESUMMARY $PAGEMINOREDIT
+Editörün iletişim bilgileri:
+e-posta: $PAGEEDITOR_EMAIL
+viki: $PAGEEDITOR_WIKI
 
-Sayfayı değiştiren kullanıcıya erişim bilgileri:
-E-posta: $PAGEEDITOR_EMAIL
-Viki: $PAGEEDITOR_WIKI
+Bahsi geçen sayfayı ziyaret edinceye kadar sayfayla ilgili başka bildirim gönderilmeyecektir. Ayrıca izleme listenizdeki tüm sayfaların bildirim durumlarını sıfırlayabilirsiniz.
 
-Bahsi geçen sayfayı ziyaret edinceye kadar sayfayla ilgili başka değişiklik bildirimi gönderilmeyecektir. İzleme listenizdeki tüm sayfalar bildirim durumlarını sıfırlayabilirsiniz.
-
-              {{SITENAME}} sitesinin uyarı sistemi.
+{{SITENAME}} bildirim sistemi
 
 --
-İzleme listesi ayarlarınızı değiştirmek için:
+E-posta bildirim ayarlarınızı değiştirmek için aşağıdaki sayfayı ziyaret ediniz:
+{{canonicalurl:{{#special:Preferences}}}}
+
+İzleme listesi ayarlarınızı değiştirmek için aşağıdaki sayfayı ziyaret ediniz:
 {{canonicalurl:{{#special:EditWatchlist}}}}
 
-Sayfayı izleme listenizden silmek için:
+Sayfayı izleme listenizden silmek için aşağıdaki sayfayı ziyaret ediniz:
 $UNWATCHURL
 
 Geri bildirim ve daha fazla yardım için:
@@ -2393,6 +2401,7 @@ dikkatle devam edin.',
 'rollback' => 'değişiklikleri geri al',
 'rollback_short' => 'geri al',
 'rollbacklink' => 'geridöndür',
+'rollbacklinkcount' => '$1 {{PLURAL:$1|değişikliği|değişikliği}} geri döndür',
 'rollbackfailed' => 'geri alma işlemi başarısız',
 'cantrollback' => 'Sayfaya son katkıda bulunan kullanıcı, sayfaya katkıda bulunmuş tek kişi olduğu için, değişiklikler geri alınamıyor.',
 'alreadyrolled' => '[[User:$2|$2]] ([[User talk:$2|Talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tarafından [[:$1]] sayfasında yapılmış son değişiklik geriye alınamıyor;
@@ -2440,8 +2449,8 @@ Lütfen "geri" gidin ve geldiğiniz sayfayı yeniden yükleyin, sonra tekrar den
 Bu sayfanın koruma seviyesini değiştirebilirsiniz; ancak bu kademeli korumaya etki etmeyecektir.',
 'protect-default' => 'Tüm kullanıcılara izin ver',
 'protect-fallback' => '"$1" izni gerektir',
-'protect-level-autoconfirmed' => 'Yeni ve kayıtlı olmayan kullanıcıları engelle',
-'protect-level-sysop' => 'sadece hizmetliler',
+'protect-level-autoconfirmed' => 'Yalnızca otomatik onaylanmış kullanıcılara izin verilir',
+'protect-level-sysop' => 'Yalnızca hizmetlilere izin verilir',
 'protect-summary-cascade' => 'kademeli',
 'protect-expiring' => 'bitiş tarihi $1 (UTC)',
 'protect-expiring-local' => '$1 tarihinde bitiyor',
@@ -2920,6 +2929,8 @@ Geçici dosya kayıp.',
 # JavaScriptTest
 'javascripttest' => 'JavaScript denemesi',
 'javascripttest-title' => '$1 testleri çalışıyor',
+'javascripttest-qunit-intro' => 'mediawiki.org üzerinden [$1 deneme belgelerine] bakınız.',
+'javascripttest-qunit-heading' => 'MediaWiki JavaScript QUnit deneme paketi',
 
 # Tooltip help for the actions
 'tooltip-pt-userpage' => 'Kullanıcı sayfanız',
@@ -3059,6 +3070,8 @@ Geçici dosya kayıp.',
 'pageinfo-protect-cascading-from' => 'Korumalar üzerinden geçiş',
 'pageinfo-category-info' => 'Kategori bilgileri',
 'pageinfo-category-pages' => 'Sayfa sayısı',
+'pageinfo-category-subcats' => 'Alt kategori sayısı',
+'pageinfo-category-files' => 'Dosya sayısı',
 
 # Skin names
 'skinname-standard' => 'Klasik',
@@ -3109,6 +3122,7 @@ Bunu çalıştırmak, sisteminizi tehlikeye atabilir.",
 'file-info-size-pages' => '$1 × $2 piksel, dosya boyutu: $3, MIME tipi: $4, $5 {{PLURAL:$5|sayfa|sayfa}}',
 'file-nohires' => 'Daha yüksek çözünürlük yok.',
 'svg-long-desc' => 'SVG dosyası, sözde $1 × $2 piksel, dosya boyutu: $3',
+'svg-long-desc-animated' => 'Hareketli SVG dosyası, sözde $1 × $2 piksel, dosya boyutu: $3',
 'svg-long-error' => 'Geçersiz SVG dosyası: $1',
 'show-big-image' => 'Tam çözünürlük',
 'show-big-image-preview' => 'Ön izleme boyutu: $1.',
@@ -3141,6 +3155,8 @@ Bunu çalıştırmak, sisteminizi tehlikeye atabilir.",
 'minutes' => '{{PLURAL:$1|$1 dakika|$1 dakika}}',
 'hours' => '{{PLURAL:$1|$1 saat|$1 saat}}',
 'days' => '{{PLURAL:$1|$1 gün|$1 gün}}',
+'months' => '{{PLURAL:$1|$1 ay|$1 ay}}',
+'years' => '{{PLURAL:$1|$1 yıl|$1 yıl}}',
 'ago' => '$1 önce',
 'just-now' => 'Hemen şimdi',
 
@@ -3297,6 +3313,7 @@ Diğerleri varsayılan olarak gizlenecektir.
 'exif-worldregiondest' => 'Gösterilen bölge',
 'exif-countrydest' => 'Gösterilen ülke',
 'exif-countrycodedest' => 'Gösterilen ülke kodu',
+'exif-provinceorstatedest' => 'Gösterilen il ya da devlet/eyalet',
 'exif-citydest' => 'Gösterilen Şehir',
 'exif-objectname' => 'Kısa başlık',
 'exif-specialinstructions' => 'Özel talimatlar',
@@ -3332,6 +3349,7 @@ Diğerleri varsayılan olarak gizlenecektir.
 'exif-giffilecomment' => 'GIF dosyası yorumu',
 'exif-intellectualgenre' => 'Öğe türü',
 'exif-subjectnewscode' => 'Konu kodu',
+'exif-scenecode' => 'IPTC sahne kodu',
 'exif-event' => 'Adı geçen olay',
 'exif-organisationinimage' => 'Organizasyon gösterilmiştir',
 'exif-personinimage' => 'Adı geçen kişi',
@@ -3805,7 +3823,7 @@ Resimler tam çözünürlükte görüntülenir, diğer dosya tipleri ilgili prog
 'specialpages-group-highuse' => 'Çok kullanılan sayfalar',
 'specialpages-group-pages' => 'Sayfaların listeleri',
 'specialpages-group-pagetools' => 'Sayfa araçları',
-'specialpages-group-wiki' => 'Viki bilgiler ve araçlar',
+'specialpages-group-wiki' => 'Veri ve araçlar',
 'specialpages-group-redirects' => 'Yönlendirmeli özel sayfalar',
 'specialpages-group-spam' => 'Spam araçları',
 
@@ -3896,7 +3914,6 @@ Resimler tam çözünürlükte görüntülenir, diğer dosya tipleri ilgili prog
 'logentry-newusers-create' => 'Kullanıcı hesabı $1 oluşturdu',
 'logentry-newusers-create2' => '$1 kullanıcı hesabı oluşturdu $3',
 'logentry-newusers-autocreate' => '$1 hesabı otomatik olarak oluşturuldu',
-'newuserlog-byemail' => 'e-posta yoluyla şifre gönderilmiştir',
 'rightsnone' => '(hiçbiri)',
 
 # Feedback
index 3e9b3aa..6208505 100644 (file)
@@ -464,6 +464,9 @@ Legend: '''({{int:cur}})''' = difference with latest revision, '''({{int:last}})
 'group-user' => 'Hadome',
 'group-all' => '(kulle)',
 
+# Special:Log/newusers
+'newuserlogpage' => 'User creation log',
+
 # Associated actions - in the sentence "You do not have permission to X"
 'action-edit' => 'Mşaḥlaf iFaṭaṭe',
 
@@ -585,9 +588,6 @@ The description on its [$2 file description page] there is shown below.',
 # Special:ListUsers
 'listusers-submit' => 'Maḥway',
 
-# Special:Log/newusers
-'newuserlogpage' => 'User creation log',
-
 # Special:ListGroupRights
 'listgrouprights-group' => 'Gudo',
 'listgrouprights-rights' => 'Ḥaqat',
index 56aab08..42d9c49 100644 (file)
@@ -564,6 +564,9 @@ Adiresi ya wena ya e-mail yitunberile loko van'wana va bula na wena.",
 'right-move-subpages' => "yisa matluka lawa na matluka-ntsongo ya wona, kun'wana",
 'right-delete' => 'Sula matluka lawa',
 
+# Special:Log/newusers
+'newuserlogpage' => 'Nghula ya nxaxamelo wa ku tumbuluxiwa ka vatirhisi',
+
 # Associated actions - in the sentence "You do not have permission to X"
 'action-read' => 'hlaya tluka leri',
 'action-edit' => 'Lulamisa tluka leri',
@@ -690,9 +693,6 @@ Nhlamuselo ya yona leyi nge ndzeni ka [$2 tluka ro hlamusela] hi yona leyi kombi
 'linksearch-ok' => 'Lava',
 'linksearch-line' => '$1 yi khwekerisiwe kusuka eka $2',
 
-# Special:Log/newusers
-'newuserlogpage' => 'Nghula ya nxaxamelo wa ku tumbuluxiwa ka vatirhisi',
-
 # Special:ListGroupRights
 'listgrouprights-members' => '(nxaxamelo wa valandzeri)',
 
index b7087c0..121decf 100644 (file)
@@ -2531,7 +2531,6 @@ $1',
 'logentry-newusers-create' => '$1 хисап язмасы төзеде',
 'logentry-newusers-create2' => '$1 $3 кулланучы хисап язмасын төзеде',
 'logentry-newusers-autocreate' => 'Автоматик рәвештә $1 хисап язмасы төзелде.',
-'newuserlog-byemail' => 'серсүз электрон почта аша җибәрелде',
 'rightsnone' => '(юк)',
 
 # Feedback
index f09b370..167a008 100644 (file)
@@ -2186,7 +2186,6 @@ Yulnıñ berençe sıltaması quyma öçen tıyılğan räsemgä sıltama bulır
 
 # New logging system
 'revdelete-restricted' => 'çikläwlär idaräçelärgä dä qullanıla',
-'newuserlog-byemail' => 'sersüz elektron poçta aşa cibärelde',
 'rightsnone' => '(yuq)',
 
 );
index a8a7959..8dfc21b 100644 (file)
  * @author לערי ריינהארט
  */
 
+$fallback = 'ru';
+$fallback8bitEncoding = "windows-1251";
+
 $namespaceNames = array(
        NS_MEDIA            => 'Медиа',
        NS_SPECIAL          => 'Тускай',
        NS_TALK             => 'Чугаа',
        NS_USER             => 'Aжыглакчы',
-       NS_USER_TALK        => 'AжÑ\8bглакÑ\87Ñ\8b\87Ñ\83гаазÑ\83',
-       NS_PROJECT_TALK     => '$1_Ñ\87Ñ\83гаазÑ\83',
+       NS_USER_TALK        => 'AжÑ\8bглакÑ\87Ñ\8b\87Ñ\83гаазÑ\8b',
+       NS_PROJECT_TALK     => '$1_Ñ\87Ñ\83гаазÑ\8b',
        NS_FILE             => 'Файл',
-       NS_FILE_TALK        => 'Файл_Ñ\87Ñ\83гаазÑ\83',
+       NS_FILE_TALK        => 'Файл_Ñ\87Ñ\83гаазÑ\8b',
        NS_MEDIAWIKI        => 'МедиаВики',
-       NS_MEDIAWIKI_TALK   => 'Ð\9cедиаÐ\92ики_Ñ\87Ñ\83гаазÑ\83',
-       NS_TEMPLATE         => 'Ð¥Ñ\8dÑ\8d',
-       NS_TEMPLATE_TALK    => 'Ð¥Ñ\8dÑ\8d\87Ñ\83гаазÑ\83',
+       NS_MEDIAWIKI_TALK   => 'Ð\9cедиаÐ\92ики_Ñ\87Ñ\83гаазÑ\8b',
+       NS_TEMPLATE         => 'Ð\9cайÑ\8bк',
+       NS_TEMPLATE_TALK    => 'Ð\9cайÑ\8bк_Ñ\87Ñ\83гаазÑ\8b',
        NS_HELP             => 'Дуза',
-       NS_HELP_TALK        => 'Ð\94Ñ\83за_Ñ\87Ñ\83гаазÑ\83',
-       NS_CATEGORY         => 'Ð\91өлүк',
-       NS_CATEGORY_TALK    => 'Ð\91өлүк_Ñ\87Ñ\83гаазÑ\83',
+       NS_HELP_TALK        => 'Ð\94Ñ\83за_Ñ\87Ñ\83гаазÑ\8b',
+       NS_CATEGORY         => 'Ð\9aаÑ\82егоÑ\80иÑ\8f',
+       NS_CATEGORY_TALK    => 'Ð\9aаÑ\82егоÑ\80иÑ\8f\87Ñ\83гаазÑ\8b',
 );
 
-$namespaceAliases = array(
-       'Aжыглакчы_чугаа' => NS_USER_TALK,
-       '$1_чугаа'        => NS_PROJECT_TALK,
-       'Чурук'           => NS_FILE,
-       'Чурук_чугаа'     => NS_FILE_TALK,
-       'МедиаВики_чугаа' => NS_MEDIAWIKI_TALK,
-       'Хээ_чугаа'       => NS_TEMPLATE_TALK,
-       'Дуза_чугаа'      => NS_HELP_TALK,
-       'Бөлүк_чугаа'     => NS_CATEGORY_TALK,
+
+$magicWords = array(
+       'redirect'                  => array( '0', '#ШИГЛЕДИР', '#REDIRECT' ),
+       'notoc'                     => array( '0', '__ДОПЧУЗУЧОК__', '__NOTOC__' ),
+       'toc'                       => array( '0', '__ДОПЧУЗУ__', '__TOC__' ),
+       'currentmonth'              => array( '1', 'АМГЫАЙ', 'АМГЫАЙ2', 'CURRENTMONTH', 'CURRENTMONTH2' ),
+       'currentmonth1'             => array( '1', 'АМГЫАЙ1', 'CURRENTMONTH1' ),
+       'currentmonthname'          => array( '1', 'АМГЫАЙНЫҢАДЫ', 'CURRENTMONTHNAME' ),
+       'currentday'                => array( '1', 'АМГЫХҮН', 'CURRENTDAY' ),
+       'currentday2'               => array( '1', 'АМГЫХҮН2', 'CURRENTDAY2' ),
+       'currentdayname'            => array( '1', 'АМГЫХҮННҮҢАДЫ', 'CURRENTDAYNAME' ),
+       'currentyear'               => array( '1', 'АМГЫЧЫЛ', 'CURRENTYEAR' ),
+       'currenttime'               => array( '1', 'АМГЫҮЕ', 'CURRENTTIME' ),
+       'currenthour'               => array( '1', 'АМГЫШАК', 'CURRENTHOUR' ),
+       'numberofpages'             => array( '1', 'АРЫННАРНЫҢСАНЫ', 'NUMBEROFPAGES' ),
+       'numberofarticles'          => array( '1', 'ЧҮҮЛДЕРНИҢСАНЫ', 'NUMBEROFARTICLES' ),
+       'numberoffiles'             => array( '1', 'ФАЙЛДАРНЫҢСАНЫ', 'NUMBEROFFILES' ),
+       'numberofusers'             => array( '1', 'АЖЫГЛАКЧЫЛАРНЫҢСАНЫ', 'NUMBEROFUSERS' ),
+       'numberofedits'             => array( '1', 'ӨСКЕРЛИИШКИННЕРНИҢСАНЫ', 'NUMBEROFEDITS' ),
+       'pagename'                  => array( '1', 'АРЫННЫҢАДЫ', 'PAGENAME' ),
+       'namespace'                 => array( '1', 'АТТАРДЕЛГЕМИ', 'NAMESPACE' ),
+       'namespacee'                => array( '1', 'АТТАРДЕЛГЕМИ2', 'NAMESPACEE' ),
+       'namespacenumber'           => array( '1', 'АТТАРДЕЛГЕМИНИҢСАНЫ', 'NAMESPACENUMBER' ),
+       'talkspace'                 => array( '1', 'ЧУГААДЕЛГЕМИ', 'TALKSPACE' ),
+       'talkspacee'                => array( '1', 'ЧУГААДЕЛГЕМИ2', 'TALKSPACEE' ),
+       'img_right'                 => array( '1', 'оң', 'right' ),
+       'img_left'                  => array( '1', 'солагай', 'left' ),
+       'img_center'                => array( '1', 'төп', 'center', 'centre' ),
+       'sitename'                  => array( '1', 'САЙТТЫҢАДЫ', 'SITENAME' ),
+       'ns'                        => array( '0', 'АД:', 'NS:' ),
+       'nse'                       => array( '0', 'АД2:', 'NSE:' ),
+       'currentweek'               => array( '1', 'АМГЫЧЕДИХОНУК', 'CURRENTWEEK' ),
+       'currentdow'                => array( '1', 'АМГЫЧЕДИХОНУКТУҢХҮНҮ', 'CURRENTDOW' ),
+       'raw'                       => array( '0', 'ЧИГ:', 'RAW:' ),
+       'language'                  => array( '0', '#ДЫЛ:', '#LANGUAGE:' ),
+       'special'                   => array( '0', 'тускай', 'special' ),
+       'tag'                       => array( '0', 'демдек', 'tag' ),
+       'pagesincategory_all'       => array( '0', 'шупту', 'all' ),
+       'pagesincategory_pages'     => array( '0', 'арыннар', 'pages' ),
+       'pagesincategory_files'     => array( '0', 'файлдар', 'files' ),
 );
 
 $bookstoreList = array(
@@ -55,8 +89,6 @@ $bookstoreList = array(
        'Barnes & Noble' => 'http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1'
 );
 
-$fallback8bitEncoding = "windows-1251";
-
 $messages = array(
 # User preference toggles
 'tog-underline' => 'Холбааны шыяры:',
@@ -448,6 +480,15 @@ $messages = array(
 
 The password for this new account can be changed on the ''[[Special:ChangePassword|change password]]'' page upon logging in.",
 'newarticle' => '(Чаа)',
+'newarticletext' => 'Амдыызында чаяатынмаан арынче шөлүглеп шилчий бердиңер.
+Ону чаяарда адакы көзенекке сөзүглелден таналап киириңер ([[{{MediaWiki:Helppage}}|тайылбыр арынын]] тода көрүңер).. 
+Маңаа алдаг аайы-биле шилчий берген болзуңарза, браузериңерниң "дедир"  деп таназын базыптыңар.',
+'noarticletext' => "Амдыызында ук арында сөзүглел чок.
+Ол дилеп турар [[Special:Search/{{PAGENAME}}|арыныңар дугайында өске чүүлдерге бижээнин тып аап]] болур силер,
+<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} журналдар аразынга айытканын көрүп болур силер] азы '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} шак ындыг аттыг арын чаяап болур силер]'''</span>.,",
+'noarticletext-nopermission' => 'Амдыызында ук арында сөзүглел чок.
+Ол дилеп турар [[Special:Search/{{PAGENAME}}|арыныңар дугайында өске чүүлдерге бижээнин тып аап]] болур силер, азы
+<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} журналдар аразынга айытканын көрүп болур силер]. Шак ындыг ук арын чаяар чөшпээрелиңер чок.',
 'userpage-userdoesnotexist' => '«<nowiki>$1</nowiki>» деп ажыглакчы is not registered.
 Please check if you want to create/edit this page.',
 'userpage-userdoesnotexist-view' => '«$1» деп ажыглакчы not registered.',
@@ -464,6 +505,10 @@ Please check if you want to create/edit this page.',
 'template-semiprotected' => '(четпес камгалаан)',
 'hiddencategories' => 'Бо арын {{PLURAL:$1|$1 чажыт бөлүкке}} хамааржыр:',
 'permissionserrorstext-withaction' => "Мында «'''$2'''» силерниң эргеңер чок, {{PLURAL:$1|чылдагааны|чылдагааннары}}:",
+'recreate-moveddeleted-warn' => "'''Кичээңейлиг. Ооң мурнунда казыттынган арынны катап тургузар деп тур Силер.'''
+
+Ол арынны катап тургузары шынап-ла чугула бе, боданыңар.
+Бо адаанда ол арынның казыышкыннар болгаш өскээр адалгалар журналдарын көргүскен.",
 'moveddeleted-notice' => 'Бо арын ап каавыткан.
 Адаанда ап каавыткан биле өскээр адаан бижиктер шынзылгазын көргүскен.',
 
@@ -490,6 +535,8 @@ Please check if you want to create/edit this page.',
 'last' => 'эрткен',
 'page_first' => 'бирги',
 'page_last' => 'сөөлгү',
+'histlegend' => "Версиялар шилиири: деңнээр дээн арыныңар версияларын имнеңеш, бээр базыптыңар '''{{int:compare-submit}}'''.<br />
+Тайылбыр: '''({{int:cur}})''' — амгы версиядан ылгавыр; '''({{int:last}})''' — эрткен версиядан ылгавыр;  '''{{int:minoreditletter}}''' — биче өскерилгелер.",
 'history-fieldset-title' => 'Каралаары төөгүзү',
 'history-show-deleted' => 'Чүгле казыттынган',
 'histfirst' => 'Эң эрте',
@@ -914,7 +961,7 @@ It must not be more than $1 {{PLURAL:$1|character|characters}} long.',
 'emailsend' => 'Чорудары',
 
 # Watchlist
-'watchlist' => 'Ð\9cÑ\8dÑ\8dÒ£ Ñ\85айгааÑ\80ал Ð´Ð°Ò£Ð·Ñ\8bм',
+'watchlist' => 'ХайгааÑ\80ал Ð´Ð°Ò£Ð·Ñ\8bзÑ\8b',
 'mywatchlist' => 'Хайгаарал даңзы',
 'watchlistfor2' => '$1, силерге $2',
 'nowatchlist' => 'Силерниң хайгаарал даңзыңар куруг.',
@@ -1310,6 +1357,16 @@ It must not be more than $1 {{PLURAL:$1|character|characters}} long.',
 # Special:BlankPage
 'blankpage' => 'Куруг арын',
 
+# External image whitelist
+'external_image_whitelist' => ' #Бо одуругну ол-ла хевээр арттырыңар<pre>
+#Турум илередиглер (регулярные выражения) фрагментилерин маңаа салыңар (// аразынга турар кезээн)
+#Даштыкы чурумалдар URL-биле олар холбаашкан болур.
+#Дужа бергеннери чурумалдар кылдыр көстүп келир, артканнары чурумалдарже шөлүг кылдыр көстүр.
+# "#" деп демдектен эгелээн одуругларны саналдар кылдыр билдинер.
+#Одуруглар регистрге кунук эвес (билинмес)
+
+#Турум илередиглер фрагментилерин бо одуругнуң кырынга салыңар. А бо одуругну олчаан хевээр арттырыңар</pre>',
+
 # Special:Tags
 'tag-filter' => '[[Special:Tags|демдек]] шүүрү:',
 'tag-filter-submit' => 'Шүүрү',
index 523311d..152b92d 100644 (file)
@@ -9,6 +9,7 @@
  *
  * @author Alfredie
  * @author Arlin
+ * @author Calak
  * @author Kaganer
  * @author Reedy
  * @author Sahran
@@ -173,6 +174,7 @@ $messages = array(
 'newwindow' => '(يېڭى كۆزنەكتە ئاچ)',
 'cancel' => 'ۋاز كەچ',
 'moredotdotdot' => 'تەپسىلىي…',
+'morenotlisted' => 'تەپسىلاتى كۆرسىتىلمىگەنلىرى…',
 'mypage' => 'بەتىم',
 'mytalk' => 'مۇنازىرە بېتىم',
 'anontalk' => 'بۇ IP نىڭ مۇنازىرە بېتى',
@@ -499,7 +501,7 @@ $2',
 'gotaccount' => "ھېساباتىم بار؟ '''$1'''.",
 'gotaccountlink' => 'تىزىمغا كىر',
 'userlogin-resetlink' => 'تىزىمغا كىرىش تەپسىلاتىنى ئۇنۇتتىڭىز؟',
-'createaccountmail' => 'ئېلخەتتە',
+'createaccountmail' => 'ۋاقىتلىق ئىختىيارىي بىر ئېمنى ئىشلىتىدۇ ھەمدە تۆۋەندىكى بەلگىلەنگەن تورخەت ئادرېسىغا ئەۋەتىدۇ',
 'createaccountreason' => 'سەۋەب:',
 'badretype' => 'سىز كىرگۈزگەن ئىم ماس كەلمىدى.',
 'userexists' => 'كىرگۈزگەن ئىشلەتكۈچى ئاتى ئىشلىتىلىۋاتىدۇ.
@@ -587,6 +589,7 @@ cookies نى قوزغاتقانلىقىڭىزنى جەزملەڭ، بۇ بەتن
 # E-mail sending
 'php-mail-error-unknown' => 'PHP نىڭ mail() فونكسىيەسىدىكى يوچۇن خاتالىق',
 'user-mail-no-addy' => 'ئېلخەت ئادرېسسىز خەت يوللاشنى سىنىدى.',
+'user-mail-no-body' => 'بوش ياكى مەزمۇنى قىسقا مۇۋاپىق بولمىغان تورخەت ئەۋەتىشنى سىنىدى.',
 
 # Change password dialog
 'resetpass' => 'ئىم ئۆزگەرت',
@@ -825,7 +828,7 @@ $2
 'readonlywarning' => "'''ئاگاھلاندۇرۇش: ساندان قۇلۇپلىنىپ ئاسرىلىۋاتىدۇ، شۇڭلاشقا ئۆزگەرتىشىڭىزنى ساقلىيالمايسىز.'''
 سىز بۇ تېكستنى كۆچۈرۈپ تېكست ھۆججىتىگە ساقلاپ، سەل تۇرۇپ ئاندىن ئۆزگەرتىڭ.
 
-باشقۇرغۇچىنىڭ چۈشەندۈرۈشى تۆۋەندىكىچە: $1",
³Ø§Ù\86داÙ\86Ù\86Ù\89 Ù\82Û\87Ù\84Û\87Ù¾Ù\84Ù\89غاÙ\86 Ø¨Ø§Ø´Ù\82Û\87رغÛ\87Ú\86Ù\89Ù\86Ù\89Ú­ Ú\86Û\88Ø´Û\95Ù\86دÛ\88رÛ\88Ø´Ù\89 ØªÛ\86Û\8bÛ\95Ù\86دÙ\89Ù\83Ù\89Ú\86Û\95: $1",
 'protectedpagewarning' => "'''ئاگاھلاندۇرۇش:''' بۇ بەت قۇلۇپلانغان شۇڭلاشقا باشقۇرغۇچى ھوقۇقىغا ئىگە ئىشلەتكۈچىلا ئۇنى ئۆزگەرتەلەيدۇ. پايدىلىنىش ئۈچۈن تۆۋەندە يېقىنقى خاتىرە تەمىنلەندى:",
 'semiprotectedpagewarning' => "'''دىققەت:''' بۇ بەت قۇلۇپلانغان شۇڭلاشقا خەتلەتكەن ئىشلەتكۈچىلا ئۇنى تەھرىرلىيەلەيدۇ.
  پايدىلىنىش ئۈچۈن تۆۋەندە يېقىنقى خاتىرە تەمىنلەندى:",
@@ -2049,7 +2052,7 @@ URL نىڭ توغرىلىقى ۋە تور بېكەتنى زىيارەت قىلى
 # Special:ActiveUsers
 'activeusers' => 'ئاكتىپ ئەزالار تىزىملىكى',
 'activeusers-intro' => 'بۇ يېقىنقى $1 {{PLURAL:$1| كۈن|كۈن}}دىكى مەشغۇلات قىلغان ئىشلەتكۈچىلەر تىزىملىكى.',
-'activeusers-count' => 'يېقىنقى {{PLURAL:$3|كۈن|$3 كۈن}}دىكى $1 {{PLURAL:$1|تەھرىر|تەھرىر}}  قېتىم سانى',
+'activeusers-count' => 'يېقىنقى {{PLURAL:$3|كۈن|$3 كۈن}}دىكى {{PLURAL:$1|مەشغۇلات}} قېتىم سانى $1',
 'activeusers-from' => 'باشلانغان ئىشلەتكۈچىنى كۆرسەت:',
 'activeusers-hidebots' => 'ماشىنا ئادەمنى يوشۇر',
 'activeusers-hidesysops' => 'باشقۇرغۇچىنى يوشۇر',
@@ -2115,7 +2118,7 @@ URL نىڭ توغرىلىقى ۋە تور بېكەتنى زىيارەت قىلى
 'usermessage-template' => 'MediaWiki:UserMessage',
 
 # Watchlist
-'watchlist' => 'كۆزەت تىزىملىكىم',
+'watchlist' => 'كۆزەت تىزىملىكى',
 'mywatchlist' => 'كۆزىتىش تىزىملىكى',
 'watchlistfor2' => '$1 $2 ئۈچۈن',
 'nowatchlist' => 'كۆزەت تىزىملىكىڭىز بوش.',
@@ -2265,6 +2268,8 @@ $2 نىڭ ئاخىرقى تۈزىتىلگەن نەشرىگە ئۆزگەرتىل
 'prot_1movedto2' => '[[$1]] دىن [[$2]]غا يۆتكەلدى',
 'protect-badnamespace-title' => 'قوغداتقل بولمايدىغان ئىسىم بوشلۇق',
 'protect-badnamespace-text' => 'بۇ ئىسىم بوشلۇقىدىكى بەتنى قوغدىغىلى بولمايدۇ.',
+'protect-norestrictiontypes-text' => 'بۇ بەتنى ساقلىيالمايدۇ سەۋەبى ئىشلەتكىلى بولىدىغان قوغداش تىپى يوق.',
+'protect-norestrictiontypes-title' => 'قوغدىغىلى بولمايدىغان بەت',
 'protect-legend' => 'قوغداش جەزملە',
 'protectcomment' => 'سەۋەب:',
 'protectexpiry' => 'قەرەلى:',
@@ -2281,9 +2286,9 @@ $2 نىڭ ئاخىرقى تۈزىتىلگەن نەشرىگە ئۆزگەرتىل
 'protect-cascadeon' => 'تۆۋەندىكى {{PLURAL:$1|بىر|بىر قانچە}} بەت مەزكۇر بەتنى ئۆز ئىچىگە ئېلىش بىلەن بىللە زەنجىرسىمان قوغداش قوزغىتىلغان.
  شۇڭلاشقا بۇ بەتمۇ قوغدالغان. بۇ بەتنىڭ قوغداش دەرىجىسىنى ئۆزگەرتەلەيسىز، ئەمما زەنجىرسىمان قوغداشقا تەسىر كۆرسەتمەيدۇ.',
 'protect-default' => 'ھەممە ئىشلەتكۈچىگە يول قوي',
-'protect-fallback' => '"$1" نىڭ ئىجازىتى زۆرۈر.',
-'protect-level-autoconfirmed' => 'يېڭى ۋە تىزىملاتمىغان ئىشلەتكۈچى چەكلىنىدۇ',
-'protect-level-sysop' => 'باشقۇرغۇچىلا',
+'protect-fallback' => 'پەقەت "$1" ھوقۇقى بار ئىشلەتكۈچىلەرگىلا يول قويىدۇ',
+'protect-level-autoconfirmed' => 'ئۆزلۈكىدىن جەزملەنگەن ئىشلەتكۈچىلەرگىلا يول قويىدۇ',
+'protect-level-sysop' => 'باشقۇرغۇچىلارغىلا يول قويىدۇ',
 'protect-summary-cascade' => 'زەنجىرسىمان قۇلۇپ',
 'protect-expiring' => ' $1 (UTC) توختىتىلغان',
 'protect-expiring-local' => '$1 ۋاقتى توشىدۇ',
@@ -2970,6 +2975,7 @@ $1',
 'pageinfo-magic-words' => '{{PLURAL:$1|سېھرىي خەت}}',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|يوشۇرۇلغان تۈر}}',
 'pageinfo-templates' => '{{PLURAL:$1|سىڭدۈرۈلگەن قېلىپ}}',
+'pageinfo-transclusions' => '($1) {{PLURAL:$1|بەت}}تە سىڭدۈرۈلگەن',
 'pageinfo-toolboxlink' => 'بەت ئۇچۇر',
 'pageinfo-redirectsto' => 'قايتا نىشانلىنىدىغىنى',
 'pageinfo-redirectsto-info' => ' ئۇچۇر',
@@ -2978,6 +2984,10 @@ $1',
 'pageinfo-protect-cascading' => 'زەنجىرلىك قۇلۇپ بۇ جايدىن باشلىنىدۇ',
 'pageinfo-protect-cascading-yes' => 'ھەئە',
 'pageinfo-protect-cascading-from' => 'قوغداش دەرىجىسىنىڭ باغلىنىش ئورنى',
+'pageinfo-category-info' => 'تۈر ئۇچۇرى',
+'pageinfo-category-pages' => 'بەت سانى',
+'pageinfo-category-subcats' => 'تارماق تۈر سانى',
+'pageinfo-category-files' => 'ھۆججەت سانى',
 
 # Skin names
 'skinname-standard' => 'Classic',
@@ -3070,6 +3080,7 @@ $1',
 'minutes' => '{{PLURAL: $1|$1مىنۇت}}',
 'hours' => '{{PLURAL:$1|$1سائەت}}',
 'days' => '{{PLURAL:$1|$1 كۈن}}',
+'months' => '{{PLURAL:$1|$1 ئاي}}',
 'years' => '{{PLURAL:$1|$1 يىل}}',
 'ago' => '$1 بۇرۇن',
 'just-now' => 'بايا',
@@ -3761,7 +3772,7 @@ MediaWiki ئىشلىتىش مەقسىتىنى ئاساس قىلىپ ئېلان 
 'specialpages-group-highuse' => 'كۆپ ئىشلىتىلگەن بەت',
 'specialpages-group-pages' => 'بەت تىزىملىكى',
 'specialpages-group-pagetools' => 'بەت قورالى',
-'specialpages-group-wiki' => 'Wiki سانلىق مەلۇماتى ۋە قورال',
+'specialpages-group-wiki' => 'سانلىق مەلۇمات ۋە قوراللار',
 'specialpages-group-redirects' => 'قايتا نىشانلانغان ئالاھىدە بەت',
 'specialpages-group-spam' => 'ئەخلەتكە قارشى قورال',
 
@@ -3859,8 +3870,8 @@ MediaWiki ئىشلىتىش مەقسىتىنى ئاساس قىلىپ ئېلان 
 'logentry-newusers-newusers' => 'ئەزا $1 قۇرۇلبولدى',
 'logentry-newusers-create' => 'ئەزا $1 قۇرۇلبولدى',
 'logentry-newusers-create2' => 'ئىشلەتكۈچى ھېساباتى $3 نى $1 قۇردى',
+'logentry-newusers-byemail' => 'ئىشلەتكۈچى ھېساباتى $3 نى $1 قۇردى ھەمدە ئىمنى تورخەتكە ئەۋەتتى',
 'logentry-newusers-autocreate' => 'ئىشلەتكۈچى $1 ئاپتوماتلىق قۇرۇلدى',
-'newuserlog-byemail' => 'ئىم ئىلخەتتە يوللاندى',
 'logentry-rights-rights' => '$3 نىڭ ئىشلەتكۈچى گۇرۇپپىسىنى $4 دىن $5 غا $1 ئالماشتۇردى',
 'logentry-rights-rights-legacy' => '$3 نىڭ ئىشلەتكۈچى گۇرۇپپىسىنى $1 ئۆزگەرتتى',
 'logentry-rights-autopromote' => '$1 نىڭ ئىشلەتكۈچى گۇرۇپپىسى ئۆزلۈكىدىن $4 دىن $5 غا يۈكسەلدى',
@@ -3917,6 +3928,7 @@ MediaWiki ئىشلىتىش مەقسىتىنى ئاساس قىلىپ ئېلان 
 'api-error-ok-but-empty' => 'ئىچكى خاتالىق: مۇلازىمېتىردا ئىنكاس يوق.',
 'api-error-overwrite' => 'مەۋجۇد ھۆججەت قاپلاشقا يول قويمايدۇ.',
 'api-error-stashfailed' => 'ئىچكى خاتالىق: مۇلازىمېتىر ۋاقىتلىق ھۆججەتنى ساقلىيالمىدى.',
+'api-error-publishfailed' => 'ئىچكى خاتالىق: مۇلازىمېتىر ۋاقىتلىق ھۆججەتنى تارقىتالمىدى.',
 'api-error-timeout' => 'مۇلازىمەت كومپيۇتېر كۆتكەن ۋاقتا ئىنكاس قايتۇرمىدى.',
 'api-error-unclassified' => 'نامەلۇم خاتالىق كۆرۈلدى.',
 'api-error-unknown-code' => 'نامەلۇم خاتالىق:"$1"',
index 2963c19..907b52e 100644 (file)
@@ -793,7 +793,7 @@ $1',
 'gotaccount' => "Ви вже зареєстровані? '''$1'''.",
 'gotaccountlink' => 'Увійдіть',
 'userlogin-resetlink' => 'Забули дані, потрібні для входу?',
-'createaccountmail' => 'елекÑ\82Ñ\80онноÑ\8e Ð¿Ð¾Ñ\88Ñ\82оÑ\8e',
+'createaccountmail' => 'Ð\92икоÑ\80иÑ\81Ñ\82аÑ\82и Ñ\82имÑ\87аÑ\81овий Ð²Ð¸Ð¿Ð°Ð´ÐºÐ¾Ð²Ð¸Ð¹ Ð¿Ð°Ñ\80олÑ\8c Ñ\96 Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð¹Ð¾Ð³Ð¾ Ð½Ð° Ð°Ð´Ñ\80еÑ\81Ñ\83 ÐµÐ»ÐµÐºÑ\82Ñ\80онноÑ\97 Ð¿Ð¾Ñ\88Ñ\82и, Ð²ÐºÐ°Ð·Ð°Ð½Ñ\83 Ð½Ð¸Ð¶Ñ\87е',
 'createaccountreason' => 'Причина:',
 'badretype' => 'Уведені вами паролі не збігаються.',
 'userexists' => "Уведене ім'я користувача вже існує.
@@ -1409,7 +1409,7 @@ $1",
 'search-interwiki-default' => '$1 результати:',
 'search-interwiki-more' => '(більше)',
 'search-relatedarticle' => "Пов'язаний",
-'mwsuggest-disable' => 'Ð\92имкнÑ\83Ñ\82и Ð¿Ð¾Ñ\80ади AJAX',
+'mwsuggest-disable' => 'Ð\92имкнÑ\83Ñ\82и Ð¿Ð¾Ñ\88Ñ\83ковÑ\96 Ð¿Ñ\96дказки',
 'searcheverything-enable' => 'Пошук у всіх просторах назв',
 'searchrelated' => "пов'язаний",
 'searchall' => 'усі',
@@ -1516,7 +1516,7 @@ $1",
 'prefs-emailconfirm-label' => 'Підтвердження електронної пошти:',
 'prefs-textboxsize' => 'Розмір вікна редагування',
 'youremail' => 'Адреса електронної пошти:',
-'username' => '{{GENDER:$1|Ім’я користувача}}:',
+'username' => "{{GENDER:$1|Ім'я користувача|Ім'я користувачки}}:",
 'uid' => 'Ідентифікатор {{GENDER:$1|користувача}}:',
 'prefs-memberingroups' => '{{GENDER:$2|Член}} {{PLURAL:$1|групи|груп}}:',
 'prefs-memberingroups-type' => '$1',
@@ -2330,7 +2330,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Список активних користувачів',
 'activeusers-intro' => 'Це список користувачів, які здійснювали які-небудь дії за {{PLURAL:$1|останній $1 день|останні $1 дні|останні $1 днів}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|редагування|редагування|редагувань}} за {{PLURAL:$3|останній $3 день|останні $3 дні|останні $3 днів}}',
+'activeusers-count' => '$1 {{PLURAL:$1|дія|дії|дій}} за {{PLURAL:$3|останній $3 день|останні $3 дні|останні $3 днів}}',
 'activeusers-from' => 'Показувати користувачів, починаючи з:',
 'activeusers-hidebots' => 'Приховати ботів',
 'activeusers-hidesysops' => 'Приховати адміністраторів',
@@ -2517,7 +2517,7 @@ $UNWATCHURL
 'rollbacklinkcount' => 'скасування $1 {{PLURAL:$1|редагування|редагувань|редагувань}}',
 'rollbacklinkcount-morethan' => 'скасування більш, ніж $1 {{PLURAL:$1|редагування|редагувань|редагувань}}',
 'rollbackfailed' => 'Відкинути зміни не вдалося',
-'cantrollback' => 'Неможливо відкинути редагування, оскільки останній дописувач є її автором.',
+'cantrollback' => 'Ð\9dеможливо Ð²Ñ\96дкинÑ\83Ñ\82и Ñ\80едагÑ\83ваннÑ\8f, Ð¾Ñ\81кÑ\96лÑ\8cки Ð¾Ñ\81Ñ\82аннÑ\96й Ð´Ð¾Ð¿Ð¸Ñ\81Ñ\83ваÑ\87 Ñ\81Ñ\82оÑ\80Ñ\96нки Ñ\94 Ñ\97Ñ\97 Ð°Ð²Ñ\82оÑ\80ом.',
 'alreadyrolled' => 'Неможливо відкинути останні редагування [[:$1]], зроблені [[User:$2|$2]] ([[User talk:$2|обговорення]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), оскільки хтось інший уже змінив чи відкинув редагування цієї статті.
 
 Останні редагування зроблено [[User:$3|$3]] ([[User talk:$3|обговорення]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
@@ -2860,7 +2860,7 @@ $1',
 Якщо ви цього не зробите, будь ласка, перевірте наявність [[Special:DoubleRedirects|подвійних]] чи [[Special:BrokenRedirects|розірваних]] перенаправлень.
 Ви відповідаєте за те, щоб посилання і надалі вказували туди, куди припускалося.
 
\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка '''не''' Ð±Ñ\83де Ð¿ÐµÑ\80ейменована, Ñ\8fкÑ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка Ð· Ð½Ð¾Ð²Ð¾Ñ\8e Ð½Ð°Ð·Ð²Ð¾Ñ\8e Ð²Ð¶Ðµ Ñ\96Ñ\81нÑ\83Ñ\94, Ð¾ÐºÑ\80Ñ\96м Ð²Ð¸Ð¿Ð°Ð´ÐºÑ\96в, ÐºÐ¾Ð»Ð¸ Ð²Ð¾Ð½Ð° порожня або є перенаправленням, а журнал її редагувань порожній.
\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка '''не''' Ð±Ñ\83де Ð¿ÐµÑ\80ейменована, Ñ\8fкÑ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка Ð· Ð½Ð¾Ð²Ð¾Ñ\8e Ð½Ð°Ð·Ð²Ð¾Ñ\8e Ð²Ð¶Ðµ Ñ\96Ñ\81нÑ\83Ñ\94, Ð¾ÐºÑ\80Ñ\96м Ð²Ð¸Ð¿Ð°Ð´ÐºÑ\96в, ÐºÐ¾Ð»Ð¸ Ð¾Ñ\81Ñ\82аннÑ\8f порожня або є перенаправленням, а журнал її редагувань порожній.
 Це означає, що ви можете повернути сторінці стару назву, якщо ви перейменували її помилково, але ви не можете затерти існуючу сторінку.
 
 '''ПОПЕРЕДЖЕННЯ!'''
@@ -3221,6 +3221,7 @@ The wiki server can't provide data in a format your client can read.",
 'pageinfo-robot-noindex' => 'Не індексується',
 'pageinfo-views' => 'Кількість переглядів',
 'pageinfo-watchers' => 'Кількість спостерігачів',
+'pageinfo-few-watchers' => 'Менше ніж $1 {{PLURAL:$1|спостерігач|спостерігачі|спостерігачів}}',
 'pageinfo-redirects-name' => 'Перенаправлення на цю сторінку',
 'pageinfo-subpages-name' => 'Підсторінки цієї сторінки',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|перенаправлення|перенаправлення|перенаправлень}}; $3 {{PLURAL:$3|неперенаправлення|неперенаправлення|неперенаправлень}})',
@@ -4130,6 +4131,8 @@ MediaWiki поширюється в надії, що вона буде кори
 'version-entrypoints' => 'URL-адреса точки входу',
 'version-entrypoints-header-entrypoint' => 'Точка входу',
 'version-entrypoints-header-url' => 'URL',
+'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath Шлях до статей]',
+'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath Шлях до скриптів]',
 
 # Special:FilePath
 'filepath' => 'Шлях до файлу',
@@ -4164,7 +4167,7 @@ MediaWiki поширюється в надії, що вона буде кори
 'specialpages-group-highuse' => 'Часто вживані',
 'specialpages-group-pages' => 'Списки сторінок',
 'specialpages-group-pagetools' => 'Інструменти',
-'specialpages-group-wiki' => 'Ð\92Ñ\96кÑ\96-дані та інструменти',
+'specialpages-group-wiki' => 'Ð\94ані та інструменти',
 'specialpages-group-redirects' => 'Перенаправлення',
 'specialpages-group-spam' => 'Інструменти проти спаму',
 
@@ -4261,8 +4264,8 @@ MediaWiki поширюється в надії, що вона буде кори
 'logentry-newusers-newusers' => 'Створено обліковий запис $1',
 'logentry-newusers-create' => '$1 — створено обліковий запис',
 'logentry-newusers-create2' => '$1 {{GENDER:$2|створив|створила}} обліковий запис {{GENDER:$4|користувача|користувачки}} $3',
+'logentry-newusers-byemail' => 'Обліковий запис {{GENDER:$2|користувача|користувачки}} створений {{GENDER:$4|користувачем|користувачкою}} $1 і пароль було надіслано електронною поштою',
 'logentry-newusers-autocreate' => '$1 — автоматично створений обліковий запис',
-'newuserlog-byemail' => 'пароль надісланий електронною поштою',
 'logentry-rights-rights' => '$1 {{GENDER:$1|змінив|змінила}} членство в групах для $3 із $4 на $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|змінив|змінила}} членство в групах для $3',
 'logentry-rights-autopromote' => '$1 було автоматично переведено із $4 в $5',
@@ -4320,6 +4323,7 @@ MediaWiki поширюється в надії, що вона буде кори
 'api-error-ok-but-empty' => 'Внутрішня помилка: сервер не відповідає.',
 'api-error-overwrite' => 'Заміну існуючого файлу не дозволено.',
 'api-error-stashfailed' => 'Внутрішня помилка: сервер не зміг зберегти тимчасовий файл.',
+'api-error-publishfailed' => 'Внутрішня помилка: сервер не зміг опублікувати тимчасовий файл.',
 'api-error-timeout' => 'Сервер не відповідає протягом очікуваного часу.',
 'api-error-unclassified' => 'Сталася невідома помилка.',
 'api-error-unknown-code' => 'Невідома помилка: «$1»',
index 72f19ca..aff7c2d 100644 (file)
@@ -46,6 +46,115 @@ $namespaceNames = array(
        NS_CATEGORY_TALK    => 'تبادلۂ_خیال_زمرہ',
 );
 
+$specialPageAliases = array(
+       'Activeusers'               => array( 'متحرک_صارفین' ),
+       'Allmessages'               => array( 'تمام_پیغامات' ),
+       'Allpages'                  => array( 'تمام_صفحات' ),
+       'Ancientpages'              => array( 'قدیم_صفحات' ),
+       'Badtitle'                  => array( 'خراب_عنوان' ),
+       'Blankpage'                 => array( 'خالی_صفحہ' ),
+       'Block'                     => array( 'پابندی،_دستور_شبکی_پابندی،_پابندی_بر_صارف' ),
+       'Blockme'                   => array( 'میری_پابندی' ),
+       'Booksources'               => array( 'کتابی_وسائل' ),
+       'BrokenRedirects'           => array( 'شکستہ_رجوع_مکررات' ),
+       'Categories'                => array( 'زمرہ_جات' ),
+       'ChangeEmail'               => array( 'ڈاک_تبدیل' ),
+       'ChangePassword'            => array( 'کلمہ_شناخت_تبدیل،_تنظیم_کلمہ_شناخت' ),
+       'ComparePages'              => array( 'موازنہ_صفحات' ),
+       'Confirmemail'              => array( 'تصدیق_ڈاک' ),
+       'Contributions'             => array( 'شراکتیں' ),
+       'CreateAccount'             => array( 'تخلیق_کھاتہ' ),
+       'Deadendpages'              => array( 'مردہ_صفحات' ),
+       'DeletedContributions'      => array( 'حذف_شدہ_شراکتیں' ),
+       'Disambiguations'           => array( 'ضد_ابہام_صفحات' ),
+       'DoubleRedirects'           => array( 'دوہرے_رجوع_مکررات' ),
+       'EditWatchlist'             => array( 'ترمیم_زیر_نظر' ),
+       'Emailuser'                 => array( 'صارف_ڈاک' ),
+       'Export'                    => array( 'برآمدگی' ),
+       'Fewestrevisions'           => array( 'کم_نظر_ثانی_شدہ' ),
+       'FileDuplicateSearch'       => array( 'دہری_ملف_تلاش' ),
+       'Filepath'                  => array( 'راہ_ملف' ),
+       'Import'                    => array( 'درآمدگی' ),
+       'Invalidateemail'           => array( 'ڈاک_تصدیق_منسوخ' ),
+       'JavaScriptTest'            => array( 'تجربہ_جاوا_اسکرپٹ' ),
+       'BlockList'                 => array( 'فہرست_ممنوع،_فہرست_دستور_شبکی_ممنوع' ),
+       'LinkSearch'                => array( 'تلاش_روابط' ),
+       'Listadmins'                => array( 'فہرست_منتظمین' ),
+       'Listbots'                  => array( 'فہرست_روبہ_جات' ),
+       'Listfiles'                 => array( 'فہرست_املاف،_فہرست_تصاویر' ),
+       'Listgrouprights'           => array( 'فہرست_اختیارات_گروہ،_صارفی_گروہ_اختیارات' ),
+       'Listredirects'             => array( 'فہرست_رجوع_مکررات' ),
+       'Listusers'                 => array( 'فہرست_صارفین،_صارف_فہرست' ),
+       'Log'                       => array( 'نوشتہ،_نوشتہ_جات' ),
+       'Lonelypages'               => array( 'یتیم_صفحات' ),
+       'Longpages'                 => array( 'طویل_صفحات' ),
+       'MergeHistory'              => array( 'ضم_تاریخچہ' ),
+       'Movepage'                  => array( 'منتقلی_صفحہ' ),
+       'Mycontributions'           => array( 'میرا_حصہ' ),
+       'Mypage'                    => array( 'میرا_صفحہ' ),
+       'Mytalk'                    => array( 'میری_گفتگو' ),
+       'Myuploads'                 => array( 'میرے_زبراثقالات' ),
+       'Newimages'                 => array( 'جدید_املاف،_جدید_تصاویر' ),
+       'Newpages'                  => array( 'جدید_صفحات' ),
+       'PermanentLink'             => array( 'مستقل_ربط' ),
+       'Popularpages'              => array( 'مقبول_صفحات' ),
+       'Preferences'               => array( 'ترجیحات' ),
+       'Prefixindex'               => array( 'اشاریہ_سابقہ' ),
+       'Protectedpages'            => array( 'محفوظ_صفحات' ),
+       'Protectedtitles'           => array( 'محفوظ_عناوین' ),
+       'Randompage'                => array( 'تصادف،_تصادفی_مقالہ' ),
+       'Randomredirect'            => array( 'تصادفی_رجوع_مکرر' ),
+       'Recentchanges'             => array( 'حالیہ_تبدیلیاں' ),
+       'Recentchangeslinked'       => array( 'متعلقہ_تبدیلیاں' ),
+       'Revisiondelete'            => array( 'حذف_اعادہ' ),
+       'Search'                    => array( 'تلاش' ),
+       'Shortpages'                => array( 'مختصر_صفحات' ),
+       'Specialpages'              => array( 'خصوصی_صفحات' ),
+       'Statistics'                => array( 'شماریات' ),
+       'Uncategorizedcategories'   => array( 'غیر_زمرہ_بند_زمرہ_جات' ),
+       'Uncategorizedimages'       => array( 'غیر_زمرہ_بند_املاف،_غیر_زمرہ_بند_تصاویر' ),
+       'Uncategorizedpages'        => array( 'غیر_زمرہ_بند_صفحات' ),
+       'Uncategorizedtemplates'    => array( 'غیر_زمرہ_بند_سانچے' ),
+       'Undelete'                  => array( 'بحال' ),
+       'Unusedcategories'          => array( 'غیر_مستعمل_زمرہ_جات' ),
+       'Unusedimages'              => array( 'غیر_مستعمل_املاف،_غیر_مستعمل_تصاویر' ),
+       'Unusedtemplates'           => array( 'غیر_مستعمل_سانچے' ),
+       'Unwatchedpages'            => array( 'نادیدہ_صفحات' ),
+       'Upload'                    => array( 'زبراثقال' ),
+       'Userlogin'                 => array( 'داخل_نوشتگی' ),
+       'Userlogout'                => array( 'خارج_نوشتگی' ),
+       'Userrights'                => array( 'صارفی_اختیارات' ),
+       'Version'                   => array( 'اخراجہ' ),
+       'Wantedcategories'          => array( 'مطلوب_زمرہ_جات' ),
+       'Wantedfiles'               => array( 'مطلوب_املاف' ),
+       'Wantedpages'               => array( 'مطلوب_صفحات،_شکستہ_روابط' ),
+       'Wantedtemplates'           => array( 'مطلوب_سانچے' ),
+       'Watchlist'                 => array( 'زیر_نظر_فہرست' ),
+       'Whatlinkshere'             => array( 'یہاں_کس_کا_رابطہ' ),
+       'Withoutinterwiki'          => array( 'بدون_بین_الویکی' ),
+);
+
+$magicWords = array(
+       'redirect'                  => array( '0', '#رجوع_مکرر', '#REDIRECT' ),
+       'notoc'                     => array( '0', '_فہرست_نہیں_', '__NOTOC__' ),
+       'toc'                       => array( '0', '__فہرست__', '__TOC__' ),
+       'noeditsection'             => array( '0', '__ناتحریرقسم__', '__NOEDITSECTION__' ),
+       'msg'                       => array( '0', 'پیغام:', 'MSG:' ),
+       'subst'                     => array( '0', 'نقل:', 'SUBST:' ),
+       'safesubst'                 => array( '0', 'محفوظ_نقل:', 'SAFESUBST:' ),
+       'img_thumbnail'             => array( '1', 'تصغیر', 'thumbnail', 'thumb' ),
+       'img_right'                 => array( '1', 'دائیں', 'right' ),
+       'img_left'                  => array( '1', 'بائیں', 'left' ),
+       'img_center'                => array( '1', 'درمیان', 'center', 'centre' ),
+       'sitename'                  => array( '1', 'نام_موقع', 'SITENAME' ),
+       'grammar'                   => array( '0', 'قواعد:', 'GRAMMAR:' ),
+       'gender'                    => array( '0', 'جنس:', 'GENDER:' ),
+       'special'                   => array( '0', 'خاص', 'special' ),
+       'speciale'                  => array( '0', 'خاص_عنوان', 'speciale' ),
+       'index'                     => array( '1', '__اشاریہ__', '__INDEX__' ),
+       'noindex'                   => array( '1', '__نااشاریہ__', '__NOINDEX__' ),
+);
+
 $messages = array(
 # User preference toggles
 'tog-underline' => 'ربط کی خط کشیدگی:',
index e713bb8..e01943a 100644 (file)
@@ -52,6 +52,54 @@ $namespaceAliases = array(
        'Kategoriya_munozarasi' => NS_CATEGORY_TALK,
 );
 
+$magicWords = array(
+       'redirect'                  => array( '0', '#YONALTIRISH', '#REDIRECT' ),
+       'notoc'                     => array( '0', '__ICHIDAGILARYOQ__', '__NOTOC__' ),
+       'nogallery'                 => array( '0', '__GALEREYAYOQ__', '__NOGALLERY__' ),
+       'forcetoc'                  => array( '0', '__ICHIDAGILARMAJBURIY__', '__FORCETOC__' ),
+       'toc'                       => array( '0', '__ICHIDAGILARI__', '__ICHIDAGILAR__', '__TOC__' ),
+       'noeditsection'             => array( '0', '__TAHRIRYOQ__', '__TARTIBLASHYOQ__', '__NOEDITSECTION__' ),
+       'currentmonth'              => array( '1', 'JORIYOY', 'JORIYOY2', 'CURRENTMONTH', 'CURRENTMONTH2' ),
+       'currentmonth1'             => array( '1', 'JORIYOY1', 'CURRENTMONTH1' ),
+       'currentmonthname'          => array( '1', 'JORIYOYNOMI', 'CURRENTMONTHNAME' ),
+       'currentmonthnamegen'       => array( '1', 'JORIYOYNOMIQARATQICH', 'CURRENTMONTHNAMEGEN' ),
+       'currentmonthabbrev'        => array( '1', 'JORIYOYQISQARTMASI', 'CURRENTMONTHABBREV' ),
+       'currentday'                => array( '1', 'JORIYKUN', 'CURRENTDAY' ),
+       'currentday2'               => array( '1', 'JORIYKUN2', 'CURRENTDAY2' ),
+       'currentdayname'            => array( '1', 'JORIYKUNNOMI', 'CURRENTDAYNAME' ),
+       'currentyear'               => array( '1', 'JORIYYIL', 'CURRENTYEAR' ),
+       'currenttime'               => array( '1', 'JORIYVAQT', 'CURRENTTIME' ),
+       'currenthour'               => array( '1', 'JORIYSOAT', 'CURRENTHOUR' ),
+       'localmonth'                => array( '1', 'MAHALLIYOY', 'MAHALLIYOY2', 'LOCALMONTH', 'LOCALMONTH2' ),
+       'localmonth1'               => array( '1', 'MAHALLIYOY1', 'LOCALMONTH1' ),
+       'localmonthname'            => array( '1', 'MAHALLIYOYNOMI', 'LOCALMONTHNAME' ),
+       'localmonthnamegen'         => array( '1', 'MAHALLIYOYQARATQICH', 'LOCALMONTHNAMEGEN' ),
+       'localmonthabbrev'          => array( '1', 'MAHALLIYOYQISQARTMASI', 'LOCALMONTHABBREV' ),
+       'localday'                  => array( '1', 'MAHALLIYKUN', 'LOCALDAY' ),
+       'localday2'                 => array( '1', 'MAHALLIYKUN2', 'LOCALDAY2' ),
+       'localdayname'              => array( '1', 'MAHALLIYKUNNOMI', 'LOCALDAYNAME' ),
+       'localyear'                 => array( '1', 'MAHALLIYYIL', 'LOCALYEAR' ),
+       'localtime'                 => array( '1', 'MAHALLIYVAQT', 'LOCALTIME' ),
+       'localhour'                 => array( '1', 'MAHALLIYSOAT', 'LOCALHOUR' ),
+       'numberofpages'             => array( '1', 'SAHIFASONI', 'NUMBEROFPAGES' ),
+       'numberofarticles'          => array( '1', 'MAQOLASONI', 'NUMBEROFARTICLES' ),
+       'numberoffiles'             => array( '1', 'FAYLSONI', 'NUMBEROFFILES' ),
+       'numberofusers'             => array( '1', 'FOYDALANUVCHISONI', 'NUMBEROFUSERS' ),
+       'numberofactiveusers'       => array( '1', 'FAOLFOYDALANUVCHISONI', 'NUMBEROFACTIVEUSERS' ),
+       'numberofedits'             => array( '1', 'OZGARISHSONI', 'NUMBEROFEDITS' ),
+       'numberofviews'             => array( '1', 'KORISHSONI', 'NUMBEROFVIEWS' ),
+       'pagename'                  => array( '1', 'SAHIFANOMI', 'PAGENAME' ),
+       'numberofadmins'            => array( '1', 'ADMINISTRATORSONI', 'NUMBEROFADMINS' ),
+       'special'                   => array( '0', 'maxsus', 'special' ),
+       'tag'                       => array( '0', 'yorliq', 'tag' ),
+       'hiddencat'                 => array( '1', '__YASHIRINTURKUM__', '__HIDDENCAT__' ),
+       'pagesincategory'           => array( '1', 'TURKUMDAGISAHIFALAR', 'PAGESINCATEGORY', 'PAGESINCAT' ),
+       'pagesize'                  => array( '1', 'SAHIFAHAJMI', 'PAGESIZE' ),
+       'index'                     => array( '1', '__INDEKS__', '__INDEX__' ),
+       'noindex'                   => array( '1', '__INDEKSYOQ__', '__NOINDEX__' ),
+       'url_wiki'                  => array( '0', 'VIKI', 'WIKI' ),
+);
+
 $linkTrail = '/^([a-zʻʼ“»]+)(.*)$/sDu';
 
 $messages = array(
@@ -674,7 +722,7 @@ Bu yerda: (joriy) = hozirgi koʻrinish bilan farq,
 'search-interwiki-default' => '$1 natijalar:',
 'search-interwiki-more' => '(yana)',
 'search-relatedarticle' => "Bog'liq",
-'mwsuggest-disable' => "AJAX-takliflarini o'chirish",
+'mwsuggest-disable' => 'Qidiruv takliflarini oʻchirib qoʻyish',
 'searcheverything-enable' => 'Barcha nomfazolarda qidir',
 'searchrelated' => 'bogʻlangan',
 'searchall' => 'barchasi',
index 9546aca..58208a8 100644 (file)
@@ -67,7 +67,8 @@ $specialPageAliases = array(
        'Booksources'               => array( 'SercaISBN' ),
        'BrokenRedirects'           => array( 'RimandiSbalià' ),
        'Categories'                => array( 'Categorie' ),
-       'ChangePassword'            => array( 'ReinpostaPassword' ),
+       'ChangeEmail'               => array( 'CanbiaEmail' ),
+       'ChangePassword'            => array( 'CanbiaPassword' ),
        'ComparePages'              => array( 'ConfrontaPagine' ),
        'Confirmemail'              => array( 'ConfermaEMail' ),
        'Contributions'             => array( 'Contributi' ),
@@ -76,6 +77,7 @@ $specialPageAliases = array(
        'DeletedContributions'      => array( 'ContributiScancelà' ),
        'Disambiguations'           => array( 'Disanbiguassion' ),
        'DoubleRedirects'           => array( 'DópiRimandi' ),
+       'EditWatchlist'             => array( 'CanbiaTegnuiDeOcio' ),
        'Emailuser'                 => array( 'MandaEMail' ),
        'Export'                    => array( 'Esporta' ),
        'Fewestrevisions'           => array( 'PagineConMancoRevision' ),
@@ -99,6 +101,7 @@ $specialPageAliases = array(
        'MIMEsearch'                => array( 'SercaMIME' ),
        'Mostcategories'            => array( 'PagineConPiassèCategorie' ),
        'Mostimages'                => array( 'FilePiassèDoparà' ),
+       'Mostinterwikis'            => array( 'PiassèInterwiki' ),
        'Mostlinked'                => array( 'PaginePiassèRiciamà' ),
        'Mostlinkedcategories'      => array( 'CategoriePiassèDoparà' ),
        'Mostlinkedtemplates'       => array( 'ModèiPiassèDoparà' ),
@@ -107,8 +110,11 @@ $specialPageAliases = array(
        'Mycontributions'           => array( 'IMeContributi' ),
        'Mypage'                    => array( 'LaMePaginaUtente' ),
        'Mytalk'                    => array( 'LeMeDiscussion' ),
+       'Myuploads'                 => array( 'IMeCaricamenti' ),
        'Newimages'                 => array( 'FileNovi' ),
        'Newpages'                  => array( 'PagineNove' ),
+       'PasswordReset'             => array( 'ReinpostaPassword' ),
+       'PermanentLink'             => array( 'LinkParmanente' ),
        'Popularpages'              => array( 'PaginePiassèVisità' ),
        'Preferences'               => array( 'Preferense' ),
        'Prefixindex'               => array( 'Prefissi' ),
@@ -172,9 +178,9 @@ $messages = array(
 'tog-previewontop' => "Mostra l'anteprima sora ła caseła de modifega e no soto",
 'tog-previewonfirst' => "Mostra l'anteprima par ła prima modifega",
 'tog-nocache' => 'Disativa ła cache par łe pajine del browser',
-'tog-enotifwatchlistpages' => 'Segnałame via e-mail łe modifeghe a łe pajine oservae',
+'tog-enotifwatchlistpages' => "Segnałame via e-mail có vien canbià na pàjina o un file prexente inte ła lista de łe tegnùe d'ocio",
 'tog-enotifusertalkpages' => 'Avìseme par e-mail se i scrive su la me pagina de discussion',
-'tog-enotifminoredits' => 'Avìseme par e-mail anca par i canbiamenti picenini',
+'tog-enotifminoredits' => "Avìxeme par e-mail anca pa' i canbiamenti picenini de pàjine e file",
 'tog-enotifrevealaddr' => 'Fà védar el me indirisso e-mail in tei messagi de aviso',
 'tog-shownumberswatching' => 'Mostra el numaro de utenti che i ga ła pajina en oservasion',
 'tog-oldsig' => 'Anteprima de ła firma:',
@@ -197,7 +203,7 @@ $messages = array(
 
 'underline-always' => 'Senpre',
 'underline-never' => 'Mai',
-'underline-default' => 'Mantieni łe inpostasion del browser',
+'underline-default' => 'Mantien łe inpostasion del browser o de ła skin',
 
 # Font style option in Special:Preferences
 'editfont-style' => "Stiłe font de l'area de modifega:",
@@ -283,7 +289,7 @@ $messages = array(
 'cancel' => 'Lassa star',
 'moredotdotdot' => 'Altro...',
 'morenotlisted' => 'Altro nó elencà',
-'mypage' => 'La me pagina',
+'mypage' => 'Pàjina',
 'mytalk' => 'Discussion',
 'anontalk' => 'Discusion par sto IP',
 'navigation' => 'Navigasion',
@@ -306,7 +312,7 @@ $messages = array(
 'vector-action-protect' => 'Protezi',
 'vector-action-undelete' => 'Recupera',
 'vector-action-unprotect' => 'Canbia ła protesion',
-'vector-simplesearch-preference' => "Intaca i sugerimenti di ricerca avansadi (solo par l'interfacia Vector)",
+'vector-simplesearch-preference' => "Abiłita ła sbara par ła riserca senplifegà (soło che par l'interfacia Vector)",
 'vector-view-create' => 'Crea',
 'vector-view-edit' => 'Canbia',
 'vector-view-history' => "Varda ła 'storia",
@@ -468,12 +474,12 @@ L'elenco de le pagine speciali te lo cati su [[Special:SpecialPages|{{int:specia
 # General errors
 'error' => 'Erore',
 'databaseerror' => 'Erore del database',
-'dberrortext' => 'Erore de sintassi ne ła richiesta inoltrà al database.
-Ciò podaria indicare ła presensa de on bug nel software.
-L\'ultima query invià al database xè sta:
+'dberrortext' => 'Eror de sintasi inte ła dimanda inoltrà al database.
+Ciò podaria indicar ła prexensa de un bug inte\'l software.
+L\'ultema query invià al database ła xè sta:
 <blockquote><tt>$1</tt></blockquote>
 riciamà da ła funsion "<tt>$2</tt>".
-El database el ga restituio el seguente erore "<tt>$3: $4</tt>".',
+El database el ga restituio el seguente eror "<tt>$3: $4</tt>".',
 'dberrortextcl' => 'Erore de sintasi ne ła richiesta inoltrà al database.
 L\'ultima query invià al database xè sta:
 "$1"
@@ -525,12 +531,13 @@ Query: $2',
 'viewsource-title' => 'Varda el testo de $1',
 'actionthrottled' => 'Asion ritardà',
 'actionthrottledtext' => "Come misura de sicuresa contro e o spam, l'esecusion de alcune asion e a xè limità a on numaro masimo de volte en on determinà periodo de tenpo, limite che en questo caso xè sta superà. Se prega de riprovare tra qualche minuto.",
-'protectedpagetext' => 'Sta pagina la xe stà proteta de modo che nissuni possa canbiarla.',
+'protectedpagetext' => 'Sta pàjina ła xe stà proteta de modo che nisun posa canbiarla o far altre operasion.',
 'viewsourcetext' => 'Se pole vardar e copiar el testo de sta pagina:',
 'viewyourtext' => "Xè posibile vedàre e copiare el codexe sorzente de le '''to modifighe''' a sta pajina:",
-'protectedinterface' => "Sta pagina la gà drento un testo de l'interfacia utente del software, quindi la xe proteta parché nissuni la strussia.",
-'editinginterface' => "'''Ocio:''' El testo de sta pajina el fa parte de l'interfacia utente del sito. Tute łe modifeghe aportae a sta pajina se riflete so i mesaji visuałizà par tuti i utenti.
-Par łe tradusion, considera ła posibiłità de usare [//translatewiki.net/wiki/Main_Page?setlang=vec translatewiki.net], el projeto MediaWiki par ła localizasion.",
+'protectedinterface' => "Sta pàjina ła gà drento un testo de l'interfacia utente del software de sto sito, quindi la xe proteta parché nisuni ła strusie.
+Par xontar o modifegar tradusion par tute łe wiki doparar [//translatewiki.net/ translatewiki.net], el projeto de locałixasion de MediaWiki.",
+'editinginterface' => "'''Ocio:''' El testo de sta pàjina el fa parte de l'interfacia utente del sito. Tute łe modifeghe aportae a sta pajina se riflete so i mesaji visuałixà par tuti i utenti so sta wiki.
+Par xontare o modifegar łe tradusion vałide so tute łe wiki, considera ła posibiłità de doparar [//translatewiki.net/wiki/Main_Page?setlang=vec translatewiki.net], el projeto MediaWiki par ła localixasion.",
 'sqlhidden' => '(ła query SQL ła xè sta sconta)',
 'cascadeprotected' => 'So sta pajina no xè posibiłe efetuare modifeghe parché xè sta inclusa {{PLURAL:$1|ne ła pajina indicà de seguito, che xè sta proteta|ne łe pajine indicae de seguito, che e xè sta protete}} sełesionando ła protesion "ricorsiva":
 $2',
@@ -583,7 +590,7 @@ Nó desmentegarte de personałixare łe [[Special:Preferences|prefarense de {{SI
 'gotaccount' => "Sito zà iscrito? '''$1'''.",
 'gotaccountlink' => 'Entra',
 'userlogin-resetlink' => "Desmentegà i to dati d'aceso?",
-'createaccountmail' => 'Par e-mail',
+'createaccountmail' => 'Dopara na password caxuałe tenporanea e inviała al indiriso e-mail spesifegà cuà soto',
 'createaccountreason' => 'Motivassion:',
 'badretype' => 'Le do password le xe difarenti.',
 'userexists' => 'El nome utente inserido vien xa doparà da cualchedun altro.
@@ -814,12 +821,11 @@ o <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}
 'userpage-userdoesnotexist-view' => 'L\'utensa "$1" no la xe gnancora registrà.',
 'blocked-notice-logextract' => "Sto utente xè atualmente blocà.
 L'ultimo ełemento del rejistro de i blochi xè riportà de seguito par informasion:",
-'clearyourcache' => "Ocio: dopo aver salvà, połe darse che te gabi da netare ła cache del to browser par védar i canbiamenti.
+'clearyourcache' => "Ocio: dopo 'ver salvà, pol darse che te gabi da netare ła cache del to browser par védar i canbiamenti.
 *Par '''Firefox / Safari:''' tien macà el boton de łe majuscołe e schicia \"Recarga\", o senò maca ''Ctrl-F5'' o ''Ctrl-R'' (''⌘-R'' se te ghè el Mac)
-*Par '''Google Chrome''':schicia ''Ctrl-Shift-R'' (''⌘-Shift-R'' co' un Mac)
+*Par '''Google Chrome''':schicia ''Ctrl-Shift-R'' (''⌘-Shift-R'' có un Mac)
 *Par '''Internet Explorer''': tien schicià el boton \"Ctrl\" fin che te schici '''Recarga''', senò schicia '''Ctrl+F5'''
-*Par '''Konqueror''': schicia \"Recarga\" o maca ''F5'';
-*Par '''Opera:''' néta la cache in ''Strumenti → Preferense;''",
+*Par '''Opera:''' néta la cache in ''Strumenti → Prefarense;''",
 'usercssyoucanpreview' => "'''Sugerimento:''' se consiglia de doparar el boton \"{{int:showpreview}} par proàr i novi CSS prima de salvarli.",
 'userjsyoucanpreview' => "'''Sugerimento:''' se consiglia de doparar el boton \"{{int:showpreview}}\" par proàr i novi JavaScript prima de salvarli.",
 'usercsspreview' => "'''Sta qua la xe solo n'anteprima del proprio CSS personal.
@@ -831,7 +837,7 @@ Le modifiche no le xe gnancora stà salvà!'''",
 'updated' => '(Agiornà)',
 'note' => "'''Nota:'''",
 'previewnote' => "Sta cua ła xe soło n'anteprima; i canbiamenti a ła pajina NO i xe gnancora stà salvài!",
-'continue-editing' => 'Continua modifegare',
+'continue-editing' => "Va a l'area de modifega",
 'previewconflict' => 'Sta anteprima la corisponde al testo ne la casèla de edizion de sora, e la fa védar come vegnarà fora la pagina se te machi "Salva la pagina" in sto momento.',
 'session_fail_preview' => "No xè stà possibiłe salvar le to modifiche parché i dati de la session i xè andai persi.
 Par piaser, riproa da novo.
@@ -868,10 +874,10 @@ Sapi che te stè prometendo che te stè inserendo un testo scrito de to pugno, o
 '''NO STA INSERIR OPERE PROTETE DA COPYRIGHT SENSA PERMESSO!'''",
 'longpageerror' => "'''Erore: el testo invià xe grando {{PLURAL:$1|1|$1}} kilobyte, che xe de pì deła dimension masima consentìa de {{PLURAL:$2|1|$2}} kilobyte.'''
 El testo no połe esare salvà.",
-'readonlywarning' => "'''OCIO: El database el xe stà blocà par manutenzion, quindi no se pol salvar le modifiche in sto momento.
-Par no pèrdarle, te pol copiar tuto quel che te ghè inserìo fin desso ne la casela de modifica, incolarlo in un programa de elaborazion de testi e salvarlo, intanto che te speti che i sbloca el database.'''
+'readonlywarning' => "'''OCIO: El database el xe stà blocà par manutension, cuindi nó se pol salvar łe modifeghe in sto momento.'''
+Par nó pèrdarle, te pol copiar tuto chel che te ghè inserìo fin deso inte ła caxeła de modifega, incołarlo inte un programa de elaborasion de testi e salvarlo, intanto che te speti che i sbloca el database.
 
-L'aministrador che gà blocà el database el gà dato la seguente spiegassion: $1",
+L'aministrador che gà blocà el database el gà dato ła seguente spiegasion: $1",
 'protectedpagewarning' => "'''Ocio:''' Sta pajina ła xe sta proteta in maniera che soło i aministradori i posa canbiarla. Sta qua ła xe l'ultima operasion catà sul registro de ła pajina:",
 'semiprotectedpagewarning' => "'''Ocio:''' Sta pajina ła xe stà proteta in maniera che soło i utenti rexistrài i posa canbiarla. Sta qua ła xe l'ultima operasion catà sul registro de ła pajina:",
 'cascadeprotectedwarning' => "'''Ocio:''' Sta pajina ła xe stà proteta in maniera che soło i utenti co priviłegi de aministrador i posa canbiarla. Questo sucede parché ła pajina ła xe inclusa {{PLURAL:\$1|'nte ła pajina indicà de seguito, che ła xe stà proteta|ne le pagine indicà de seguito, che łe xe stae protete}} sełesionando ła protesion \"ricorsiva\":",
@@ -1065,9 +1071,11 @@ No ti gà acesso su de ela.',
 'revdelete-no-change' => "''Ocio:''' la version datà $1 a le $2 la gà zà le inpostassion de visibilità da ti richieste.",
 'revdelete-concurrent-change' => "No se riesse a modificar la version datà $1 a le $2: pararìa che qualchidun altro el gavesse canbià el stato de la version intanto che ti te sercavi de far la stessa roba. Daghe n'ociada sui registri.",
 'revdelete-only-restricted' => "Eròr sercando de scondar l'elemento datà $1 a le $2: no te podi inpedirghe ai aministradori de vardar na revision se no te selessioni al tenpo stesso una de le altre opzioni de restrizion.",
-'revdelete-reason-dropdown' => '*Motivassion pi comuni par la scancelassion
-** Violassion de copyright
-** Informassion personali inapropriàe',
+'revdelete-reason-dropdown' => '*Motivasion pi comuni par la scansełasion
+** Viołasion de copyright
+** Comenti o informasion personali inapropriàe
+** Nome utente inapropià
+** Informasion potensialmente difamatoria',
 'revdelete-otherreason' => 'Altro:',
 'revdelete-reasonotherlist' => 'Altra motivassion',
 'revdelete-edit-reasonlist' => 'Modifica le motivazion par la scancelazion',
@@ -1212,7 +1220,7 @@ Prova a métarghe \"all:\" davanti al testo che te serchi par vardar in tuti i n
 'prefs-rc' => 'Ultime modifeghe',
 'prefs-watchlist' => "Pàjine tegnùe d'ocio",
 'prefs-watchlist-days' => 'Nùmaro de giòrni da far védar nei osservati speciali:',
-'prefs-watchlist-days-max' => 'Masimo $1 ',
+'prefs-watchlist-days-max' => 'Masimo $1 {{PLURAL:$1|xorno|xorni}}',
 'prefs-watchlist-edits' => 'Nùmaro de modifiche da far védar con le funzion avanzade:',
 'prefs-watchlist-edits-max' => 'Numaro massimo: 1000',
 'prefs-watchlist-token' => "Segnal par le pagine tegnùe d'ocio:",
@@ -1257,7 +1265,7 @@ Prova a métarghe \"all:\" davanti al testo che te serchi par vardar in tuti i n
 'timezoneregion-indian' => 'Oceano Indian',
 'timezoneregion-pacific' => 'Oceano Pacifico',
 'allowemail' => 'Consenti la ricezion de e-mail da altri utenti<sup>1</sup>',
-'prefs-searchoptions' => 'Opsioni de riserca',
+'prefs-searchoptions' => 'Riserca',
 'prefs-namespaces' => 'Namespace',
 'defaultns' => 'Serca in sti namespace se no diversamente specificà:',
 'default' => 'predefinìo',
@@ -1270,9 +1278,9 @@ Sta operassion no la pol èssar anulà.',
 'prefs-emailconfirm-label' => "Conferma de l'e-mail:",
 'prefs-textboxsize' => 'Dimension de la casèla de modifica',
 'youremail' => 'La to e-mail',
-'username' => 'Nome utente',
-'uid' => 'ID utente:',
-'prefs-memberingroups' => 'Menbro {{PLURAL:$1|del grupo|dei grupi}}:',
+'username' => '{{GENDER:$1|Nome utente}}:',
+'uid' => '{{GENDER:$1|ID utente}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Menbro}} {{PLURAL:$1|del grupo|de i grupi}}:',
 'prefs-registration' => 'Data de registrassion:',
 'yourrealname' => 'El to vero nome:',
 'yourlanguage' => 'Lengua:',
@@ -1880,8 +1888,9 @@ Probabilmente te vui modifegar ła descrision prexente inte ła [$2 pàjina de d
 
 'disambiguations' => 'Pajine cołegade a pajine de dixanbiguasion',
 'disambiguationspage' => 'Template:Disambigua',
-'disambiguations-text' => "Le pagine ne la lista che segue le contien dei colegamenti a '''pagine de disanbiguazion''' e no a l'argomento a cui le dovarìà far riferimento.<br />
-Vien considerà pagine de disanbiguazion tute quele che contien i modèi elencà in [[MediaWiki:Disambiguationspage]]",
+'disambiguations-text' => "Łe pàjine inte ła lista cuà soto łe ga drento almanco un ligamento a na '''pàjina de dixanbiguasion'''.
+Łe podaria dover puntar a na pàjina pì apropià.<br />
+Vien considerae pàjine de dixanbiguasion tute cuełe che łe ga drento i modełi elencai in [[MediaWiki:Disambiguationspage]].",
 
 'doubleredirects' => 'Redirect dopi',
 'doubleredirectstext' => 'Sta pagina le elenca pagine che rimanda a altre pagine de rimando.
@@ -2033,9 +2042,9 @@ Varda anca le [[Special:WantedCategories|categorie domandà]].',
 'linksearch-pat' => 'Espression de riserca:',
 'linksearch-ns' => 'Namespace:',
 'linksearch-ok' => 'Serca',
-'linksearch-text' => 'Xe posibiłe doparare metacarateri, come "*.wikipedia.org".<br />
-Xe necesario almanco un dominio de primo liveło, tipo "*.org".<br />
-Protocołi suportadi: <code>$1</code> (no sta xontare nesuno de sti cuà inte ła to riçerca).',
+'linksearch-text' => 'Xe posibiłe doparare metacarateri, come "*.wikipedia.org".
+Xe nesesario almanco un dominio de primo liveło, tipo "*.org".<br />
+{{PLURAL:$2|Protocoło suportà|Protocołi suportai}}: <code>$1</code> (predefinio http:// se nisun protocoło el xe spesifegà).',
 'linksearch-line' => '$1 presente ne la pagina $2',
 'linksearch-error' => "I metacaràteri i pode vegner doparài solo a l'inizio del nome de l'host.",
 
@@ -2048,7 +2057,7 @@ Protocołi suportadi: <code>$1</code> (no sta xontare nesuno de sti cuà inte ł
 # Special:ActiveUsers
 'activeusers' => 'Lista dei utenti ativi',
 '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|canbiamento|canbiamenti}} {{PLURAL:$3|ne l'ultimo zorno|in tei ultimi $3 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',
@@ -2064,14 +2073,14 @@ Se pol consultar anca dele altre [[{{MediaWiki:Listgrouprights-helppage}}|inform
 'listgrouprights-rights' => 'Diriti',
 'listgrouprights-helppage' => 'Help:Diriti dei grupi',
 'listgrouprights-members' => '(Elenco de i menbri)',
-'listgrouprights-addgroup' => 'Pode zontar {{PLURAL:$2|al grupo|ai grupi}}: $1',
-'listgrouprights-removegroup' => 'Pode cavar {{PLURAL:$2|dal grupo|dai grupi}}: $1',
-'listgrouprights-addgroup-all' => 'Pode zontar tuti i grupi',
-'listgrouprights-removegroup-all' => 'Pode cavar tuti i grupi',
-'listgrouprights-addgroup-self' => 'Poder zontar la propria utensa in {{PLURAL:$2|te un grupo|più grupi}}: $1',
-'listgrouprights-removegroup-self' => 'Poder cavar la propria utensa da {{PLURAL:$2|un grupo|dei grupi}}: $1',
-'listgrouprights-addgroup-self-all' => 'Pode zontar la propria utensa in tuti i grupi',
-'listgrouprights-removegroup-self-all' => 'Pode cavar la propria utensa da tuti i grupi',
+'listgrouprights-addgroup' => 'Pol xontar {{PLURAL:$2|al grupo|ai grupi}}: $1',
+'listgrouprights-removegroup' => 'Pol cavar {{PLURAL:$2|dal grupo|dai grupi}}: $1',
+'listgrouprights-addgroup-all' => 'Pol xontar a tuti i grupi',
+'listgrouprights-removegroup-all' => 'Pol cavar da tuti i grupi',
+'listgrouprights-addgroup-self' => 'Pol xontarse {{PLURAL:$2|al grupo|ai grupi}}: $1',
+'listgrouprights-removegroup-self' => 'Pol cavarse da {{PLURAL:$2|un grupo|dei grupi}}: $1',
+'listgrouprights-addgroup-self-all' => 'Pol xontarse a tuti i grupi',
+'listgrouprights-removegroup-self-all' => 'Pol cavarse da tuti i grupi',
 
 # E-mail user
 'mailnologin' => 'Nissun indirizo a cui mandarghe el messagio',
@@ -2080,8 +2089,8 @@ Se pol consultar anca dele altre [[{{MediaWiki:Listgrouprights-helppage}}|inform
 'emailuser-title-target' => 'Scrivi na e-mail a {{GENDER:$1|sto|sta}} utente',
 'emailuser-title-notarget' => "Scrivi na e-mail a l'utente",
 'emailpage' => "Scrivi na e-mail a l'utente",
-'emailpagetext' => 'Te podi usar el modulo chi soto par mandare na e-mail a sto utente.
-La e-mail che te ghè indicà ne le [[Special:Preferences|to preferense]] la vegnarà fora nel canpo "Da" de la mail, così che el destinatario el possa rispóndarte a ti diretamente.',
+'emailpagetext' => 'Te podi usar el moduło chi soto par mandare na e-mail a sto {{GENDER:$1|utente}}.
+Ła e-mail che te ghè indicà inte łe [[Special:Preferences|to prefarense]] ła vegnarà fora inte\'l canpo "Da" de la mail, cusì che\'l destinatario el posa rispóndarte diretamente a ti.',
 'usermailererror' => "L'ogeto mail el gà restituìo l'eror:",
 'defemailsubject' => 'Mesajo da {{SITENAME}} dal utente "$1"',
 'usermaildisabled' => 'e-mail utente disabiłità',
@@ -2111,7 +2120,7 @@ La e-mail che te ghè indicà ne le [[Special:Preferences|to preferense]] la veg
 'usermessage-editor' => 'Messagero de sistema',
 
 # Watchlist
-'watchlist' => "Pagine tegnùe d'ocio",
+'watchlist' => "Pàjine tegnùe d'ocio",
 'mywatchlist' => "Pàjine tegnùe d'ocio",
 'watchlistfor2' => 'De $1 $2',
 'nowatchlist' => "No te ghè indicà pagine da tegner d'ocio.",
@@ -2119,8 +2128,8 @@ La e-mail che te ghè indicà ne le [[Special:Preferences|to preferense]] la veg
 'watchnologin' => 'Acesso mia efetuà',
 'watchnologintext' => 'Te ghè prima da far el [[Special:UserLogin|login]] par modificar la to lista de osservati speciali.',
 'addwatch' => "Tien d'ocio",
-'addedwatchtext' => "La pagina \"[[:\$1]]\" la xe stà zontà a la to [[Special:Watchlist|lista de pagine da tegner d'ocio]].
-I futuri canbiamenti a sta pagina e a la so pagina de discussion i se vedarà fora qua, e la pagina la se vedarà in '''grosso''' sui [[Special:RecentChanges|ultimi canbiamenti]] par tegnerla d'ocio mejo.",
+'addedwatchtext' => 'Ła pagina "[[:$1]]" ła xe stà xontà a ła to [[Special:Watchlist|lista de pàjine da tegner d\'ocio]].
+I futuri canbiamenti a sta pàjina e a ła so pàjina de discusion i vegnarà elencai in cheła pàjina là.',
 'removewatch' => "Cava da łe tegnùe d'ocio",
 'removedwatchtext' => 'La pagina "[[:$1]]" la xe stà cavà da le to [[Special:Watchlist|pagine tegnùe de ocio]].',
 'watch' => "Tien d'ocio",
@@ -2137,7 +2146,7 @@ I futuri canbiamenti a sta pagina e a la so pagina de discussion i se vedarà fo
 'watchmethod-list' => 'controło de i osservati speciałi par modifeghe recenti',
 'watchlistcontains' => 'La lista de i osservati speciałi la contien {{PLURAL:$1|una pagina|$1 pagine}}.',
 'iteminvalidname' => "Problemi con la voxe '$1', nome mìa vałido...",
-'wlnote' => "Qua soto te cati {{PLURAL:$1|l'ultimo canbiamento|i ultimi '''$1''' canbiamenti}} ne {{PLURAL:$2|l'ultima ora|le ultime '''$2''' ore}}.",
+'wlnote' => "Cuà soto te cati {{PLURAL:$1|'l ultimo canbiamento|i ultimi '''$1''' canbiamenti}} inte {{PLURAL:$2|l'ultema ora|łe ultime '''$2''' ore}}; i dati i xe axornai a łe $4 del $3.",
 'wlshowlast' => 'Mostra le ultime $1 ore $2 zorni $3',
 'watchlist-options' => "Inpostassion de le pagine tegnùe d'ocio",
 
@@ -2164,29 +2173,29 @@ I futuri canbiamenti a sta pagina e a la so pagina de discussion i se vedarà fo
 'enotif_anon_editor' => 'utente anonimo $1',
 'enotif_body' => 'Caro/a $WATCHINGUSERNAME,
 
-ła pàxena $PAGETITLE de {{SITENAME}} la xè stà $CHANGEDORCREATED el $PAGEEDITDATE da $PAGEEDITOR, varda $PAGETITLE_URL par ła version atuałe.
-
-$NEWPAGE
+$PAGEINTRO $NEWPAGE
 
-Somario del redator: $PAGESUMMARY $PAGEMINOREDIT
+Ogeto del intervento, inserio dal autor: $PAGESUMMARY $PAGEMINOREDIT
 
-Contatta el redator:
-mail: $PAGEEDITOR_EMAIL
-wiki: $PAGEEDITOR_WIKI
+Contata l\'autor:
+via posta eletronega: $PAGEEDITOR_EMAIL
+so\'l sito: $PAGEEDITOR_WIKI
 
-No ghe sarà altre notifiche in caso de ulteriori canbiamenti, a manco che ti no te visiti sta pàxena.
-Te podi anca reinpostar l\'avixo de notifica par tuti i osservati speciałi de ła to łista.
+Nó vegnarà inviae altre notifeghe in caxo de ulteriori atività, se nó te vixiti ła pàjina. Inoltre, xe posibiłe modifegar łe inpostasion de notifega par tute łe pàjine inte ła lista de łe tegnùe d\'ocio.
 
-             El to amichevole sistema de notifica de {{SITENAME}}
+             El sistema de notifega de {{SITENAME}}, al to servisio
 
 --
-Par canbiar łe inpostassion de i to osservati speciałi, visita
-{{canonicalurl:Special:Watchlist/edit}}
+Par modifegar łe inpostasion de łe notifeghe via posta eletronega, varda 
+{{canonicalurl:{{#special:Preferences}}}}
+
+Par modifegar ła lista de łe tegnùe d\'ocio, varda 
+{{canonicalurl:{{#special:EditWatchlist}}}}
 
-Par cavar la pagina da i to osservati speciałi, visita
+Par cavar ła pàjina da ła lista de łe tegnùe d\'ocio, varda
 $UNWATCHURL
 
-Par riscontri e ulteriore assistensa:
+Par comentare e risevere ajuto:
 {{canonicalurl:{{MediaWiki:Helppage}}}}',
 'created' => 'creà',
 'changed' => 'canbià',
@@ -2270,9 +2279,9 @@ Le inpostazion corenti par la pagina le xe '''$1''':",
 Le impostazion atuali par la pagina le xe '''$1''':",
 'protect-cascadeon' => 'Al momento sta pagina la xe blocà parché la xe inclusa {{PLURAL:$1|ne la pagina indicà de seguito, par la quale|ne le pagine indichè de seguito, par le quali}} xe ativa la protezion ricorsiva. Se pol modificar el livel de protezion individual de la pagina, ma le inpostazion derivanti da la protezion ricorsiva no le sarà mìa modificà.',
 'protect-default' => 'Autoriza tuti i utenti',
-'protect-fallback' => 'Ghe vole el parmesso de "$1"',
-'protect-level-autoconfirmed' => 'Bloca i utenti novi o mia registrà',
-'protect-level-sysop' => 'Solo aministradori',
+'protect-fallback' => 'Consentio soło che a i utenti có parmeso "$1"',
+'protect-level-autoconfirmed' => 'Consentio soło che a i utenti "autoconfermai"',
+'protect-level-sysop' => 'Consentio soło che a i aministradori',
 'protect-summary-cascade' => 'ricorsiva',
 'protect-expiring' => 'scadensa: $1 (UTC)',
 'protect-expiring-local' => 'scade el $1',
@@ -2317,8 +2326,8 @@ Le impostazion atuali par la pagina le xe '''$1''':",
 'undeletepagetext' => "{{PLURAL:$1|La pàxena qua de sèvito la xe stà scancelà, ma la ghe xe 'ncora in archivio e pertanto se pole 'ncora recuperarla|Le $1 pàxene qua de sèvito le xe stà scancelè, ma le ghe xe 'ncora in archivio e pertanto se pole 'ncora recuperarle}}.
 L'archivio el vien svodà periodicamente.",
 'undelete-fieldset-title' => 'Recupera version',
-'undeleteextrahelp' => "Par recuperar la storia de la pàxena par intiero, lassa tute łe casełe desełezionàe e struca '''''Ripristina'''''.
-Par efetuar un ripristino sełetivo, seleziona łe casełe corispondenti a łe revixion da ripristinar e struca '''''Ripristina'''''. Strucando '''''Reset''''' vegnarà deselezionàe tute łe casełe e svodà el posto par el comento.",
+'undeleteextrahelp' => "Par recuperar l'intiera storia de ła pàjina, łasar tute łe caxełe desełesionae e strucar so '''''{{int:undeletebtn}}'''''.
+Par efetuar un ripristino sełetivo, sełesionar łe caxełe corispondenti a łe revixion da ripristinar e strucar so '''''{{int:undeletebtn}}'''''.",
 'undeleterevisions' => '{{PLURAL:$1|Una revision|$1 revision}} in archivio',
 'undeletehistory' => 'Recuperando sta pàxena, tute łe so revixion le vegnarà inserìe da novo ne ła rełativa cronołogia.
 Se dopo ła scancełazion xè stà creà na nova pàxena col stesso titoło, łe revixion recuperà le sarà inserìe ne ła cronołogia preçedente.',
@@ -2336,7 +2345,8 @@ Se dopo ła scancełazion xè stà creà na nova pàxena col stesso titoło, łe
 'undeletedrevisions' => '{{PLURAL:$1|Una revision recuperà|$1 revision recuperà}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|Una revision|$1 revision}} e $2 file recuperà',
 'undeletedfiles' => '{{PLURAL:$1|Un file recuperà|$1 file recuperà}}',
-'cannotundelete' => "El recupero no'l xè riussìo: qualchedun altro el podarià aver xà recuperà ła pàxena.",
+'cannotundelete' => 'Ripristino nó riusìo:
+$1',
 'undeletedpage' => "'''$1 la xè stà recuperà'''
 
 Consulta el [[Special:Log/delete|registro de le scancełassion]] par vardare łe scancełassion e i recuperi pì reçenti.",
@@ -2558,18 +2568,18 @@ Tiente in mente de [[Special:UnlockDB|sblocarlo]] co te ghè finìo de far manut
 # Move page
 'move-page' => 'Spostamento de $1',
 'move-page-legend' => 'Spostamento de pagina',
-'movepagetext' => "Col modulo qua soto te podi rinominar na pagina, spostando anca tuta la so storia al titolo novo.
-El vecio titolo el deventarà automaticamente un rimando (redirect) che punta al titolo novo.
-Te podi agiornar automaticamente i rimandi che punta al vecio titolo.
-Se te siegli de no farlo, tiente in mente de controlar ben che no se crea [[Special:DoubleRedirects|dopi redirect]] o [[Special:BrokenRedirects|redirect interoti]].
-Resta ne la to responsabilità de controlar che i colegamenti i continua a puntar dove che i deve.
+'movepagetext' => "Có 'l moduło cuà soto te podi rinominar na pàjina, spostando anca tuta ła so storia al titoło novo.
+El vecio titoło el devegnarà automategamente un rimando (redirect) che ponta al titoło novo.
+Te podi axornar automategamente i rimandi che ponta al vecio titoło.
+Se te siełi de nó farlo, tiente inamente de controłar ben che nó se cree [[Special:DoubleRedirects|dopi rimandi]] o [[Special:BrokenRedirects|rimandi interoti]].
+Resta inte ła to responsabiłità de controłar che i ligamenti i continue a pontar 'ndove che i deve.
 
-Ocio: la pagina '''no''' la sarà spostà se ghe fusse zà na pagina col titolo novo, a meno che no la sia na pagina voda o un rimando, e senpre che no la gabia na storia.
-Questo significa che, se te fè un eror, te podi da novo rinominar na pagina col vecio titolo, ma no te podi sovrascrìvar na pagina zà esistente.
+Ocio: ła pàjina '''nó''' ła sarà spostà se ghe fuse xà na pàjina có 'l titoło novo, a meno che nó ła sia un rimando, e senpre che nó ła gabia na storia.
+Cuesto signifega che, se te fè un eror, te podi da novo rinominar na pàjina có 'l vecio titoło, ma nó te podi sovrascrìvar na pàjina xà existente.
 
 '''OCIO!'''
-Sto canbiamento drastico el podarìa dar problemi che no se se speta, specialmente se se trata de na pagina molto visità.
-Stà ben tento a le conseguense del spostamento, prima de farlo.",
+Sto canbiamento drastico el podarìa dar problemi che nó se se speta, spesalmente se se trata de na pàjina molto vixità.
+Stà ben tento a łe conseguense del spostamento, prima de farlo.",
 'movepagetext-noredirectfixer' => "Col modulo qua soto te podi rinominar na pagina, spostando anca tuta la so storia al titolo novo.
 El vecio titolo el deventarà automaticamente un rimando (redirect) che punta al titolo novo.
 Tiente in mente de controlar ben che no se crea [[Special:DoubleRedirects|dopi redirect]] o [[Special:BrokenRedirects|redirect interoti]].
@@ -3633,7 +3643,7 @@ Le imagini le vien mostrà a la risoluzion pi granda che se pol, par i altri tip
 'specialpages-group-highuse' => 'Pagine doparà assè',
 'specialpages-group-pages' => 'Liste de pagine',
 'specialpages-group-pagetools' => 'Strumenti par le pagine',
-'specialpages-group-wiki' => 'Dati e strumenti wiki',
+'specialpages-group-wiki' => "Strumenti e informasion so'l projeto",
 'specialpages-group-redirects' => 'Pagine speciali de rimando',
 'specialpages-group-spam' => 'Strumenti anti spam',
 
@@ -3729,9 +3739,9 @@ Le imagini le vien mostrà a la risoluzion pi granda che se pol, par i altri tip
 'logentry-patrol-patrol-auto' => '$1 ga segnà automategamente la revixion $4 de la pajina $3 come verifegà',
 'logentry-newusers-newusers' => "L'utensa $1 xe sta creà",
 'logentry-newusers-create' => "L'utensa $1 xe sta creà",
-'logentry-newusers-create2' => 'Lutensa $3 xe sta creà da $1',
+'logentry-newusers-create2' => "L'utensa $3 xe sta creà da $1",
+'logentry-newusers-byemail' => "L'utensa $3 xe sta creà da $1 e ła password ła xe sta invià via e-mail",
 'logentry-newusers-autocreate' => "L'utensa $1 xè stà creà automategamente",
-'newuserlog-byemail' => 'password spedìa par e-mail',
 'logentry-rights-rights' => "$1 ga canbià l'apartenensa de $3 dal grupo $4 al grupo $5",
 'logentry-rights-rights-legacy' => "$1 ga canbià l'apartenensa a grupi de $3",
 'logentry-rights-autopromote' => '$1 xe stà automategamente promoso/a da $4 a $5',
@@ -3788,6 +3798,7 @@ Le imagini le vien mostrà a la risoluzion pi granda che se pol, par i altri tip
 'api-error-ok-but-empty' => 'Eror interno: nisuna risposta dal server.',
 'api-error-overwrite' => 'Nó xe parmeso de sorascrìvar un file existente.',
 'api-error-stashfailed' => "Eror interno: el server nó 'l xe riusio a memorixar el documento tenporaneo.",
+'api-error-publishfailed' => "Eror interno: el server nó 'l xe riusio a publicar el documento tenporaneo.",
 'api-error-timeout' => "El server nó 'l ga risposto entro el tenpo previsto.",
 'api-error-unclassified' => 'Se gà verifegà un eror sconosùo.',
 'api-error-unknown-code' => 'Eror sconosùo: "$1"',
index 3980a0a..d5a2d69 100644 (file)
@@ -3057,7 +3057,6 @@ Kävutagat normaline ezikacund.',
 # New logging system
 'revdelete-restricted' => 'kaidendused administratoriden täht',
 'revdelete-unrestricted' => 'kaidendused heittud administratoriden täht',
-'newuserlog-byemail' => 'peisana om oigetud e-počtadme',
 'rightsnone' => '(ei ole)',
 
 # Feedback
index 30d17aa..eb32c04 100644 (file)
@@ -61,7 +61,7 @@ $specialPageAliases = array(
        'Ancientpages'              => array( 'Trang_cũ' ),
        'Badtitle'                  => array( 'Tựa_đề_hỏng' ),
        'Blankpage'                 => array( 'Trang_trắng' ),
-       'Block'                     => array( 'Cấm_IP' ),
+       'Block'                     => array( 'Cấm', 'Cấm_IP', 'Cấm_thành_viên', 'Cấm_người_dùng' ),
        'Blockme'                   => array( 'Khóa_tôi', 'Khoá_tôi' ),
        'Booksources'               => array( 'Nguồn_sách' ),
        'BrokenRedirects'           => array( 'Đổi_hướng_sai' ),
@@ -211,14 +211,17 @@ $magicWords = array(
        'img_page'                  => array( '1', 'trang=$1', 'trang $1', 'page=$1', 'page $1' ),
        'img_upright'               => array( '1', 'đứng', 'đứng=$1', 'đứng $1', 'upright', 'upright=$1', 'upright $1' ),
        'img_link'                  => array( '1', 'liên_kết=$1', 'link=$1' ),
+       'img_class'                 => array( '1', 'lớp=$1', 'class=$1' ),
        'int'                       => array( '0', 'NỘI:', 'INT:' ),
        'sitename'                  => array( '1', 'TÊNMẠNG', 'SITENAME' ),
        'ns'                        => array( '0', 'KGT:', 'NS:' ),
        'localurl'                  => array( '0', 'URLĐỊAPHƯƠNG:', 'LOCALURL:' ),
-       'articlepath'               => array( '0', 'LỐIBÀI', 'ARTICLEPATH' ),
+       'articlepath'               => array( '0', 'ĐƯỜNGDẪNBÀI', 'LỐIBÀI', 'ARTICLEPATH' ),
+       'pageid'                    => array( '0', 'IDTRANG', 'PAGEID' ),
        'server'                    => array( '0', 'MÁYCHỦ', 'SERVER' ),
        'servername'                => array( '0', 'TÊNMÁYCHỦ', 'SERVERNAME' ),
-       'scriptpath'                => array( '0', 'ĐƯỜNGDẪNSCRIPT', 'SCRIPTPATH' ),
+       'scriptpath'                => array( '0', 'ĐƯỜNGDẪNKỊCHBẢN', 'ĐƯỜNGDẪNSCRIPT', 'SCRIPTPATH' ),
+       'stylepath'                 => array( '0', 'ĐƯỜNGDẪNKIỂU', 'STYLEPATH' ),
        'grammar'                   => array( '0', 'NGỮPHÁP:', 'GRAMMAR:' ),
        'gender'                    => array( '0', 'GIỐNG:', 'GENDER:' ),
        'notitleconvert'            => array( '0', '__KHÔNGCHUYỂNTÊN__', '__NOTITLECONVERT__', '__NOTC__' ),
@@ -251,7 +254,9 @@ $magicWords = array(
        'pagesize'                  => array( '1', 'CỠTRANG', 'PAGESIZE' ),
        'numberingroup'             => array( '1', 'CỠNHÓM', 'NUMBERINGROUP', 'NUMINGROUP' ),
        'staticredirect'            => array( '1', '__ĐỔIHƯỚNGNHẤTĐỊNH__', '__STATICREDIRECT__' ),
+       'protectionlevel'           => array( '1', 'MỨCKHÓA', 'MỨCKHOÁ', 'PROTECTIONLEVEL' ),
        'url_path'                  => array( '0', 'ĐƯỜNGDẪN', 'PATH' ),
+       'url_query'                 => array( '0', 'TRUYVẤN', 'QUERY' ),
 );
 
 $datePreferences = array(
@@ -727,7 +732,7 @@ Hãy nhớ thay đổi [[Special:Preferences|tùy chọn cá nhân {{SITENAME}}]
 'gotaccount' => "Đã mở tài khoản rồi? '''$1'''.",
 'gotaccountlink' => 'Đăng nhập',
 'userlogin-resetlink' => 'Quên mất thông tin đăng nhập?',
-'createaccountmail' => 'qua thư điện tử',
+'createaccountmail' => 'Sử dụng mật khẩu ngẫu nhiên tạm và gửi nó cho địa chỉ thư điện tử được chỉ định ở dưới',
 'createaccountreason' => 'Lý do:',
 'badretype' => 'Hai mật khẩu không khớp.',
 'userexists' => 'Tên người dùng được nhập đã có người lấy.
@@ -1118,9 +1123,8 @@ Lý do được $3 đưa ra là ''$2''",
 'last' => 'trước',
 'page_first' => 'đầu',
 'page_last' => 'cuối',
-'histlegend' => 'Chọn so sánh: đánh dấu để chọn các phiên bản để so sánh rồi nhấn enter hoặc nút ở dưới.<br />
-Chú giải: (hiện) = khác với phiên bản hiện hành,
-(trước) = khác với phiên bản trước, n = sửa đổi nhỏ.',
+'histlegend' => "Chọn so sánh: Đánh dấu để chọn các phiên bản để so sánh rồi nhấn Enter hoặc nút ở dưới.<br />
+Chú giải: '''({{int:cur}})''' = khác với phiên bản hiện hành, '''({{int:last}})''' = khác với phiên bản trước, '''{{int:minoreditletter}}''' = sửa đổi nhỏ.",
 'history-fieldset-title' => 'Tìm trong lịch sử',
 'history-show-deleted' => 'Chỉ bị xóa',
 'histfirst' => 'Cũ nhất',
@@ -1325,7 +1329,7 @@ Xem chi tiết trong [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'search-interwiki-default' => '$1 kết quả:',
 'search-interwiki-more' => '(thêm)',
 'search-relatedarticle' => 'Liên quan',
-'mwsuggest-disable' => 'Tắt gợi ý bằng AJAX',
+'mwsuggest-disable' => 'Tắt gợi ý tìm kiếm',
 'searcheverything-enable' => 'Tìm trong tất cả không gian tên',
 'searchrelated' => 'có liên quan',
 'searchall' => 'tất cả',
@@ -2228,7 +2232,7 @@ Xem thêm [[Special:WantedCategories|thể loại cần thiết]].',
 # Special:ActiveUsers
 'activeusers' => 'Danh sách thành viên tích cực',
 '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 {{PLURAL:$1|sửa đổi|sửa đổi}} trong {{PLURAL:$3|ngày|$3 ngày}} gần đây',
+'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',
@@ -2291,7 +2295,7 @@ Có [[{{MediaWiki:Listgrouprights-helppage}}|thông tin thêm]] về từng nhó
 'usermessage-editor' => 'Trình thông báo hệ thống',
 
 # Watchlist
-'watchlist' => 'Trang tôi theo dõi',
+'watchlist' => 'Danh sách theo dõi',
 'mywatchlist' => 'Trang theo dõi',
 'watchlistfor2' => 'Của $1 $2',
 'nowatchlist' => 'Danh sách theo dõi của bạn không có gì.',
@@ -2333,7 +2337,7 @@ Những sửa đổi đối với trang này và trang thảo luận của nó s
 'enotif_subject_created' => 'Trang $1 tại {{SITENAME}} đã được tạo ra bởi $2.',
 'enotif_subject_moved' => 'Trang $1 tại {{SITENAME}} đã được di chuyển bởi $2.',
 'enotif_subject_restored' => 'Trang $1 tại {{SITENAME}} đã được phục hồi bởi $2.',
-'enotif_subject_changed' => 'Trang $1 tại {{SITENAME}} đã được thay đổi bởi $2.',
+'enotif_subject_changed' => 'Trang $1 tại {{SITENAME}} đã được thay đổi bởi $2',
 'enotif_body_intro_deleted' => 'Trang $1 tại {{SITENAME}} đã được $2 xóa vào $PAGEEDITDATE. Xem $3 .',
 'enotif_body_intro_created' => 'Trang $1 tại {{SITENAME}} đã được $2 tạo ra vào $PAGEEDITDATE. Xem phiên bản hiện hành tại $3 .',
 'enotif_body_intro_moved' => 'Trang $1 tại {{SITENAME}} đã được $2 di chuyển vào $PAGEEDITDATE. Xem phiên bản hiện hành tại $3 .',
@@ -2756,7 +2760,7 @@ Bạn có thể cập nhật tự động các trang đổi hướng đến tên
 Nếu bạn chọn không cập nhật, hãy nhớ kiểm tra [[Special:DoubleRedirects|đổi hướng kép]] hoặc [[Special:BrokenRedirects|đổi hướng đến trang không tồn tại]].
 Bạn phải chịu trách nhiệm đảm bảo các liên kết đó tiếp tục trỏ đến nơi chúng cần đến.
 
-Chú ý rằng trang sẽ '''không''' bị di chuyển nếu đã có một trang tại tên mới, trừ khi nó rỗng hoặc là trang đổi hướng và không có lịch sử sửa đổi trước đây.
+Chú ý rằng trang sẽ '''không''' bị di chuyển nếu đã có một trang tại tên mới, trừ khi trang tại tên mới là trang đổi hướng và không có lịch sử sửa đổi trước đây.
 Điều này có nghĩa là bạn có thể đổi tên trang lại như cũ nếu bạn có nhầm lẫn, và bạn không thể ghi đè lên một trang đã có sẵn.
 
 '''CẢNH BÁO!'''
@@ -3106,6 +3110,7 @@ Lưu nó vào máy tính của bạn rồi tải nó lên đây.',
 'pageinfo-robot-noindex' => 'Không thể ghi chỉ mục',
 'pageinfo-views' => 'Số lần xem',
 'pageinfo-watchers' => 'Số người theo dõi trang',
+'pageinfo-few-watchers' => 'Không tới $1 người theo dõi',
 'pageinfo-redirects-name' => 'Số trang đổi hướng đến trang này',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Số trang con của trang này',
@@ -3389,7 +3394,7 @@ Những thông tin khác mặc định sẽ được ẩn đi.
 'exif-gpslongituderef' => 'Kinh độ đông hay tây',
 'exif-gpslongitude' => 'Kinh độ',
 'exif-gpsaltituderef' => 'Tham chiếu cao độ',
-'exif-gpsaltitude' => 'Độ cao',
+'exif-gpsaltitude' => 'Cao độ',
 'exif-gpstimestamp' => 'Giờ GPS (đồng hồ nguyên tử)',
 'exif-gpssatellites' => 'Vệ tinh nhân tạo dùng để đo',
 'exif-gpsstatus' => 'Tình trạng đầu thu',
@@ -3997,7 +4002,7 @@ Các hình ảnh được hiển thị ở kích thước tối đa, còn các l
 'specialpages-group-highuse' => 'Trang được dùng nhiều',
 'specialpages-group-pages' => 'Danh sách các trang',
 'specialpages-group-pagetools' => 'Công cụ cho trang',
-'specialpages-group-wiki' => 'Dữ liệu và công cụ cho wiki',
+'specialpages-group-wiki' => 'Dữ liệu và công cụ',
 'specialpages-group-redirects' => 'Đang đổi hướng trang đặc biệt',
 'specialpages-group-spam' => 'Công cụ chống spam',
 
@@ -4094,8 +4099,8 @@ Các hình ảnh được hiển thị ở kích thước tối đa, còn các l
 'logentry-newusers-newusers' => 'Đã mở tài khoản người dùng $1',
 'logentry-newusers-create' => 'Đã mở tài khoản người dùng $1',
 'logentry-newusers-create2' => '$1 đã mở tài khoản người dùng $3',
+'logentry-newusers-byemail' => '$1 đã mở tài khoản người dùng $3 và nhận mật khẩu qua thư điện tử',
 'logentry-newusers-autocreate' => 'Tài khoản $1 đã được mở tự động',
-'newuserlog-byemail' => 'gửi mật khẩu qua thư điện tử',
 'logentry-rights-rights' => '$1 đã đổi các nhóm liên kết của $3 từ $4 đến $5',
 'logentry-rights-rights-legacy' => '$1 đã đổi các nhóm liên kết của $3',
 'logentry-rights-autopromote' => '$1 đã được tự động phong cấp từ $4 đến $5',
@@ -4153,6 +4158,7 @@ Nếu không thì bạn có thể điền biểu mẫu đơn giản ở dưới.
 'api-error-ok-but-empty' => 'Lỗi nội bộ: Máy chủ không phản hồi.',
 'api-error-overwrite' => 'Không được ghi đè một tập tin đã tồn tại.',
 'api-error-stashfailed' => 'Lỗi nội bộ: Máy chủ bị thất bại trong việc lưu giữ tập tin tạm.',
+'api-error-publishfailed' => 'Lỗi nội bộ: Máy chủ bị thất bại trong việc xuất bản tập tin tạm.',
 'api-error-timeout' => 'Máy chủ không đáp ứng trong thời gian dự kiến.',
 'api-error-unclassified' => 'Gặp lỗi không ngờ',
 'api-error-unknown-code' => 'Lỗi không rõ: “$1”',
index b6774ea..fcc9b8b 100644 (file)
@@ -357,6 +357,9 @@ $messages = array(
 'youhavenewmessages' => 'Su pad ola binons $1 ($2).',
 'newmessageslink' => 'nuns nulik',
 'newmessagesdifflink' => 'votükam lätik',
+'youhavenewmessagesfromusers' => 'Labol $1 de {{PLURAL:$3|geban votik|gebans $3}} ($2).',
+'youhavenewmessagesmanyusers' => 'Labol $1 de gebans mödik ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|nuni nulik|nunis nulik}}',
 'youhavenewmessagesmulti' => 'Labol nunis nulik su $1',
 'editsection' => 'redakön',
 'editold' => 'redakön',
@@ -2809,7 +2812,6 @@ Magods pajonons ma fomät gudikün, ragivasots votik pamaifükons stedöfo kobü
 # New logging system
 'revdelete-restricted' => 'miedükams pelonöfükons pro guvans',
 'revdelete-unrestricted' => 'miedükams pro guvans pemoükons',
-'newuserlog-byemail' => 'letavöd pesedon me pot leäktronik',
 'rightsnone' => '(nonik)',
 
 # Search suggestions
index 895d82e..6ca447b 100644 (file)
@@ -609,7 +609,7 @@ Seness [$2 kuvauhsõ lehocülless] informaattsija on alapallõ annõttu.',
 'emailmessage' => 'Ilmottamin:',
 
 # Watchlist
-'watchlist' => 'Minu kattsõspiiska',
+'watchlist' => 'Kattsõspiiska',
 'mywatchlist' => 'Minu kattsõspiiska',
 'watchlistfor2' => '$2 - $1 vart',
 'addedwatchtext' => "Cülci \"[[:\$1]]\" on lisättü Teďďee [[Special:Watchlist|kattsospiizgallõ]].
index 3ba9d00..c1a3c61 100644 (file)
@@ -2339,7 +2339,6 @@ Acertinez s' i vs plait ki vos vloz vormint rifé cisse pådje ci.",
 'logentry-newusers-create' => "$1 a-st ahivé on conte d' uzeu",
 'logentry-newusers-create2' => "$1 a-st ahivé on conte d' uzeu $3",
 'logentry-newusers-autocreate' => 'li conte $1 a stî ahivé otomaticmint',
-'newuserlog-byemail' => "emilaedje d' on scret",
 'rightsnone' => '(nouk)',
 
 # Feedback
index 2d9185d..766b3e5 100644 (file)
@@ -112,7 +112,7 @@ $messages = array(
 
 'underline-always' => 'Pirme',
 'underline-never' => 'Diri',
-'underline-default' => 'An aada-nga-daan nga panngaykayan',
+'underline-default' => 'An panmutos o pandalikyat nga aada-nga-daan',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Estilo hin font ha lugar hin pagliwat',
@@ -199,8 +199,9 @@ $messages = array(
 'newwindow' => '(nabuklad hin bag-o nga tamboan o bintana)',
 'cancel' => 'Pasagdi',
 'moredotdotdot' => 'Damo pa nga…',
-'mypage' => 'Akon pakli',
-'mytalk' => 'Akon paghingay',
+'morenotlisted' => 'Damo pa nga waray gintalaan...',
+'mypage' => 'Pakli',
+'mytalk' => 'Mga akon paghingay',
 'anontalk' => 'Paghingay para hini nga IP',
 'navigation' => 'Paglayag',
 'and' => '&#32;ngan',
@@ -440,7 +441,7 @@ Kweri: $2',
 'actionthrottled' => 'Ginpahinay an ginbuhat',
 'actionthrottledtext' => 'Komo uska pangontra ha spam, ikaw in ginlilimitaran paghimo hini nga pagbuhat hin sobra kadamo ha sulod hin gutiay nga oras, ngan ikaw in naglapos hini nga katubtuban.
 Alayon pagutro kahuman hin pipira ka mga minuto.',
-'protectedpagetext' => 'Ini nga pakli in pinasaliporan para mapugngan an mga pagliwat.',
+'protectedpagetext' => 'Ginpanalipdan ini nga pakli basi mapugngan an pagliwat o iba pa nga mga maburuhat.',
 'viewsourcetext' => 'Puydi ka kinmita ngan kinmopya han gintikangan han pakli:',
 'viewyourtext' => "Puydi nim makit-an ngan makopya an tinikangan han '''imo mga pagliwat''' ha dinhi nga pakli:",
 'protectedinterface' => 'Ini nga pakli in nahatag hin teksto hit interface para han software han hin nga wiki, ngan in pinasasaliporan para makalikay hit pag-abuso.
@@ -464,6 +465,7 @@ An magdudurmara nga nagtrangka hini in naghatag hini nga eksplenasyon: "$3".',
 'virus-unknownscanner' => 'diri-nasasabtan nga antivirus:',
 
 # Login and logout pages
+'welcomeuser' => '¡Uswag ngan Dayon, $1!',
 'yourname' => 'Agnay hit gumaramit:',
 'yourpassword' => 'Tigaman-pagsulod:',
 'yourpasswordagain' => 'Utroha pagbutang an tigaman-han-pagsakob:',
@@ -485,7 +487,7 @@ An magdudurmara nga nagtrangka hini in naghatag hini nga eksplenasyon: "$3".',
 'gotaccount' => '¿Mayda kana akawnt? $1.',
 'gotaccountlink' => 'Sakob',
 'userlogin-resetlink' => 'Nangalimot han imo detalye han pagsakob?',
-'createaccountmail' => 'Ha e-mail',
+'createaccountmail' => 'Gamiti hin temporaryo nga bisan ano nag password ngan igpadangat ngada ha e-mail address nga nakasurat ha ubos',
 'createaccountreason' => 'Rason:',
 'badretype' => 'Diri naangay an mga tigaman-pagsulod nga im ginbutang',
 'userexists' => 'An agnay hiton gumaramit nga im ginbutang in gingamit na.
@@ -514,6 +516,11 @@ Alayon pagutro pagbutang.',
 'passwordremindertitle' => 'Bag-o nga diri-pirmihan nga tigaman-pagsulod para han {{SITENAME}}',
 'noemail' => 'Waray e-mail nga adres nga ginrekord para han nágámit "$1".',
 'noemailcreate' => 'Kinahanglan nim maghatag hin may hinungdan nga e-mail address',
+'passwordsent' => 'Uska bag-o nga password in ginpadangat ha e-mail address nga nakarehistro kan "$1".
+Alayon paglog-in utro kahuman mo makarawat ini.',
+'blocked-mailpassword' => 'An imo IP address in ginpugong ha pag-edit, ngan tungod hini in diri gintutugotan paggamit han password recovery function para malikyan an abuso.',
+'eauthentsent' => 'Uska kompirmasyon nga e-mail in ginpadangan ha gin-ngaranan nga e-mail address.
+San-o matagan pa hin iba nga e-mail para ha imo akawnt, kinahanglan mo sundon an mga surundan nga nakasurat ha e-mail, para makompirma nga imo gud ito akawnt.',
 'mailerror' => 'Sayop han pagpadangat hin surat: $1',
 'emailauthenticated' => 'Ginpamatuod an imo e-mail adres han $2 ha $3.',
 'emailconfirmlink' => 'Igkompirma an imo e-mail address',
@@ -534,6 +541,7 @@ Alayon pagutro pagbutang.',
 'oldpassword' => 'Daan nga tigaman-pagsulod:',
 'newpassword' => 'Bag-o nga tigaman-pagsulod:',
 'retypenew' => 'Utroha pagbutang an bag-o nga tigaman-pagsulod:',
+'resetpass_submit' => 'Igbutang an password ngan log in',
 'resetpass_success' => 'Malinamposon nga nasalyuan na an imo tigaman-pagsulod!
 Ikaw in naglalog-in yana...',
 'resetpass_forbidden' => 'Diri mababalyoan an mga tigaman-pagsulod',
@@ -628,7 +636,7 @@ o <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}
 'note' => "'''Pahibaro:'''",
 'previewnote' => "'''Hinumdumi nga pahiuna-nga-paggawas pa la ini.'''
 ¡Waray pa katipig an imo mga ginbag-o!",
-'continue-editing' => 'Padayon pagliwat',
+'continue-editing' => 'Pakadto han lugar hin panliwat',
 'editing' => 'Ginliliwat an $1',
 'creating' => 'Ginhihimo an $1',
 'editingsection' => 'Ginliliwat an $1 (bahin)',
@@ -662,6 +670,7 @@ An taramdan han pagpara ngan pagbalhin para han pakli in ginhahatag ha ubos para
 'edit-already-exists' => 'Diri nakakahimo hin bag-o nga pakli.
 Aada na ito.',
 'defaultmessagetext' => 'Aada-nga-daan nga teksto han mensahe',
+'invalid-content-data' => 'Sayop nga sulod nga datos',
 'content-not-allowed-here' => 'An sulod nga "$1" in diri gintutugotan ha pakli nga [[$2]]',
 
 # Content models
@@ -720,6 +729,7 @@ Leyenda: '''({{int:cur}})''' = kaibhan ha giuurhii nga pag-bag-o, '''({{int:last
 'rev-showdeleted' => 'igpakita',
 'revisiondelete' => 'Pagpara/pagtanggal han pagpara nga mga rebisyon',
 'revdelete-nologtype-title' => 'Waray ginhatag nga klase hit talaan',
+'revdelete-nologid-title' => 'Sayop nga log entry',
 'revdelete-show-file-confirm' => 'Sigurado ka nga gusto mo makita an ginpara nga pagliwat han file "<nowiki>$1</nowiki>" tikang $2 ha $3?',
 'revdelete-show-file-submit' => 'Oo',
 'revdelete-hide-text' => 'Tagoon an rebisyon han teksto',
@@ -829,7 +839,7 @@ Ginpapasabot nga an sulod han mga panudlok han {{SITENAME}} in bangin daan an.',
 
 # Preferences page
 'preferences' => 'Mga karuyag',
-'mypreferences' => 'Akon mga karuyag',
+'mypreferences' => 'Mga akon karuyag',
 'prefs-edits' => 'Ihap han mga pagliwat:',
 'prefsnologin' => 'Diri nakalog-in',
 'changepassword' => 'Igliwan an tigaman-pagsulod',
@@ -1390,8 +1400,8 @@ An paglaladawan han iya [$2 fayl han paglaladawan nga pakli] didto in ginpapakit
 'usermessage-editor' => 'Mensahero han sistema',
 
 # Watchlist
-'watchlist' => 'Akon barantayan',
-'mywatchlist' => 'Akon angay timan-an',
+'watchlist' => 'Barantayan',
+'mywatchlist' => 'Mga angay timan-an nakon',
 'watchlistfor2' => 'Para ha $1 $2',
 'watchnologin' => 'Diri nakalog-in',
 'watch' => 'Bantayi',
@@ -1480,9 +1490,9 @@ $1',
 'blanknamespace' => '(Panguna)',
 
 # Contributions
-'contributions' => 'Mga amot han gumaramit',
+'contributions' => 'Mga ámot ni {{GENDER:$1|User}}',
 'contributions-title' => 'Mga amot han gumaramit para ha $1',
-'mycontris' => 'Akon mga ámot',
+'mycontris' => 'Mga ámot nakon',
 'contribsub2' => 'Para ha $1 $2',
 'uctop' => '(bawbaw)',
 'month' => 'Tikang ha bulan (ngan uruunhan):',
@@ -1514,7 +1524,7 @@ $1',
 'whatlinkshere-hideredirs' => '$1 nga mga redirek',
 'whatlinkshere-hidetrans' => '$1 nga mga transklusyon',
 'whatlinkshere-hidelinks' => '$1 an mga sumpay',
-'whatlinkshere-hideimages' => '$1 sumpay hin hulagway',
+'whatlinkshere-hideimages' => '$1 an mga sumpay han paypay',
 'whatlinkshere-filters' => 'Mga panara',
 
 # Block/unblock
@@ -2203,7 +2213,6 @@ An iba in daan nakatago.
 'logentry-newusers-create' => '$1 in naghimo hin gumaramit nga akawnt',
 'logentry-newusers-create2' => '$1 in naghimo hin gumaramit nga akawnt $3',
 'logentry-newusers-autocreate' => 'An akawnt nga $1 in lugaring nga nahimo',
-'newuserlog-byemail' => 'Ginpadangat an tigaman-pagsulod pinaagi han e-mail',
 'rightsnone' => '(waray)',
 
 # Feedback
index 192fc84..a4b0680 100644 (file)
@@ -2198,7 +2198,6 @@ Man nga tamit  [[Special:EditWatchlist/raw|soppi ko]].',
 # New logging system
 'revdelete-restricted' => 'doxalub digal ngir yorkat yi',
 'revdelete-unrestricted' => 'digal ngir yorkat yi deñ na',
-'newuserlog-byemail' => 'baatujáll bi yónne nañu ko cib bataaxal',
 'rightsnone' => '(menn)',
 
 );
index b11e2d0..8a21cc4 100644 (file)
@@ -147,8 +147,12 @@ $magicWords = array(
        'toc'                       => array( '0', '__אינהאלט__', '__תוכן_עניינים__', '__תוכן__', '__TOC__' ),
        'noeditsection'             => array( '0', '__נישט_רעדאקטירן__', '__ללא_עריכה__', '__NOEDITSECTION__' ),
        'currentday'                => array( '1', 'לויפיקער_טאג', 'יום נוכחי', 'CURRENTDAY' ),
+       'currentyear'               => array( '1', 'לויפֿיקע_יאָר', 'שנה נוכחית', 'CURRENTYEAR' ),
+       'currenttime'               => array( '1', 'לויפֿיקע_צײַט', 'שעה נוכחית', 'CURRENTTIME' ),
        'numberofpages'             => array( '1', 'צאל_בלעטער', 'מספר דפים כולל', 'מספר דפים', 'NUMBEROFPAGES' ),
        'numberofarticles'          => array( '1', 'צאל_ארטיקלען', 'מספר ערכים', 'NUMBEROFARTICLES' ),
+       'numberoffiles'             => array( '1', 'צאל_טעקעס', 'מספר קבצים', 'NUMBEROFFILES' ),
+       'numberofusers'             => array( '1', 'צאל_באניצער', 'מספר משתמשים', 'NUMBEROFUSERS' ),
        'pagename'                  => array( '1', 'בלאטנאמען', 'שם הדף', 'PAGENAME' ),
        'namespace'                 => array( '1', 'נאמענטייל', 'מרחב השם', 'NAMESPACE' ),
        'fullpagename'              => array( '1', 'פולבלאטנאמען', 'שם הדף המלא', 'FULLPAGENAME' ),
@@ -160,8 +164,10 @@ $magicWords = array(
        'img_right'                 => array( '1', 'רעכטס', 'ימין', 'right' ),
        'img_left'                  => array( '1', 'לינקס', 'שמאל', 'left' ),
        'img_none'                  => array( '1', 'אן', 'ללא', 'none' ),
+       'img_width'                 => array( '1', '$1פיקס', '$1 פיקסלים', '$1px' ),
        'img_center'                => array( '1', 'צענטער', 'מרכז', 'center', 'centre' ),
        'img_sub'                   => array( '1', 'אונטער', 'תחתי', 'sub' ),
+       'img_super'                 => array( '1', 'איבער', 'עילי', 'super', 'sup' ),
        'img_top'                   => array( '1', 'אויבן', 'למעלה', 'top' ),
        'img_bottom'                => array( '1', 'אונטן', 'למטה', 'bottom' ),
        'img_link'                  => array( '1', 'לינק=$1', 'קישור=$1', 'link=$1' ),
@@ -269,7 +275,7 @@ $messages = array(
 'january-gen' => 'יאנואר',
 'february-gen' => 'פעברואר',
 'march-gen' => 'מערץ',
-'april-gen' => 'אפריל',
+'april-gen' => 'אַפּריל',
 'may-gen' => 'מיי',
 'june-gen' => 'יוני',
 'july-gen' => 'יולי',
@@ -620,7 +626,7 @@ $2',
 'gotaccount' => "האסטו שוין א קאנטע? '''$1'''.",
 'gotaccountlink' => 'אַרײַנלאגירן',
 'userlogin-resetlink' => 'פארגעסן אײַערע אַרײַנלאָגירן פרטים?',
-'createaccountmail' => '×\93×\95ר×\9a ×¢-פ×\90ס×\98',
+'createaccountmail' => '× ×\99צ×\9f ×\90 ×¤×¨×\90×\95×\95×\99×\96×\90ר×\99ש ×¤×\90ס×\95×\95×\90ר×\98 ×\90×\95×\9f ×©×\99ק×\9f ×¦×\95×\9d ×¢-פ×\90ס×\98 ×\90×\93רעס ×\92עצ×\99×\99×\9b× ×\98 ×\90×\95× ×\98×\9f',
 'createaccountreason' => 'אורזאַך:',
 'badretype' => 'די פאסווערטער וואס איר האט אריינגעלייגט זענען נישט אייניג.',
 'userexists' => 'דער באַניצער נאָמען איז שוין געניצט. 
@@ -697,6 +703,7 @@ $2',
 # E-mail sending
 'php-mail-error-unknown' => 'אומבאַקאַנט טעות אין()mail פֿונקציע פֿון PHP.',
 'user-mail-no-addy' => 'געפרוווט צו שיקן ע-פּאָסט אָן אַן ע-פּאָסט אַדרעס.',
+'user-mail-no-body' => 'האט פרובירט צו שיקן א בליצבריוו וואס זיין אינהאלט איז ליידיק אדער גאר קורץ.',
 
 # Change password dialog
 'resetpass' => 'ענדערן קאנטע פאסווארט',
@@ -927,8 +934,8 @@ $2
 '''זיכט נישט באניצן מיט שטאף וואס איז באשיצט מיט קאפירעכטן!'''",
 'longpageerror' => "'''פעלער: דער טעקסט וואס איר האט ארײַנגעשטעלט איז לאנג {{PLURAL:$1|איין קילאבייט|$1 קילאבייטן}}, וואס איז לענגער פון דעם מאקסימום פון {{PLURAL:$2|איין קילאבייט|$2 קילאבייטן}}. 
 ער קען נישט ווערן אפגעהיטן.'''",
-'readonlywarning' => "'''×\95×\95×\90רענ×\95× ×\92: ×\93×\99 ×\93×\90×\98×¢×\91×\90×\96×¢ ×\90×\99×\96 ×\92×¢×\95×\95×\90ר×\9f ×¤×\90רש×\9c×\90ס×\9f ×¤×\90ר ×¡×\99×\99×\98 ×\90×\95×\99פ×\94×\90×\9c×\98×\95× ×\92,
\9e×\9e×\99×\9c×\90 ×\95×\95×¢×\98 ×\90×\99ר × ×\99ש×\98 ×§×¢× ×¢×\9f ×\90פ×\94×\99×\98×\9f ×\90×\99×\99ערע ×¢× ×\93ער×\95× ×\92×¢×\9f ×\90צ×\99× ×\93. ×\90×\99ר ×§×¢× ×\98 ×§×\90פ×\99ר×\9f ×\90×\95×\9f ×\90רײַנ×\9c×\99×\99×\92×\9f ×\93×¢×\9d ×\98עקס×\98 ×\90ר×\99×\99×\9f ×¦×\95 ×\90 ×\98עקס×\98 ×\98עקע ×\90×\95×\9f ×\93×\90ס ×\93×\90ר×\98×\9f ×\90פ×\94×\99×\98×\9f ×¤×\90ר ×©×¤×¢×\98ער.'''
+'readonlywarning' => "'''×\95×\95×\90רענ×\95× ×\92: ×\93×\99 ×\93×\90×\98× ×\91×\90×\96×¢ ×\90×\99×\96 ×\92×¢×\95×\95×\90ר×\9f ×¤×\90רש×\9c×\90ס×\9f ×¤×\90ר ×\90×\95×\99פ×\94×\90×\9c×\98×\95× ×\92, ×\9e×\9e×\99×\9c×\90 ×\95×\95×¢×\98 ×\90×\99ר × ×\99ש×\98 ×§×¢× ×¢×\9f ×\90פ×\94×\99×\98×\9f ×\90×\99×\99ערע ×¢× ×\93ער×\95× ×\92×¢×\9f ×\90צ×\99× ×\93. '''
\90×\99ר ×§×¢× ×\98 ×§×\90פ×\99ר×\9f ×\90×\95×\9f ×\90רײַנ×\9c×\99×\99×\92×\9f ×\93×¢×\9d ×\98עקס×\98 ×\90ר×\99×\99×\9f ×¦×\95 ×\90 ×\98עקס×\98 ×\98עקע ×\90×\95×\9f ×\93×\90ס ×\93×\90ר×\98×\9f ×\90פ×\94×\99×\98×\9f ×\90×\95×\99×£ ×©×¤×¢×\98ער.
 
 דער אדמיניסטראטאר וואס האט זי פארשלאסן האט מסביר געווען אזוי: $1",
 'protectedpagewarning' => "'''ווארענונג:  דער בלאט איז געווארן פארשפארט אז בלויז באניצערס מיט סיסאפ פריווילעגיעס קענען אים ענדערן.'''
@@ -994,6 +1001,8 @@ $2
 'language-converter-depth-warning' => 'אַריבער דעם שפּראַך קאַנווערטער טיף לימיט ($1)',
 'node-count-exceeded-category' => 'בלעטער וואו קנופצאל איז צו פיל',
 'node-count-exceeded-warning' => 'קנופנצאל אויפן בלאט צו הויך',
+'expansion-depth-exceeded-category' => "בלעטער וואו מ'האט אריבערגעשטיגן די פארברייטערונג טיף",
+'expansion-depth-exceeded-warning' => 'בלאט גייט אריבער דער פארברייטערונג טיף',
 'converter-manual-rule-error' => 'געטראפן א גרײַז אין האנטלעכן שפראך־קאנווערטירן כלל',
 
 # "Undo" feature
@@ -1223,7 +1232,7 @@ $1",
 'search-interwiki-default' => '$1 רעזולטאטן:',
 'search-interwiki-more' => '(נאך)',
 'search-relatedarticle' => 'פארבינדן',
-'mwsuggest-disable' => '×\91×\98×\9c ×\9e×\90×\9b×\9f ×¤×\90רש×\9c×\90×\92×\9f AJAX',
+'mwsuggest-disable' => '×\91×\98×\9c ×\9e×\90×\9b×\9f ×\96×\95×\9a ×¤×\90רש×\9c×\90×\92×\9f',
 'searcheverything-enable' => 'זוכן אין אלע נאמענטיילן',
 'searchrelated' => 'פארבינדן',
 'searchall' => 'אלץ',
@@ -1724,6 +1733,7 @@ $1",
 'lockmanager-fail-deletelock' => 'נישט מעגלעך אויסמעקן שלאס טעקע פאר "$1".',
 
 # ZipDirectoryReader
+'zip-file-open-error' => 'געטראפן א גרײַז ביים עפענען די טעקע פאר ZIP־קאנטראלירונג.',
 'zip-wrong-format' => 'ספעציפירטע טעקע איז נישט קיין ZIP טעקע.',
 
 # Special:UploadStash
@@ -2013,9 +2023,9 @@ $1",
 'prevpage' => 'פֿריִערדיקער בלאַט ($1)',
 'allpagesfrom' => 'ווייזן בלעטער אנגעהויבן פון:',
 'allpagesto' => 'ווייזן בלעטער ביז:',
-'allarticles' => '×\90Ö·×\9c×¢ ×\90ַר×\98×\99ק×\9c×¢×\9f',
-'allinnamespace' => 'אלע בלעטער ($1 נאָמענטייל )',
-'allnotinnamespace' => 'אלע בלעטער (נישט אין נאמענטייל  $1)',
+'allarticles' => '×\90Ö·×\9c×¢ ×\91×\9c×¢×\98ער',
+'allinnamespace' => 'אַלע בלעטער ($1 נאָמענטייל )',
+'allnotinnamespace' => 'אַלע בלעטער (נישט אין $1 נאָמענטייל)',
 'allpagesprev' => 'פריערדיגע',
 'allpagesnext' => 'נעקסט',
 'allpagessubmit' => 'גיי',
@@ -2058,7 +2068,7 @@ $1",
 # Special:ActiveUsers
 'activeusers' => 'ליסטע פֿון אַקטיווע באַניצער',
 'activeusers-intro' => 'דאָס איז א ליסטע פֿון באַניצער וואָס זענען געווען אַקטיוו אינערהאָלב  $1 {{PLURAL:$1|דעם לעצטן טאָג|די לעצטע $1 טעג}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|×\91×\90Ö·×\90ַר×\91×¢×\98×\95× ×\92\91×\90Ö·×\90ַר×\91×¢×\98×\95× ×\92×¢×\9f}} אין  {{PLURAL:$3|דעם לעצטן טאָג|די לעצטע $3 טעג}}',
+'activeusers-count' => '$1 {{PLURAL:$1|פע×\95×\9c×\94|פע×\95×\9c×\95ת}} אין  {{PLURAL:$3|דעם לעצטן טאָג|די לעצטע $3 טעג}}',
 'activeusers-from' => 'ווײַזן באַניצער אָנהייבנדיג פון:',
 'activeusers-hidebots' => 'באַהאַלטן באטן',
 'activeusers-hidesysops' => 'באַהאַלטן סיסאפן',
@@ -2122,7 +2132,7 @@ $1",
 'usermessage-template' => 'MediaWiki:באניצער־מעלדונג',
 
 # Watchlist
-'watchlist' => '×\9e×\99×\99×\9f ×\90×\95×\99פפַּ×\90סונג ליסטע',
+'watchlist' => '×\90×\95×\99פֿפ×\90Ö·סונג ליסטע',
 'mywatchlist' => 'אויפפַּאסונג ליסטע',
 'watchlistfor2' => 'פֿאַר $1 $2',
 'nowatchlist' => 'איר האט נישט קיין שום בלעטער אין אייער אויפפַּאסונג ליסטע.',
@@ -2270,6 +2280,7 @@ $UNWATCHURL
 'prot_1movedto2' => '[[$1]] אריבערגעפירט צו [[$2]]',
 'protect-badnamespace-title' => 'אומשיצבארער נאמענטייל',
 'protect-badnamespace-text' => 'בלעטער אין דעם נאמענטייל קען מען נישט שיצן.',
+'protect-norestrictiontypes-title' => 'נישט־שיצבארער בלאט',
 'protect-legend' => 'באַשטעטיגן שיץ',
 'protectcomment' => 'אורזאַך:',
 'protectexpiry' => 'גייט אויס:',
@@ -2285,9 +2296,9 @@ $UNWATCHURL
 
 איר קענט ענדערן דעם שיצונג ניווא פונעם בלאַט, אבער דאס וועט נישט ווירקן אויף דער קאַסקאַדירטער שיצונג .',
 'protect-default' => 'אלע באניצער ערלויבט',
-'protect-fallback' => 'פֿ×\90×\93ערט "$1" ערלויבניש',
-'protect-level-autoconfirmed' => '×\91×\9c×\90ק×\99ר×\9f × ×²Ö·×¢ ×\90×\95×\9f × ×\99×\98 ×\90ײַנ×\92עשר×\99×\91×¢× ×¢ ×\91×\90Ö·× ×\99צערס',
-'protect-level-sysop' => 'נאר סיסאפן',
+'protect-fallback' => '×\93ער×\9c×\95×\99×\91×\9f × ×\90ר ×\91×\90× ×\99צער ×\9e×\99ט "$1" ערלויבניש',
+'protect-level-autoconfirmed' => '×\9c×\90×\96×\9f × ×\90ר ×\90×\95×\99×\98×\90×\9e×\90×\98×\99ש ×\91×\90ש×\98×¢×\98×\99ק×\98×¢ ×\91×\90Ö·× ×\99צער',
+'protect-level-sysop' => '×\93ער×\9c×\95×\99×\91×\9f × ×\90ר ×¡×\99ס×\90פ×\9f',
 'protect-summary-cascade' => 'קאסקאדירן',
 'protect-expiring' => 'גייט אויס $1 (UTC)',
 'protect-expiring-local' => 'לאזט אויס $1',
@@ -2578,18 +2589,20 @@ $1',
 'move-page' => 'באַוועגן $1',
 'move-page-legend' => 'באַוועגן בלאַט',
 'movepagetext' => "זיך באניצן מיט דעם פֿארעם וועט פֿארענדערן דעם נאמען פֿון דעם בלאט, און וועט אריבערפֿירן זיין געשיכטע צום נייעם נאמען.
-
-דאס אלטע קעפל וועט ווערן א ווייטערפֿירן בלאט צום נייעם נאמען.
+דאס אלטע קעפל וועט ווערן א ווייטערפֿירונג בלאט צום נייעם קעפל.
 
 איר קענט דערהיינטיגן ווייטערפֿירונגען צום אלטן נאמען אויטאמאטיש.
 
-טאמער נישט, טוט פֿארזיכערן אז עס איז נישטא קיין [[Special:DoubleRedirects|געטאפלטע]] אדער [[Special:BrokenRedirects|צעבראכענע]] ווייטערפֿירונגען.
+טאמער נישט, טוט פֿארזיכערן אז עס איז נישטא קיין [[Special:DoubleRedirects|געטאפלטע]] אדער [[Special:BrokenRedirects|צעבראכענע ווייטערפֿירונגען]].
 
-איר זענט פֿאראנטווארטלעך זיכער מאכן אז אלע פֿארבינדונגען ווערן געריכטעט צו דער געהעריגער ריכטונג.
+איר זענט פֿאראנטווארטלעך זיכער מאכן אז אלע פֿארבינדונגען ווערן געריכטעט צום געהעריגן ציל.
 
-אכטונג: דער בלאט וועט נישט ווערן אריבערגעפֿירט אויב עס איז שוין דא א בלאט אונטער דעם נייעם נאמען, אחוץ ווען ער איז ליידיג. אדער ער איז א ווייטערפֿירונג בלאט, און ער האט נישט קיין געשיכטע פון ענדערונגען. פשט דערפֿון, אז איר קענט איבערקערן א ווייטערפֿירונג וואס איר האט אט געמאכט בטעות, און איר קענט נישט אריבערשרייבן אן עקסיסטירנדן בלאט.
+דער בלאט וועט '''נישט''' ווערן אריבערגעפֿירט אויב עס איז שוין דא א בלאט אונטער דעם נייעם נאמען, אחוץ ווען ער איז א ווייטערפֿירונג בלאט, און ער האט נישט קיין געשיכטע פון ענדערונגען. 
+פשט דערפֿון, אז איר קענט איבערקערן א ווייטערפֿירונג וואס איר האט אט געמאכט בטעות, און איר קענט נישט אריבערשרייבן אן עקסיסטירנדן בלאט.
 
-'''ווארענונג:''' אזא ענדערונג קען זיין דראסטיש און נישט געווינטשען פאר א פאפולערן בלאט; ביטע פֿארזיכערט אז איר פֿארשטייט די ווייטגרייכנדע קאנסקווענסן צו דער אקציע בעפֿאר איר פֿירט דאס אויס.",
+'''ווארענונג!'''
+ אזא ענדערונג קען זיין דראסטיש און נישט געווינטשען פאר א פאפולערן בלאט; 
+ביטע פֿארזיכערט אז איר פֿארשטייט די ווייטגרייכנדע קאנסקווענסן צו דער אקציע בעפֿאר איר פֿירט דאס אויס.",
 'movepagetext-noredirectfixer' => "זיך באניצן מיט דעם פֿארעם אונטן וועט פֿארענדערן דעם נאמען פֿון דעם בלאט, און וועט אריבערפֿירן זיין געשיכטע צום נייעם נאמען.
 
 דאס אלטע קעפל וועט ווערן א ווייטערפֿירן בלאט צום נײַעם נאמען.
@@ -3217,7 +3230,9 @@ $1',
 'exif-unknowndate' => 'אומבאַוואוסטע דאַטע',
 
 'exif-orientation-1' => 'נארמאַל',
+'exif-orientation-2' => 'האריזאנטאל געשפיגלט',
 'exif-orientation-3' => 'ראטירט 180°',
+'exif-orientation-4' => 'ווערטיקאל געשפיגלט',
 'exif-orientation-6' => 'ראטירט 90° קעגן זייגער',
 'exif-orientation-7' => 'ראטירט  90° מיטן זייגער און איבערגעדרייט ווערטיקאל',
 'exif-orientation-8' => 'ראטירט 90° מיטן זייגער',
@@ -3613,7 +3628,7 @@ $5
 'specialpages-group-highuse' => 'בלעטער וואס זענען געניצט אסאך',
 'specialpages-group-pages' => 'ליסטעס פֿון בלעטער',
 'specialpages-group-pagetools' => 'געצייג פֿאר בלעטער',
-'specialpages-group-wiki' => '×\95×\95×\99ק×\99 ×\93×\90Ö·×\98×\9f ×\90×\95×\9f ×\92עצ×\99×\99×\92',
+'specialpages-group-wiki' => 'דאַטן און געצייג',
 'specialpages-group-redirects' => 'ווײַטערפֿירן ספעציעלע בלעטער',
 'specialpages-group-spam' => 'ספאַם געצייג',
 
@@ -3711,7 +3726,6 @@ $5
 'logentry-newusers-create' => 'באניצער קאנטע $1 געשאפן געווארן',
 'logentry-newusers-create2' => 'באניצער קאנטע $1 געשאפן געווארן דורך $3',
 'logentry-newusers-autocreate' => 'קאנטע $1 באשאפן אויטאמאטיש',
-'newuserlog-byemail' => 'פאַסווארט געשיקט דורך ע-פאסט',
 'logentry-rights-rights' => '$1 האט געביטן גרופע מיטגלידערשאַפֿט פֿאַר $3 פֿון $4 אויף $5',
 'logentry-rights-rights-legacy' => '$1 האט געביטן גרופע מיטגלידערשאפט פאר $3',
 'logentry-rights-autopromote' => '$1 אויטאמאטיש פראמאווירט פון $4 צו $5',
index 444d03e..1ae93eb 100644 (file)
@@ -2082,7 +2082,7 @@ Orúkọ ibiàyè pọndandan, fún àpẹrẹ "*.org".<br />
 'usermessage-editor' => 'Sìstẹ́mú olúránṣẹ́',
 
 # Watchlist
-'watchlist' => 'Ìmójútó mi',
+'watchlist' => 'Ìmójútó',
 'mywatchlist' => 'Ìmójútó',
 'watchlistfor2' => 'Fún $1 $2',
 'nowatchlist' => 'Ẹ kò ní ohun kankan nínú ìmójútó yín.',
@@ -2252,7 +2252,7 @@ Bí a ṣe to ojúewé '''$1''' nì yí:",
 'protect-default' => 'Ẹ gba gbogbo àwọn oníṣe láàyè',
 'protect-fallback' => 'Ìyọ̀nda "$1" pọn dandan',
 'protect-level-autoconfirmed' => 'Dínà àwọn oníṣe tuntun àti tíkòforúkọ sílẹ́',
-'protect-level-sysop' => 'Alámùójútó nìkan',
+'protect-level-sysop' => 'Gba àwọn alámùójútó nìkan láyè',
 'protect-summary-cascade' => 'títẹ̀léra',
 'protect-expiring' => 'parí ní $1 (UTC)',
 'protect-expiring-local' => 'yíò parí ní $1',
@@ -2899,6 +2899,8 @@ Fáìlì náà jẹ́ rírùsóké ní àbọ̀.',
 'pageinfo-protect-cascading' => 'Àbò bẹ̀rẹ̀ láti ibí',
 'pageinfo-protect-cascading-yes' => 'Bẹ́ẹ̀ni',
 'pageinfo-protect-cascading-from' => 'Àbò bẹ̀rẹ̀ láti',
+'pageinfo-category-pages' => 'Iye àwọn ojúewé',
+'pageinfo-category-files' => 'Iye àwọn fáìlì',
 
 # Patrolling
 'markaspatrolleddiff' => 'Ìṣààmí sí bíi sísọ́',
@@ -3456,7 +3458,7 @@ $5
 'specialpages-group-highuse' => 'Àwọn ojúewé ìlò gíga',
 'specialpages-group-pages' => 'Àkójọ àwọn ojúewé',
 'specialpages-group-pagetools' => 'Àwọn irinṣẹ́ ojúewé',
-'specialpages-group-wiki' => 'Àwọn irinṣẹ́ àti dátà wiki',
+'specialpages-group-wiki' => 'Àwọn irinṣẹ́ àti dátà',
 'specialpages-group-redirects' => 'Ìtúnjúwe àwọn ojúewé pàtàkì',
 'specialpages-group-spam' => 'Irínṣẹ́ spam',
 
@@ -3556,7 +3558,6 @@ Ibiìtakùn yìí únkojú ìsòro ìṣìṣẹ́ẹ̀rọ.',
 'logentry-newusers-create' => 'Àpamọ́ oníṣe $1 jẹ́ dídá',
 'logentry-newusers-create2' => 'Àpamọ́ oníṣe $3 jẹ́ dídá látọwọ́ $1',
 'logentry-newusers-autocreate' => 'Àkópamọ́ $1 jẹ́ dídá fúnrarẹ̀',
-'newuserlog-byemail' => 'ọ̀rọ̀ìpamọ́ jẹ́ fífiránṣẹ́ pẹ̀lú e-mail',
 'logentry-rights-rights' => '$1 yí ìjọ́mọ ẹgbẹ́ padà fún $3 láti $4 sí $5',
 'logentry-rights-rights-legacy' => '$1 yí ìjọ́mọ ẹgbẹ́ padà fún $3',
 'logentry-rights-autopromote' => '$1 jẹ́ gbígbéga nífúnraẹni láti $4 sí $5',
index 181d94f..88383e9 100644 (file)
@@ -3362,7 +3362,6 @@ MediaWiki是基於使用目的而加以發佈,但係就唔會負上任何嘅
 # New logging system
 'revdelete-restricted' => '已經應用限制到操作員',
 'revdelete-unrestricted' => '已經拎走對於操作員嘅限制',
-'newuserlog-byemail' => '密碼已由電郵寄出',
 'rightsnone' => '(無)',
 
 # Search suggestions
index b6bef28..9354cda 100644 (file)
@@ -115,7 +115,7 @@ $namespaceAliases = array(
 
 $specialPageAliases = array(
        'Activeusers'               => array( '活跃用户' ),
-       'Allmessages'               => array( '所有息' ),
+       'Allmessages'               => array( '所有息' ),
        'Allpages'                  => array( '所有页面' ),
        'Ancientpages'              => array( '最早页面' ),
        'Badtitle'                  => array( '无效标题' ),
@@ -160,6 +160,7 @@ $specialPageAliases = array(
        'MIMEsearch'                => array( 'MIME搜索' ),
        'Mostcategories'            => array( '最多分类页面' ),
        'Mostimages'                => array( '最多链接文件' ),
+       'Mostinterwikis'            => array( '最多跨wiki链接页面' ),
        'Mostlinked'                => array( '最多链接页面' ),
        'Mostlinkedcategories'      => array( '最多链接分类' ),
        'Mostlinkedtemplates'       => array( '最多链接模板' ),
@@ -189,10 +190,10 @@ $specialPageAliases = array(
        'Statistics'                => array( '统计信息' ),
        'Tags'                      => array( '标签' ),
        'Unblock'                   => array( '解除封禁' ),
-       'Uncategorizedcategories'   => array( 'æ\97 分类分类' ),
-       'Uncategorizedimages'       => array( 'æ\97 分类文件' ),
-       'Uncategorizedpages'        => array( 'æ\97 分类页面' ),
-       'Uncategorizedtemplates'    => array( 'æ\97 分类模板' ),
+       'Uncategorizedcategories'   => array( 'æ\9cª分类分类' ),
+       'Uncategorizedimages'       => array( 'æ\9cª分类文件' ),
+       'Uncategorizedpages'        => array( 'æ\9cª分类页面' ),
+       'Uncategorizedtemplates'    => array( 'æ\9cª分类模板' ),
        'Undelete'                  => array( '恢复被删页面' ),
        'Unlockdb'                  => array( '解除数据库锁定' ),
        'Unusedcategories'          => array( '未使用分类' ),
@@ -360,7 +361,7 @@ $messages = array(
 'tog-editsection' => '启用[编辑]链接编辑段落',
 'tog-editsectiononrightclick' => '启用右击段落标题编辑段落(需要JavaScript)',
 'tog-showtoc' => '显示目录(对于有多于3个标题的页面)',
-'tog-rememberpassword' => '在浏览器上记住我的登录状态(最长$1天)',
+'tog-rememberpassword' => '在该浏览器保存我的登录状态(最长$1日)',
 'tog-watchcreations' => '添加我创建的页面和上传的文件至我的监视列表',
 'tog-watchdefault' => '添加我编辑的页面和文件至我的监视列表',
 'tog-watchmoves' => '将我移动的页面和文件添加到我的监视列表',
@@ -368,7 +369,7 @@ $messages = array(
 'tog-minordefault' => '默认标记编辑为小编辑',
 'tog-previewontop' => '在编辑框上方显示预览',
 'tog-previewonfirst' => '首次编辑时显示预览',
-'tog-nocache' => '用浏览器页面缓存',
+'tog-nocache' => '用浏览器页面缓存',
 'tog-enotifwatchlistpages' => '当我的监视列表中的页面或文件更改时发送电子邮件通知我',
 'tog-enotifusertalkpages' => '当我的讨论页更改时发送电子邮件通知我',
 'tog-enotifminoredits' => '当页面和文件有小编辑时发送电子邮件通知我',
@@ -379,7 +380,7 @@ $messages = array(
 'tog-externaleditor' => '默认使用外部编辑器(供高级用户使用,需要在您的计算机上作出一些特别设置。[//www.mediawiki.org/wiki/Manual:External_editors 更多信息。])',
 'tog-externaldiff' => '默认使用外部差异分析(供高级用户使用,需要在您的计算机上作出一些特别设置。[//www.mediawiki.org/wiki/Manual:External_editors 更多信息。])',
 'tog-showjumplinks' => '启用“跳转到”访问链接',
-'tog-uselivepreview' => '使用实时预览(需要 Javascript 支持)(实验功能)',
+'tog-uselivepreview' => '使用实时预览(需要JavaScript)(实验功能)',
 'tog-forceeditsummary' => '未输入编辑摘要时提醒我',
 'tog-watchlisthideown' => '在监视列表中隐藏我的编辑',
 'tog-watchlisthidebots' => '在监视列表中隐藏机器人的编辑',
@@ -388,7 +389,7 @@ $messages = array(
 'tog-watchlisthideanons' => '在监视列表中隐藏匿名用户',
 'tog-watchlisthidepatrolled' => '在监视列表中隐藏已巡查的编辑',
 'tog-ccmeonemails' => '把我给其他用户发送的电子邮件的副本发送给我',
-'tog-diffonly' => '对比差异时不显示页面内容',
+'tog-diffonly' => '比较差异时不显示页面内容',
 'tog-showhiddencats' => '显示隐藏分类',
 'tog-noconvertlink' => '停用链接文字转换',
 'tog-norollbackdiff' => '执行回退后不显示差异',
@@ -480,7 +481,7 @@ $messages = array(
 'newwindow' => '(将于新窗口中打开)',
 'cancel' => '取消',
 'moredotdotdot' => '更多',
-'morenotlisted' => '更多未被列出...',
+'morenotlisted' => '更多未被列出的模板...',
 'mypage' => '页面',
 'mytalk' => '讨论',
 'anontalk' => '该IP地址的讨论',
@@ -600,7 +601,7 @@ $1',
 'privacypage' => 'Project:隐私权政策',
 
 'badaccess' => '权限错误',
-'badaccess-group0' => '您被禁止执行您刚才请求的操作。',
+'badaccess-group0' => '你被禁止执行你刚才请求的操作。',
 'badaccess-groups' => '您刚才请求的操作只有{{PLURAL:$2|这个用户组|以下用户组}}中的用户才能使用: $1',
 
 'versionrequired' => '需要版本为$1的MediaWiki',
@@ -609,14 +610,14 @@ $1',
 
 'ok' => '确定',
 'retrievedfrom' => '来自“$1”',
-'youhavenewmessages' => '有$1($2)。',
+'youhavenewmessages' => '有$1($2)。',
 'newmessageslink' => '新信息',
 'newmessagesdifflink' => '最后更改',
-'youhavenewmessagesfromusers' => '您有来自{{PLURAL:$3| 另一位用户| $3位用户}}的$1($2)。',
-'youhavenewmessagesmanyusers' => '您有来自多位用户的$1($2)。',
+'youhavenewmessagesfromusers' => '你有来自{{PLURAL:$3|其他用户|$3个用户}}的$1($2)。',
+'youhavenewmessagesmanyusers' => '你有来自多个用户的$1($2)。',
 'newmessageslinkplural' => '{{PLURAL:$1|一条新信息|新信息}}',
-'newmessagesdifflinkplural' => '最{{PLURAL:$1|更改}}',
-'youhavenewmessagesmulti' => '在$1有新信息',
+'newmessagesdifflinkplural' => '最{{PLURAL:$1|更改}}',
+'youhavenewmessagesmulti' => '在$1有新信息',
 'editsection' => '编辑',
 'editold' => '编辑',
 'viewsourceold' => '查看源代码',
@@ -656,7 +657,7 @@ $1',
 
 # Main script and global functions
 'nosuchaction' => '这个命令不存在',
-'nosuchactiontext' => 'URL 指定的命令无效。您可能误输入了 URL 地址,或者点击了错误的链接。这一错误也有可能是由{{SITENAME}}所使用软件自身的错误导致的。',
+'nosuchactiontext' => 'URL指定的命令无效。你可能误输入了URL地址,或者点击了错误的链接。这一错误亦有可能是由{{SITENAME}}所使用软件自身的错误导致的。',
 'nosuchspecialpage' => '此特殊页面不存在',
 'nospecialpagetext' => '<strong>您请求的特殊页面无效。</strong>
 
@@ -740,8 +741,8 @@ $2',
 执行锁定的管理员给出如下解释:$3。',
 'invalidtitle-knownnamespace' => '使用名字空间“$2”和文本“$3”的无效标题',
 'invalidtitle-unknownnamespace' => '使用未知名字空间编号$1和文本“$2”的无效标题',
-'exception-nologin' => '未登录',
-'exception-nologin-text' => '此操作需要您先登录。',
+'exception-nologin' => '未登录',
+'exception-nologin-text' => '该页面或操作需要你登录至本wiki。',
 
 # Virus scanner
 'virus-badscanner' => "错误的配置:未知的病毒扫描程序:''$1''",
@@ -753,19 +754,18 @@ $2',
 
 您可以继续以匿名方式使用{{SITENAME}},或再次以相同或不同用户身份<span class='plainlinks'>[$1 登录]</span>。请注意一些页面可能仍然显示您为登录状态,直到您清空您的浏览器缓存为止。",
 'welcomeuser' => '欢迎,$1!',
-'welcomecreation-msg' => '您的帐户已创建。
-请不要忘记更改您的[[Special:Preferences|{{SITENAME}}个人设置]]。',
+'welcomecreation-msg' => '你的账户已创建。请不要忘记更改你的[[Special:Preferences|{{SITENAME}}系统设置]]。',
 'yourname' => '用户名:',
 'yourpassword' => '密码:',
 'yourpasswordagain' => '再次输入密码:',
-'remembermypassword' => '自动登录(最长$1{{PLURAL:$1|天|天}})',
-'securelogin-stick-https' => '登录后继续使用 HTTPS 连接',
+'remembermypassword' => '在该浏览器保存我的登录状态(最长$1日)',
+'securelogin-stick-https' => '登录后继续使用HTTPS连接',
 'yourdomainname' => '您的域名:',
-'password-change-forbidden' => '您不能在此 wiki 上修改密码。',
+'password-change-forbidden' => '你不能在本wiki更改密码。',
 'externaldberror' => '这可能是由于验证数据库错误或您被禁止更新您的外部账号。',
 'login' => '登录',
 'nav-login-createaccount' => '登录/创建账户',
-'loginprompt' => '您必须启用 Cookies 才能登录{{SITENAME}}。',
+'loginprompt' => '你必须启用Cookies才能登录{{SITENAME}}。',
 'userlogin' => '登录/创建账户',
 'userloginnocreate' => '登录',
 'logout' => '退出',
@@ -776,25 +776,24 @@ $2',
 'createaccount' => '创建账户',
 'gotaccount' => '已经拥有账户?请$1。',
 'gotaccountlink' => '登录',
-'userlogin-resetlink' => '忘记了的登录信息?',
-'createaccountmail' => '通过电子邮件',
+'userlogin-resetlink' => '忘记了的登录信息?',
+'createaccountmail' => '使用一个临时的随机密码,并将它发送到以下指定的电子邮件地址',
 'createaccountreason' => '原因:',
 'badretype' => '您所输入的密码并不相同。',
-'userexists' => '用户名已存在请使用其他名称。',
+'userexists' => '用户名已存在请使用其他名称。',
 'loginerror' => '登录错误',
 'createaccounterror' => '无法建立账户:$1',
-'nocookiesnew' => '已成功创建新账户!检测到您已禁用 Cookies,请先启用然后登录。',
-'nocookieslogin' => '本站使用 Cookies 进行登录,检测到您已禁用 Cookies,请先启用然后重试。',
-'nocookiesfornew' => '该用户账户尚未创建,因为我们不能确认它的来源。
-请确保您已经启用 Cookies,刷新本页后重试。',
-'noname' => '您没有输入有效的用户名。',
+'nocookiesnew' => '本用户账户已被创建,但登录失败。{{SITENAME}}使用cookie登录。你已停用cookie。请启用cookie,然后使用你的新用户名和密码登录。',
+'nocookieslogin' => '{{SITENAME}}使用cookie登录。你已停用cookie。请启用cookie后重试。',
+'nocookiesfornew' => '本用户账户未被创建,我们不能确认它的来源。请确保你已启用cookie,刷新本页后重试。',
+'noname' => '你没有指定有效的用户名。',
 'loginsuccesstitle' => '登录成功',
 'loginsuccess' => "'''“$1”,欢迎登录{{SITENAME}}。'''",
-'nosuchuser' => 'æ\89¾ä¸\8då\88°ç\94¨æ\88·â\80\9c$1â\80\9dã\80\82ç\94¨æ\88·å\90\8d对大å°\8få\86\99å\92\8cç¹\81ç®\80ä½\93æ\98¯å\8cºå\88\86ç\9a\84ã\80\82请æ£\80æ\9f¥æ\82¨ç\9a\84æ\8b¼å\86\99æ\98¯å\90¦æ\9c\89é\94\99误ï¼\8cæ\88\96è\80\85[[Special:UserLogin/signup|注å\86\8c]]。',
-'nosuchusershort' => 'æ\89¾ä¸\8då\88°ç\94¨æ\88·â\80\9c$1â\80\9dã\80\82请æ£\80æ\9f¥æ\82¨ç\9a\84æ\8b¼å\86\99æ\98¯å\90¦æ\9c\89é\94\99误。',
-'nouserspecified' => '您需要指定一个用户名。',
+'nosuchuser' => '没æ\9c\89å\90\8d为â\80\9c$1â\80\9dç\9a\84ç\94¨æ\88·ã\80\82ç\94¨æ\88·å\90\8då\8cºå\88\86大å°\8få\86\99ã\80\82请æ£\80æ\9f¥ä½ ç\9a\84æ\8b¼å\86\99æ\88\96[[Special:UserLogin/signup|å\88\9b建æ\96°è´¦æ\88·]]。',
+'nosuchusershort' => '没æ\9c\89å\90\8d为â\80\9c$1â\80\9dç\9a\84ç\94¨æ\88·ã\80\82请æ£\80æ\9f¥ä½ ç\9a\84æ\8b¼å\86\99。',
+'nouserspecified' => '你必须指定用户名。',
 'login-userblocked' => '该用户已被封禁,禁止登录。',
-'wrongpassword' => '密码错误,请重试。',
+'wrongpassword' => '你输入的密码错误。请重试。',
 'wrongpasswordempty' => '您没有输入密码,请重试!',
 'passwordtooshort' => '您的密码至少需要$1个字符。',
 'password-name-match' => '您的密码必须和您的用户名不相同。',
@@ -812,13 +811,13 @@ $2',
 'noemailcreate' => '您需要提供一个有效的电子邮件地址',
 'passwordsent' => '用户"$1"的新密码已经寄往所登记的电子邮件地址。
 请在收到后再登录。',
-'blocked-mailpassword' => '您的 IP 地址已被禁止编辑,同时为了防止密码恢复功能被滥用,已禁用该功能。',
+'blocked-mailpassword' => '你的IP地址被禁止编辑,为预防滥用,密码恢复功能也被禁止使用。',
 'eauthentsent' => '一封确认信已经发送到推荐的地址。在发送其它邮件到此账户前,您必须首先依照这封信中的指导确认这个电子邮箱真实有效。',
 'throttled-mailpassword' => '密码提醒已在最近$1小时内发送。为了安全起见,在每$1小时内只能发送一个密码提醒。',
 'mailerror' => '发送邮件错误:$1',
-'acct_creation_throttle_hit' => '抱歉!您已经创建了$1个账号,已经达到最大允许注册数量。目前使用本 IP 的来访者将不能再创建任何账户。',
+'acct_creation_throttle_hit' => '使用你的IP地址访问本wiki的访客在过去24小时中创建了{{PLURAL:$1|$1个账户}},达到了这段时间所允许的最大值。因此,使用该IP地址的访客现在不能再创建账户。',
 'emailauthenticated' => '您的电子邮箱地址已经于$2 $3确认有效。',
-'emailnotauthenticated' => '您的邮箱地址<strong>尚未被认证</strong>。下列功能将不会发送任何邮件。',
+'emailnotauthenticated' => '你的电子邮件地址未确认。你不会接收到以下任何特性的电子邮件。',
 'noemailprefs' => '指定一个电子邮箱地址以使用此功能。',
 'emailconfirmlink' => '确认您的邮箱地址',
 'invalidemailaddress' => '邮箱地址格式不正确,请输入正确的邮箱地址或清空该输入框。',
@@ -831,8 +830,7 @@ $2',
 
 如果该账户创建错误的话,您可以忽略此信息。',
 'usernamehasherror' => '用户名中不可包含哈希(hash)字符',
-'login-throttled' => '您最近已经尝试多次登录。
-请稍后重试。',
+'login-throttled' => '你最近尝试登录的次数过多。请稍后重试。',
 'login-abort-generic' => '登录失败 - 已终止',
 'loginlanguagelabel' => '语言:$1',
 'suspicious-userlogout' => '注销请求被拒绝,因为它似乎是由有设计缺陷的浏览器或缓存代理发出的。',
@@ -861,7 +859,7 @@ $2',
 
 # Special:PasswordReset
 'passwordreset' => '重置密码',
-'passwordreset-text' => '完成此表格以接收一封包含您的帐户详情的提醒邮件。',
+'passwordreset-text' => '完成该表格以接收你账户信息的邮件提醒。',
 'passwordreset-legend' => '重置密码',
 'passwordreset-disabled' => '此wiki已经禁用密码重置。',
 'passwordreset-pretext' => '{{PLURAL:$1||输入下面的数据块之一}}',
@@ -893,11 +891,11 @@ $2
 'changeemail-text' => '完成此窗体可以更改您的电子邮件地址。您将需要输入您的密码以确认此更改。',
 'changeemail-no-info' => '
 您必须登录以直接访问本页。',
-'changeemail-oldemail' => 'å½\93å\89\8dç\9a\84ç\94µå­\90é\82®ä»¶å\9c°å\9d\80ï¼\9a',
+'changeemail-oldemail' => '当前电子邮件地址:',
 'changeemail-newemail' => '新的电子邮件地址:',
 'changeemail-none' => '(无)',
-'changeemail-password' => '的{{SITENAME}}密码:',
-'changeemail-submit' => '更改电子邮',
+'changeemail-password' => '的{{SITENAME}}密码:',
+'changeemail-submit' => '更改电子邮件地址',
 'changeemail-cancel' => '取消',
 
 # Edit page toolbar
@@ -913,9 +911,9 @@ $2
 'headline_tip' => '2级标题文字',
 'nowiki_sample' => '在此插入非格式文本',
 'nowiki_tip' => '插入非格式文本',
-'image_sample' => '例.jpg',
+'image_sample' => '例.jpg',
 'image_tip' => '插入文件',
-'media_sample' => '例.ogg',
+'media_sample' => '例.ogg',
 'media_tip' => '文件链接',
 'sig_tip' => '带时间戳的签名',
 'hr_tip' => '水平线(请小心使用)',
@@ -933,33 +931,37 @@ $2
 'anoneditwarning' => "'''警告:'''您没有登录。
 您的IP地址将记录在此页的编辑历史中。",
 'anonpreviewwarning' => "''您没有登录。保存页面将会把您的IP地址记录在此页的编辑历史中。''",
-'missingsummary' => "'''提示:'''您没有提供编辑摘要。如果您再次点击“{{int:savearticle}}”,您的编辑将不带编辑摘要保存。",
+'missingsummary' => "'''提示:'''你没有提供编辑摘要。如果你再次点击“{{int:savearticle}}”,你的编辑将不带编辑摘要保存。",
 'missingcommenttext' => '请在下面输入评论。',
 'missingcommentheader' => "'''提示:''' 您还没有为此评论提供一个标题。如果您再次点击“{{int:savearticle}}”,您的编辑将不带标题保存。",
 'summary-preview' => '摘要预览:',
 'subject-preview' => '标题预览:',
 'blockedtitle' => '用户被封禁',
-'blockedtext' => "'''您的用户名或 IP 地址已被封禁。'''
+'blockedtext' => "'''你的用户名或IP地址已被封禁。'''
 
\9c¬æ¬¡å°\81ç¦\81æ\93\8dä½\9cç\94±$1å®\8cæ\88\90ï¼\8cå°\81ç¦\81å\8e\9få\9b ä¸º''$2''。
\89§è¡\8cå°\81ç¦\81ç\9a\84管ç\90\86å\91\98æ\98¯$1ã\80\82å°\81ç¦\81å\8e\9få\9b æ\98¯''$2''。
 
 * 开始时间:$8
-* ç»\93æ\9d\9fæ\97¶é\97´ï¼\9a$6
-* 拟封禁对象:$7
+* å\88°æ\9c\9fæ\97¶é\97´ï¼\9a$6
+* 目标用户:$7
 
-您可以联系$1或其他的[[{{MediaWiki:Grouppage-sysop}}|管理员]]以申诉此次封禁。若您已在[[Special:Preferences|个人设置]]中设置了一个有效的电子邮件地址,且未被封禁电子邮件功能,则您可通过“发送邮件”功能来联系相关管理员。您当前的 IP 地址为$3,此次封禁的 ID 为#$5。请在您的查询中注明上述所有信息。",
-'autoblockedtext' => "您的 IP 地址因与另一位已封禁用户的相同而被自动封禁,该用户是由$1封禁的。封禁原因如下
+你可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。只有当你在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才可以使用它。你当前的IP地址是$3,该封禁ID是#$5。请在你的询问中包含上面的所有信息。",
+'autoblockedtext' => "你的IP地址因曾被一位被$1封禁的用户使用而被自动封禁。封禁原因
 
 :''$2''
 
 * 开始时间:$8
-* ç»\93æ\9d\9fæ\97¶é\97´ï¼\9a$6
-* 拟封禁对象:$7
+* å\88°æ\9c\9fæ\97¶é\97´ï¼\9a$6
+* 目标用户:$7
 
-您可以联系$1或其他的[[{{MediaWiki:Grouppage-sysop}}|管理员]]以申诉此次封禁。若您已在[[Special:Preferences|个人设置]]中设置了一个有效的电子邮件地址,且未被封禁电子邮件功能,则您可通过“发送邮件”功能来联系相关管理员。您当前的 IP 地址是$3,此次封禁的 ID 为#$5。请在您的查询中注明上述所有信息。",
+你可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。
+
+请注意,只有当你在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才可以使用它。
+
+你当前的IP地址是$3,该封禁ID是#$5。请在你的询问中包含上面的所有信息。",
 'blockednoreason' => '无给出原因',
 'whitelistedittext' => '您必须先$1才可编辑页面。',
-'confirmedittext' => '您必须确认您的电子邮件地址才能编辑本页。请通过[[Special:Preferences|个人设置]]页面设置并确认。',
+'confirmedittext' => '你必须确认你的电子邮件地址才能编辑页面。请通过[[Special:Preferences|系统设置]]设置并确认你的电子邮件地址。',
 'nosuchsectiontitle' => '没有这个段落',
 'nosuchsectiontext' => '您尝试编辑的章节并不存在。
 可能是在您查看页面时已经移动或删除。',
@@ -973,63 +975,53 @@ $2
 要创建该页面,请在下面的编辑框中输入内容(详情参见[[{{MediaWiki:Helppage}}|帮助页]])。
 如果您误入此页,请点击浏览器中的“返回”按钮。',
 'anontalkpagetext' => "---- ''这是一个还未建立账户的匿名用户的讨论页, 因此我们只能用IP地址来与他或她联络。该IP地址可能由几名用户共享。如果您是一名匿名用户并认为此页上的评语与您无关,请[[Special:UserLogin/signup|创建新账户]]或[[Special:UserLogin|登录]]以避免在未来与其他匿名用户混淆。''",
-'noarticletext' => '本页面目前没有内容。您可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索该页标题]]、<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编辑本页]。</span>',
+'noarticletext' => '本页面目前没有内容。你可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索该页标题]]、<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编辑本页面]。</span>',
 'noarticletext-nopermission' => '此页目前没有内容。
 您可以在其它页[[Special:Search/{{PAGENAME}}|搜寻此页标题]],或<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜寻有关日志]</span>,但您没有权限建立此页。',
 'missing-revision' => '“{{PAGENAME}}”的修订#$1不存在。
 
 这通常是因为进入了一个已被删除的页面的历史链接。
 详细信息可以在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中找到。',
-'userpage-userdoesnotexist' => '用户账户"$1"尚未注册。
-请在创建/编辑该页之前进行核对。',
+'userpage-userdoesnotexist' => '用户账户“$1”没有注册。请在创建/编辑本页前检查。',
 'userpage-userdoesnotexist-view' => '用户账户“$1”未曾创建。',
 'blocked-notice-logextract' => '这位用户目前已被封禁。以下提供最近的封禁日志以供参考:',
-'clearyourcache' => "'''注意:'''保存之后,必须清除浏览器缓存才能看到做出的更改。
-* '''火狐(Firefox)/Safari:'''按住“Shift”,同时击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)
-* '''谷歌浏览器(Google Chrome):'''按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)
-* '''Internet Explorer:'''按住“Ctrl”,同时击“刷新”,或按“Ctrl-F5”
+'clearyourcache' => "'''注意:'''保存之后,必须清除浏览器缓存才能看到做出的更改。
+* '''火狐(Firefox)/Safari:'''按住“Shift”,同时击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)
+* '''Google Chrome:'''按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)
+* '''Internet Explorer:'''按住“Ctrl”,同时击“刷新”,或按“Ctrl-F5”
 * '''Opera:'''在“工具→首选项”中清除缓存",
 'usercssyoucanpreview' => "'''提示:''' 在保存前请用“{{int:showpreview}}”按钮来测试您新的 CSS 。",
 'userjsyoucanpreview' => "'''提示:''' 在保存前请用“{{int:showpreview}}”按钮来测试您新的 JavaScript 。",
-'usercsspreview' => "'''记住您只是在预览您的个人 CSS。'''
-'''还没有保存!'''",
-'userjspreview' => "'''记住您只是在测试/预览您的个人 JavaScript。'''
-'''还没有保存!'''",
-'sitecsspreview' => "'''记住您现在只是预览此 CSS。'''
-'''尚未保存!'''",
-'sitejspreview' => "'''记住您现在只是预览此 JavaScript 代码。'''
-'''尚未保存!'''",
+'usercsspreview' => "'''请记住你现在只是在预览你的用户CSS。它尚未保存!'''",
+'userjspreview' => "'''请记住你现在只是在测试/预览你的用户JavaScript。它尚未保存!'''",
+'sitecsspreview' => "'''请记住你现在只是在预览该CSS。它尚未保存!'''",
+'sitejspreview' => "'''请记住你现在只是在预览该JavaScript代码。它尚未保存!'''",
 'userinvalidcssjstitle' => "'''警告:''' 不存在皮肤\"\$1\"。注意自定义的 .css 和 .js 页要使用小写标题,例如,{{ns:user}}:Foo/vector.css 不同于 {{ns:user}}:Foo/Vector.css。",
 'updated' => '(已更新)',
 'note' => "'''注意:'''",
 'previewnote' => "'''请记住这仅为预览。'''您的更改还未保存!",
 'continue-editing' => '往编辑框',
-'previewconflict' => 'è¿\99个é¢\84è§\88æ\98¾ç¤ºäº\86ä¸\8aé\9d¢æ\96\87å­\97ç¼\96è¾\91å\8cºä¸­ç\9a\84å\86\85容ã\80\82å®\83们å°\86å\9c¨æ\82¨ä¿\9då­\98å\90\8eå\87ºç\8e°。',
-'session_fail_preview' => "'''抱歉!由于会话数据丢失,我们不能处理您的编辑。'''请重试。如果仍然失败,请尝试[[Special:UserLogout|注销]]然后重新登录。",
-'session_fail_preview_html' => "'''抱歉!我们不能处理您在会话数据丢失时的编辑。'''
+'previewconflict' => '该é¢\84è§\88å\8f\8dæ\98 äº\86ä¸\8aé\9d¢æ\96\87å­\97ç¼\96è¾\91å\8cºä¸­ç\9a\84æ\96\87å­\97å\9c¨ä½ ä¿\9då­\98å\90\8eç\9a\84æ\98¾ç¤ºç\8a¶å\86µ。',
+'session_fail_preview' => "'''对不起!由于会话数据丢失,我们无法处理你的编辑。'''请重试。如果仍然失败,请尝试[[Special:UserLogout|退出登录]]后重新登录。",
+'session_fail_preview_html' => "'''对不起!由于会话数据丢失,我们无法处理你的编辑。'''
 
-''由于{{SITENAME}}允许使用原始的 HTML,为了防范 JavaScript 攻击,预览已被隐藏。''
+''因为{{SITENAME}}已启用原始HTML,为了预防JavaScript攻击,预览被隐藏。''
 
-'''å¦\82æ\9e\9cè¿\99æ\98¯ä¸\80次å\90\88æ³\95ç\9a\84ç¼\96è¾\91ï¼\8c请å°\9dè¯\95é\87\8dè¯\95ã\80\82'''å¦\82æ\9e\9cä¾\9dç\84¶ä¸\8dè¡\8cï¼\8c请[[Special:UserLogout|注é\94\80]]并重新登录。",
+'''å¦\82æ\9e\9c该ç¼\96è¾\91å°\9dè¯\95å\90\88æ³\95ï¼\8c请é\87\8dè¯\95ã\80\82'''å¦\82æ\9e\9cä»\8dç\84¶å¤±è´¥ï¼\8c请å°\9dè¯\95[[Special:UserLogout|é\80\80å\87ºç\99»å½\95]]å\90\8e重新登录。",
 'token_suffix_mismatch' => "'''由于您用户端中的编辑令牌毁损了一些标点符号字元,您的编辑已经被拒绝。'''
 此次编辑被拒绝以防止页面文本损坏。
 这种情况通常在您使用含有故障的网页式匿名代理服务的时候出现。",
-'edit_form_incomplete' => "'''编辑表单的某些部分没有传送至服务器;请检查您的编辑内容是否完整并重试。'''",
+'edit_form_incomplete' => "'''编辑表格的某些部分没有到达服务器,请检查你的编辑是否完整并重试。'''",
 'editing' => '编辑“$1”',
 'creating' => '创建 $1',
 'editingsection' => '编辑“$1”(段落)',
 'editingcomment' => '编辑“$1”(新段落)',
 'editconflict' => '编辑冲突:$1',
-'explainconflict' => "有人在您开始编辑后更改了页面。
-上面的文字框内显示的是目前本页的内容。
-您所做的修改显示在下面的文字框中。
-您应当将您的修改加入至现有的内容中。
-'''只有'''在上面文字框中的内容会在您点击“{{int:savearticle}}”后被保存。",
-'yourtext' => '您的文字',
+'explainconflict' => "其他用户在你开始编辑后更改了该页面。上面的文字区含有该页面当前的文字。下面的文字区显示你的更改。你必须把你的更改合并至现有文字。'''只有'''当你单击“{{int:savearticle}}”后,上面的文字区中的文字才会被保存。",
+'yourtext' => '你的文字',
 'storedversion' => '已保存的版本',
 'nonunicodebrowser' => "'''警告:您的浏览器不兼容Unicode编码。'''这里有一个工作区将使您能安全地编辑页面:非ASCII字符将以十六进制编码方式出现在编辑框中。",
-'editingold' => "'''警告:您正在编辑的是本页的旧版本。'''
-如果您保存它的话,在旧版本之后的任何修改都将丢失。",
+'editingold' => "'''警告:你正在编辑的是本页面的旧版本。'''如果你保存该编辑,该版本后的所有更改都会丢失。",
 'yourdiff' => '差异',
 'copyrightwarning' => "请注意您对{{SITENAME}}的所有贡献都被认为是在$2下发布,请查看在$1的细节。
 如果您不希望您的文字被任意修改和再散布,请不要提交。<br />
@@ -1042,7 +1034,7 @@ $2
 '''不要在未获授权的情况下发表!'''",
 'longpageerror' => "'''错误:您所提交的文本长度有{{PLURAL:$1|1|$1}}KB,这大于{{PLURAL:$2|1|$2}}KB的最大值。'''
 因此,该文本无法保存。",
-'readonlywarning' => "'''警告:数据库被锁定以进行维护,所以您目前将无法保存您的修改。'''您或许希望将本段文字先复制并保存到文本文件,并在稍后进行修改。
+'readonlywarning' => "警告:数据库被锁定以进行维护,所以您目前将无法保存您的修改。'''您或许希望将本段文字先剪贴并保存到文本文件,并在稍后进行修改。
 
 锁定数据库的管理员有如下解释:$1",
 'protectedpagewarning' => "'''警告:本页面已被保护,只有拥有管理员权限的用户可以编辑。'''下面提供最后的日志条目以供参考:",
@@ -1056,16 +1048,16 @@ $2
 'template-semiprotected' => '(半保护)',
 'hiddencategories' => '本页面属于$1个隐藏分类:',
 'edittools' => '<!-- 这里的文字将显示在编辑和上传表格下面。 -->',
-'nocreatetext' => '{{SITENAME}}限制了创建新页面功能。您可以返回并编辑已有的页面,或者[[Special:UserLogin|登录或创建新账户]]。',
-'nocreate-loggedin' => '没有权限创建新页面。',
+'nocreatetext' => '{{SITENAME}}已经限制创建新页面功能。你可以返回编辑现有页面或[[Special:UserLogin|登录或创建账户]]。',
+'nocreate-loggedin' => '没有权限创建新页面。',
 'sectioneditnotsupported-title' => '段落编辑不支持',
 'sectioneditnotsupported-text' => '本页面不支持段落编辑。',
 'permissionserrors' => '权限错误',
-'permissionserrorstext' => 'å\9b ä¸ºä¸\8bå\88\97{{PLURAL:$1|å\8e\9få\9b }}ï¼\8cæ\82¨æ²¡æ\9c\89æ\9d\83é\99\90æ\89§行该操作:',
-'permissionserrorstext-withaction' => 'å\9b ä¸ºä¸\8bå\88\97{{PLURAL:$1|å\8e\9få\9b }}ï¼\8cæ\82¨没有权限$2:',
-'recreate-moveddeleted-warn' => "'''警告:正在重新创建曾经被删除的页面。'''
+'permissionserrorstext' => 'å\9b ä¸ºä»¥ä¸\8b{{PLURAL:$1|å\8e\9få\9b }}ï¼\8c你没æ\9c\89æ\9d\83é\99\90è¿\9b行该操作:',
+'permissionserrorstext-withaction' => 'å\9b ä¸ºä»¥ä¸\8b{{PLURAL:$1|å\8e\9få\9b }}ï¼\8cä½ 没有权限$2:',
+'recreate-moveddeleted-warn' => "'''警告:正在重新创建曾经被删除的页面。'''
 
-应该考虑继续编辑本页是否合适。这里提供本页的删除和移动记录以供参考:",
+应该考虑继续编辑本页是否合适。这里提供本页的删除和移动记录以供参考:",
 'moveddeleted-notice' => '本页面已被删除。下面提供本页的删除和移动日志以供参考。',
 'log-fulllog' => '查看完整日志',
 'edit-hook-aborted' => '编辑被hook指令取消。
@@ -1073,7 +1065,7 @@ $2
 'edit-gone-missing' => '不能更新页面。
 它可能刚刚被删除。',
 'edit-conflict' => '编辑冲突。',
-'edit-no-change' => '由于文字无任何改动,您的编辑已被忽略。',
+'edit-no-change' => '因为没有文字更改,你的编辑已被忽略。',
 'edit-already-exists' => '不可以建立一个新页面。
 它已经存在。',
 'defaultmessagetext' => '默认消息文本',
@@ -1110,10 +1102,10 @@ $2
 'converter-manual-rule-error' => '手动语言转换规则中检测到错误',
 
 # "Undo" feature
-'undo-success' => '此编辑可被撤销。请检查以下对比以核实这正是您想做的,然后保存以下更改完成撤销编辑。',
+'undo-success' => '该编辑可以被撤销。请检查下面的对比以核实你想要撤销的内容,然后保存下面的更改以完成撤销。',
 'undo-failure' => '因存在冲突的中间编辑,本编辑不能撤销。',
 'undo-norev' => '由于其修订版本不存在或已删除,此编辑不能撤销。',
-'undo-summary' => '撤销由[[Special:Contributions/$2|$2]]([[User talk:$2|讨论]])所作出的修订$1',
+'undo-summary' => '撤销[[Special:Contributions/$2|$2]]([[User talk:$2|讨论]])的版本$1',
 
 # Account creation failure
 'cantcreateaccounttitle' => '无法创建账户',
@@ -1139,9 +1131,9 @@ $3的理由是''$2''",
 'histlegend' => "差异选择:选出需要对比的版本,按“回车键”或下方的按钮进行对比。<br />
 说明:'''({{int:cur}})'''=与最后版本之间的差异,'''({{int:last}})'''=与上一版本之间的差异,'''{{int:minoreditletter}}'''=小编辑。",
 'history-fieldset-title' => '浏览历史',
-'history-show-deleted' => '仅删除的',
+'history-show-deleted' => '仅删除的',
 'histfirst' => '最早',
-'histlast' => '最',
+'histlast' => '最',
 'historysize' => '($1字节)',
 'historyempty' => '(空)',
 
@@ -1158,13 +1150,12 @@ $3的理由是''$2''",
 'rev-deleted-event' => '(日志条目被删除)',
 'rev-deleted-user-contribs' => '[用户名或IP地址被删除 - 编辑在贡献中隐藏]',
 'rev-deleted-text-permission' => "本页面版本已被'''删除'''。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} 删除日志]。",
-'rev-deleted-text-unhide' => "æ\9c¬é¡µé\9d¢ç\9a\84修订ç\89\88已被'''å\88 é\99¤'''ã\80\82详æ\83\85请è§\81[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} å\88 é\99¤æ\97¥å¿\97\80\82æ\82¨å\8f¯ä»¥[$1 æ\9f¥ç\9c\8bå½\93å\89\8dç\89\88æ\9c¬]以继续。",
+'rev-deleted-text-unhide' => "æ\9c¬é¡µé\9d¢ç\89\88æ\9c¬å·²è¢«'''å\88 é\99¤'''ã\80\82详æ\83\85请è§\81[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} å\88 é\99¤æ\97¥å¿\97\80\82å¦\82æ\9e\9cä½ æ\83³ç»§ç»­æ\93\8dä½\9cï¼\8cä½ ä»\8dç\84¶å\8f¯ä»¥[$1 æ\9f¥ç\9c\8bæ\9c¬ç\89\88æ\9c¬]。",
 'rev-suppressed-text-unhide' => "该页面修订已经被'''监督隐藏'''。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。如果您想继续的话,您可以仍然[$1 去查看这次修订]。",
-'rev-deleted-text-view' => "æ\9c¬é¡µé\9d¢ç\9a\84修订ç\89\88已被'''å\88 é\99¤'''ã\80\82æ\82¨可以查看它,详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
+'rev-deleted-text-view' => "æ\9c¬é¡µé\9d¢ç\89\88æ\9c¬å·²è¢«'''å\88 é\99¤'''ã\80\82ä½ 可以查看它,详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
 'rev-suppressed-text-view' => "该页面修订已经被'''监督隐藏'''。您可以查看它。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。",
-'rev-deleted-no-diff' => "因为其中一次修订已被'''删除''',您不可以查看这个差异。
-在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中可以找到更多的信息。",
-'rev-suppressed-no-diff' => "该页面的其中一次修订版已被'''删除''',您无法查看这个对比。",
+'rev-deleted-no-diff' => "你不能查看该差异,因为其中一个版本已被'''删除'''。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
+'rev-suppressed-no-diff' => "你不能查看该差异,因为其中一个版本已被'''删除'''。",
 'rev-deleted-unhide-diff' => "该差异对比其中的一个修订版本已经被'''删除'''。在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中可以找到更多的信息。如果您想继续的话,您仍然可以[$1 查看这次修订]。",
 'rev-suppressed-unhide-diff' => "该页面的其中一次修订已经被'''监督隐藏'''。
 在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到更多的资料。如果您想继续的话,您可以仍然[$1 去查看这次修订]。",
@@ -1181,16 +1172,17 @@ $3的理由是''$2''",
 'revdelete-nologid-title' => '无效的日志项目',
 'revdelete-nologid-text' => '您尚未指定一个目标日志项目去进行这个动作或指定的项目不存在。',
 'revdelete-no-file' => '指定的文件不存在。',
-'revdelete-show-file-confirm' => '您是否想查看文件“<nowiki>$1</nowiki>”于$2 $3时的已被删除的修订版本?',
+'revdelete-show-file-confirm' => '确定要查看文件“<nowiki>$1</nowiki>”于$2$3被删除的版本吗?',
 'revdelete-show-file-submit' => '是',
 'revdelete-selected' => "'''选取'''[[:$1]]'''的$2次修订:'''",
 'logdelete-selected' => "'''{{PLURAL:$1|选取的日志项目}}:'''",
 'revdelete-text' => "'''删除的修订仍将显示在页面历史中, 但它们的文本内容已不能被公众访问。'''
 在{{SITENAME}}的其他管理员将仍能访问隐藏的内容并通过与此相同的界面恢复删除,除非站点工作者进行了一些附加的限制。",
 'revdelete-confirm' => '请确认您肯定去做的话,您就要明白到后果,以及这个程序符合[[{{MediaWiki:Policy-url}}|政策]]。',
-'revdelete-suppress-text' => "'''只有'''出现下列情况下才应阻止访问:
-* 可能虚假的个人信息
-*: ''家庭地址、电话号码、身份证号码等等。''",
+'revdelete-suppress-text' => "阻止应该'''只'''在以下情形使用:
+*潜在的诽谤信息
+*不合适的个人信息
+*:''家庭地址、电话号码和社保号码等。''",
 'revdelete-legend' => '设置可见性之限制',
 'revdelete-hide-text' => '隐藏版本文字',
 'revdelete-hide-image' => '隐藏文件内容',
@@ -1244,7 +1236,7 @@ $1",
 'mergehistory-from' => '来源页面:',
 'mergehistory-into' => '目的页面:',
 'mergehistory-list' => '可以合并的编辑历史',
-'mergehistory-merge' => 'ä¸\8bå\88\97[[:$1]]ç\9a\84修订å\8f¯ä»¥å\90\88并å\88°[[:$2]]ã\80\82ç\94¨è¯¥é\80\89项æ\8c\89é\92®å\88\97å\8e»å\90\88并å\8fªæ\9c\89å\9c¨æ\8c\87å®\9aæ\97¶é\97´ä»¥å\89\8dæ\89\80å\88\9b建ç\9a\84修订ã\80\82è¦\81ç\95\99æ\84\8fç\9a\84æ\98¯ä½¿ç\94¨å¯¼è\88ªé\93¾æ\8e¥ä¾¿ä¼\9aé\87\8d设è¿\99ä¸\80æ \8f。',
+'mergehistory-merge' => '以ä¸\8b[[:$1]]ç\9a\84ç\89\88æ\9c¬å\8f¯ä»¥å\90\88并è\87³[[:$2]]ã\80\82请使ç\94¨å\8d\95é\80\89æ\8c\89é\92®å\88\97以å\90\88并è\87³å\9c¨æ\8c\87å®\9aæ\97¶é\97´å\8f\8aä¹\8bå\89\8då\88\9b建ç\9a\84ç\89\88æ\9c¬ã\80\82请注æ\84\8fï¼\8c使ç\94¨å¯¼è\88ªé\93¾æ\8e¥ä¼\9aé\87\8d置该å\88\97。',
 'mergehistory-go' => '显示可以合并的编辑',
 'mergehistory-submit' => '合并版本',
 'mergehistory-empty' => '没有可以合并的版本。',
@@ -1330,7 +1322,7 @@ $1",
 'showingresults' => "下面显示从第'''$2'''条结果开始的'''$1'''条结果。",
 'showingresultsnum' => "下面显示从第'''$2'''条结果开始的'''$3'''条结果。",
 'showingresultsheader' => "关于'''$4'''的{{PLURAL:$5|第'''$1'''条至第'''$3'''条结果|第'''$1'''条至第'''$2'''条结果,共'''$3'''条结果}}",
-'nonefound' => "'''注意''':只有部分名字空间的页面会被默认搜索。尝试在您的搜索语句前添加“all:”前缀,这样可以搜索全部页面(包括讨论页、模板等),或者您也可使用所需名字空间作为前缀。",
+'nonefound' => "'''注意''':只有某些名字空间被默认搜索。请尝试给你的搜索内容添加前缀“all:”以搜索全部内容(包括讨论页面、模板等)或使用期望的名字空间作为前缀。",
 'search-nonefound' => '找不到和查询相匹配的结果。',
 'powersearch' => '高级搜索',
 'powersearch-legend' => '高级搜索',
@@ -1353,10 +1345,10 @@ $1",
 'qbsettings-directionality' => '根据您的语言文本方向固定位置',
 
 # Preferences page
-'preferences' => '个人设置',
-'mypreferences' => '个人设置',
+'preferences' => '系统设置',
+'mypreferences' => '系统设置',
 'prefs-edits' => '编辑数量:',
-'prefsnologin' => '未登录',
+'prefsnologin' => '未登录',
 'prefsnologintext' => '您必须先<span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} 登录]</span>才能设置个人参数。',
 'changepassword' => '更改密码',
 'prefs-skin' => '皮肤',
@@ -1390,13 +1382,13 @@ $1",
 'searchresultshead' => '搜索',
 'resultsperpage' => '每页显示链接数:',
 'stub-threshold' => '<a href="#" class="stub">短页面链接</a>格式阈值(字节):',
-'stub-threshold-disabled' => '已用',
+'stub-threshold-disabled' => '已用',
 'recentchangesdays' => '最近更改中显示的天数:',
 'recentchangesdays-max' => '最多$1天',
 'recentchangescount' => '默认显示的编辑数:',
 'prefs-help-recentchangescount' => '该项包含最近更改、页面历史和日志。',
 'prefs-help-watchlist-token' => '此栏填写的密钥可以生成您监视列表的RSS源。任何知晓本栏密钥的人都能阅读您的监视列表,因此请使用安全的数值。这里已提供了一个随机生成的数值供您选择:$1',
-'savedprefs' => '新的系统设置已经保存。',
+'savedprefs' => '你的系统设置已保存。',
 'timezonelegend' => '时区:',
 'localtime' => '当地时间:',
 'timezoneuseserverdefault' => '使用wiki默认值($1)',
@@ -1420,23 +1412,23 @@ $1",
 'defaultns' => '否则在这些名字空间中搜索:',
 'default' => '默认',
 'prefs-files' => '文件',
-'prefs-custom-css' => '自定义 CSS',
-'prefs-custom-js' => '自定义 JavaScript',
+'prefs-custom-css' => '自定义CSS',
+'prefs-custom-js' => '自定义JavaScript',
 'prefs-common-css-js' => '所有皮肤共用的CSS/JavaScript:',
-'prefs-reset-intro' => '您可以通过本页面重置您的系统设置为默认值。此操作不可撤销。',
+'prefs-reset-intro' => '你可以使用本页面重置你的系统设置为网站默认值。该操作不能撤销。',
 'prefs-emailconfirm-label' => '电子邮件确认:',
 'prefs-textboxsize' => '编辑框大小',
 'youremail' => '电子邮件:',
 'username' => '{{GENDER:$1|用户名}}:',
 'uid' => '{{GENDER:$1|用户}}ID:',
-'prefs-memberingroups' => '{{PLURAL:$1|用户组}}的{{GENDER:$2|成员}}:',
+'prefs-memberingroups' => '{{GENDER:$2|用户}}{{PLURAL:$1|组}}:',
 'prefs-registration' => '注册时间:',
 'yourrealname' => '真实姓名:',
 'yourlanguage' => '语言:',
 'yourvariant' => '内容语言变种:',
 'prefs-help-variant' => '您希望用于显示本站内容的语种或拼写语系。',
 'yournick' => '新签名:',
-'prefs-help-signature' => '讨论页面上的评论应使用“<nowiki>~~~~</nowiki>”签名,它会自动转换为您的签名和时间戳。',
+'prefs-help-signature' => '讨论页面上的评论应该使用“<nowiki>~~~~</nowiki>”签名,它会自动转换为你的签名及时间戳。',
 'badsig' => '错误的原始签名。请检查HTML标签。',
 'badsiglength' => '签名过长。请不超过$1个字符。',
 'yourgender' => '性别:',
@@ -1445,9 +1437,9 @@ $1",
 'gender-female' => '女',
 'prefs-help-gender' => '选填项目。使软件使用正确的性别称呼。该信息将会公开。',
 'email' => '电子邮件',
-'prefs-help-realname' => '真实姓名是可选的项目。如果您选择提供它,它将会用于贡献署名。',
-'prefs-help-email' => '电子邮件地址是可选的项目。但是在您忘记密码需要重置密码时需要它。',
-'prefs-help-email-others' => '您也可以选择让其他用户通过您的用户页或讨论页上的链接用电子邮件联系您。其他用户联系您时,您的电子邮件地址将不会被显示。',
+'prefs-help-realname' => '真实姓名是选填项目。如果你选择提供它,它将会用于贡献署名。',
+'prefs-help-email' => '电子邮件地址是选填项目。但是在你忘记密码需要重置密码时需要电子邮件地址。',
+'prefs-help-email-others' => '你亦可以选择让其他用户通过你的用户页或讨论页上的链接用电子邮件联系你。其他用户联系你时你的电子邮件地址不会显示。',
 'prefs-help-email-required' => '电子邮件地址是必填项目。',
 'prefs-info' => '基本信息',
 'prefs-i18n' => '界面语言',
@@ -1478,7 +1470,7 @@ $1",
 'saveusergroups' => '保存用户组',
 'userrights-groupsmember' => '用户组:',
 'userrights-groupsmember-auto' => '自动用户组:',
-'userrights-groups-help' => '可以更改该用户的用户组:
+'userrights-groups-help' => '可以更改该用户的用户组:
 * 选中的选项框表示该用户属于该用户组。
 * 未选中的选项框表示该用户不属于该用户组。
 * 星号(*)表示一旦添加该用户组后不能删除,反之亦然。',
@@ -1486,9 +1478,9 @@ $1",
 'userrights-no-interwiki' => '您并没有权限去编辑在其它wiki上的用户权限。',
 'userrights-nodatabase' => '数据库$1不存在或并非为本地的。',
 'userrights-nologin' => '您必须要以管理员帐户[[Special:UserLogin|登录]]之后才可以指定用户权限。',
-'userrights-notallowed' => '您的帐户无添加或删除用户权限的权限。',
-'userrights-changeable-col' => '可以更改的用户组',
-'userrights-unchangeable-col' => '不能更改的用户组',
+'userrights-notallowed' => '你的账户没有权限添加或删除用户权限。',
+'userrights-changeable-col' => '可以更改的用户组',
+'userrights-unchangeable-col' => '不能更改的用户组',
 
 # Groups
 'group' => '用户组:',
@@ -1548,7 +1540,7 @@ $1",
 'right-suppressrevision' => '审查和恢复管理员隐藏的版本',
 'right-suppressionlog' => '查看非公开日志',
 'right-block' => '阻止其他用户编辑',
-'right-blockemail' => '阻止用户发送邮件',
+'right-blockemail' => '阻止用户电邮联系',
 'right-hideuser' => '封禁并隐藏用户名',
 'right-ipblock-exempt' => '避开IP封禁、自动封禁和IP段封禁',
 'right-proxyunbannable' => '避开代理服务器的自动封禁',
@@ -1573,7 +1565,7 @@ $1",
 'right-userrights-interwiki' => '编辑其它wiki的用户的用户权限',
 'right-siteadmin' => '锁定和解锁数据库',
 'right-override-export-depth' => '导出含有链接页面深度为5的页面',
-'right-sendemail' => '向其他用户发送邮件',
+'right-sendemail' => '电邮联系其他用户',
 'right-passwordreset' => '查看密码重置电子邮件',
 
 # Special:Log/newusers
@@ -1613,19 +1605,19 @@ $1",
 'action-import' => '从其他wiki导入本页面',
 'action-importupload' => '从文件上传导入本页面',
 'action-patrol' => '标记他人的编辑为已巡查',
-'action-autopatrol' => '将您的编辑标记为已巡查',
+'action-autopatrol' => '使你的编辑标记为已巡查',
 'action-unwatchedpages' => '查看未受监视页面的列表',
 'action-mergehistory' => '合并本页面的历史',
 'action-userrights' => '编辑所有用户的权限',
 'action-userrights-interwiki' => '编辑其它wiki的用户的用户权限',
 'action-siteadmin' => '锁定或解锁数据库',
-'action-sendemail' => '通过邮件联系其他用户',
+'action-sendemail' => '电邮联系其他用户',
 
 # Recent changes
 'nchanges' => '$1次更改',
 'recentchanges' => '最近更改',
 'recentchanges-legend' => '最近更改选项',
-'recentchanges-summary' => '跟踪这个wiki上的最新更改。',
+'recentchanges-summary' => '在此页面上跟踪维基的更改。',
 'recentchanges-feed-description' => '跟踪订阅本wiki的最近更改。',
 'recentchanges-label-newpage' => '这次编辑建立了一个新页面',
 'recentchanges-label-minor' => '这是一个小编辑',
@@ -1652,8 +1644,8 @@ $1",
 'rc_categories' => '分类限制(用“|”分隔)',
 'rc_categories_any' => '任意',
 'rc-change-size-new' => '更改后$1字节',
-'newsectionsummary' => '/* $1 */ 新段落',
-'rc-enhanced-expand' => '显示细节(需JavaScript支持)',
+'newsectionsummary' => '/*$1*/新段落',
+'rc-enhanced-expand' => '显示细节(需要JavaScript)',
 'rc-enhanced-hide' => '隐藏细节',
 'rc-old-title' => '最初被创建为" $1 "',
 
@@ -1741,23 +1733,21 @@ $1",
 'fileexists-thumbnail-yes' => "此文件可能是另一幅图像的缩小版本''(缩略图)''。 [[$1|thumb]]
 请仔细检查该文件<strong>[[:$1]]</strong>。
 如果被检查文件与原始大小的图像是同一幅图像,您无需上传多余的缩略图。",
-'file-thumbnail-no' => "文件名以<strong>$1</strong>开头。它可能是另一幅图像的缩小版本''(缩略图)''。
-如果您有该图像完整分辨率的版本,请上传该完整版本。否则请修改文件名。",
+'file-thumbnail-no' => "文件名以<strong>$1</strong>开始。它似乎是缩小的图像''(缩略图)''。如果你有完整分辨率的该图像,请上传它,否则请更改文件名。",
 'fileexists-forbidden' => '已存在相同名称的文件,且不能覆盖;请返回并用一个新的名称来上传此文件。[[File:$1|thumb|center|$1]]',
-'fileexists-shared-forbidden' => '在共享文件库中已存在同名文件。
-如果您仍然想继续上传,请返回并使用一个新的文件名来上传此文件。[[File:$1|thumb|center|$1]]',
-'file-exists-duplicate' => '这个文件与下列{{PLURAL:$1|一|多}}个文件重复:',
+'fileexists-shared-forbidden' => '共享文件库中存在该名称的文件。如果你仍想上传你的文件,请返回使用其他名称。[[File:$1|thumb|center|$1]]',
+'file-exists-duplicate' => '本文件是以下{{PLURAL:$1|文件}}的副本:',
 'file-deleted-duplicate' => '一个相同名称的文件 ([[:$1]]) 在先前删除过。您应该在重新上传之前检查一下该文件之删除纪录。',
 'uploadwarning' => '上传警告',
 'uploadwarning-text' => '请修改下面的文件说明并重试。',
 'savefile' => '保存文件',
 'uploadedimage' => '上传“[[$1]]”',
 'overwroteimage' => '上传“[[$1]]”的新版本',
-'uploaddisabled' => '上传己用。',
-'copyuploaddisabled' => '通过网址上传功能已禁用。',
+'uploaddisabled' => '上传己用。',
+'copyuploaddisabled' => 'URL上传已停用。',
 'uploadfromurl-queued' => '上传已被列入队列。',
-'uploaddisabledtext' => '文件上传已用。',
-'php-uploaddisabledtext' => 'PHP 设置已禁用文件上传功能。请检查 file_uploads 设置。',
+'uploaddisabledtext' => '文件上传已用。',
+'php-uploaddisabledtext' => 'PHP文件上传停用。请检查file_uploads设置。',
 'uploadscripted' => '该文件包含可能被网络浏览器错误解释的 HTML 或脚本代码。',
 'uploadvirus' => '该文件包含病毒!
 详情:$1',
@@ -1845,11 +1835,11 @@ $1',
 不能正确检查安全。',
 
 # Special:UploadStash
-'uploadstash' => '文件贮藏',
+'uploadstash' => '上传隐藏',
 'uploadstash-summary' => '这个页面提供已经上传(或者上传中)但未发布到wiki之文件存取。这些文件除了上传的用户之外不会被其他人可见。',
 'uploadstash-clear' => '清除贮藏文件',
-'uploadstash-nofiles' => '您没有已贮藏的文件。',
-'uploadstash-badtoken' => '执行操作不成功,或者您的编辑信息已经过期。请重试。',
+'uploadstash-nofiles' => '你没有被隐藏的文件。',
+'uploadstash-badtoken' => '该操作执行失败,可能是因为你的编辑凭证已过期。请重试。',
 'uploadstash-errclear' => '清除文件不成功。',
 'uploadstash-refresh' => '更新文件清单',
 'invalid-chunk-offset' => '无效区块偏移量',
@@ -1866,7 +1856,7 @@ $1',
 'img-auth-nofile' => '文件“$1”不存在。',
 'img-auth-isdir' => '您正试图访问目录“$1”。您只能访问文件。',
 'img-auth-streaming' => '流式化“$1”中。',
-'img-auth-public' => 'img_auth.php 的功能是从私有 wiki 输出文件。但本 wiki 已被设置为公共 wiki。出于安全考虑,img_auth.php 已被禁用。',
+'img-auth-public' => 'img_auth.php的功能是从非公开wiki输出文件。本wiki已被设置为公开。为了最佳安全状况,img_auth.php已停用。',
 'img-auth-noread' => '用户无权读取“$1”。',
 'img-auth-bad-query-string' => 'URL 有一个无效的查询字符串。',
 
@@ -1909,7 +1899,7 @@ $1',
 # File description page
 'file-anchor-link' => '文件',
 'filehist' => '文件历史',
-'filehist-help' => '查看某一时刻的文件,请击相应的日期/时间。',
+'filehist-help' => '查看某一时刻的文件,请击相应的日期/时间。',
 'filehist-deleteall' => '删除全部',
 'filehist-deleteone' => '删除',
 'filehist-revert' => '恢复',
@@ -1924,14 +1914,14 @@ $1',
 'filehist-comment' => '评论',
 'filehist-missing' => '文件遗失',
 'imagelinks' => '文件用途',
-'linkstoimage' => 'ä¸\8bå\88\97$1个页é\9d¢é\93¾æ\8e¥å\88°本文件:',
+'linkstoimage' => '以ä¸\8b{{PLURAL:$1|页é\9d¢|$1个页é\9d¢}}é\93¾æ\8e¥è\87³本文件:',
 'linkstoimage-more' => '多于$1个页面连接到这个文件。
 下面的列表只列示了连去这个文件的最首$1个页面。
 一个[[Special:WhatLinksHere/$2|完整的列表]]可以提供。',
 'nolinkstoimage' => '没有页面链接到本文件。',
 'morelinkstoimage' => '查看连接到这个文件的[[Special:WhatLinksHere/$1|更多链接]]。',
 'linkstoimage-redirect' => '$1(文件重定向)$2',
-'duplicatesoffile' => 'ä¸\8bå\88\97$1个æ\96\87件ä¸\8e该æ\96\87件é\87\8då¤\8d([[Special:FileDuplicateSearch/$2|更多细节]]):',
+'duplicatesoffile' => '以ä¸\8b{{PLURAL:$1|æ\96\87件|$1个æ\96\87件}}æ\98¯æ\9c¬æ\96\87件ç\9a\84å\89¯æ\9c¬([[Special:FileDuplicateSearch/$2|更多细节]]):',
 'sharedupload' => '该文件来自于$1,它可能在其它计划项目中被应用。',
 'sharedupload-desc-there' => '该文件来自于$1,它可能在其它计划项目中被应用。
 请参阅在[$2 文件描述页面]以了解其相关信息。',
@@ -1962,8 +1952,8 @@ $1',
 # File deletion
 'filedelete' => '删除$1',
 'filedelete-legend' => '删除文件',
-'filedelete-intro' => "您将删除文件'''[[Media:$1|$1]]'''。",
-'filedelete-intro-old' => "您正在删除'''[[Media:$1|$1]]'''于[$4 $2 $3]的版本。",
+'filedelete-intro' => "你将要删除文件'''[[Media:$1|$1]]'''及其全部历史。",
+'filedelete-intro-old' => "你正在删除'''[[Media:$1|$1]]'''[$4 $2$3]的版本。",
 'filedelete-comment' => '原因:',
 'filedelete-submit' => '删除',
 'filedelete-success' => "'''$1'''已经删除。",
@@ -1977,7 +1967,7 @@ $1',
 ** 侵犯版权
 ** 重复文件',
 'filedelete-edit-reasonlist' => '编辑删除埋由',
-'filedelete-maintenance' => '处于维护时将暂时禁用文件删除和恢复。',
+'filedelete-maintenance' => '维护期间文件删除和恢复暂时停用。',
 'filedelete-maintenance-title' => '无法删除文件',
 
 # MIME search
@@ -2031,7 +2021,7 @@ $1',
 'disambiguations-text' => "以下的页面都有到'''消歧义页'''的链接,但它们可能可以链接到更适当的页面。<br />一个页面如果使用了[[MediaWiki:Disambiguationspage]]内的模板,则会被视为消歧义页。",
 
 'doubleredirects' => '双重重定向页',
-'doubleredirectstext' => '此页å\88\97å\87ºäº\86æ\89\80æ\9c\89é\87\8då®\9aå\90\91å\88°å\8f¦ä¸\80é\87\8då®\9aå\90\91页é\9d¢ç\9a\84页é\9d¢ã\80\82æ¯\8fä¸\80è¡\8cé\83½å\8c\85å\90«æ\9c\89å\88°ç¬¬ä¸\80å\92\8c第äº\8c个é\87\8då®\9aå\90\91页é\9d¢ç\9a\84é\93¾æ\8e¥ï¼\8c以å\8f\8a第äº\8c个é\87\8då®\9aå\90\91页é\9d¢ç\9a\84ç\9b®æ \87â\80\94â\80\94é\80\9a常就æ\98¯â\80\9cç\9c\9fæ­£ç\9a\84â\80\9dç\9b®æ \87页é\9d¢ï¼\8cä¹\9få°±æ\98¯ç¬¬ä¸\80个é\87\8då®\9aå\90\91页é\9d¢åº\94该æ\8c\87å\90\91ç\9a\84页é\9d¢ã\80\82<del>å·²å\88\92å\8e»</del>ç\9a\84æ\9d¡ç\9b®æ\98¯å·²ç»\8f解å\86³ç\9a\84项ç\9b®。',
+'doubleredirectstext' => 'æ\9c¬é¡µé\9d¢å\88\97å\87ºé\87\8då®\9aå\90\91è\87³å\85¶ä»\96é\87\8då®\9aå\90\91页ç\9a\84页é\9d¢ã\80\82æ¯\8fè¡\8cå\90«æ\9c\89第ä¸\80å\8f\8a第äº\8cé\87\8då®\9aå\90\91ç\9a\84é\93¾æ\8e¥å\92\8c第äº\8cé\87\8då®\9aå\90\91ç\9a\84ç\9b®æ \87ï¼\88é\80\9a常æ\98¯ç¬¬ä¸\80é\87\8då®\9aå\90\91åº\94该æ\8c\87å\90\91ç\9a\84â\80\9cç\9c\9få®\9eâ\80\9dç\9b®æ \87页é\9d¢ï¼\89ã\80\82<del>带å\88 é\99¤çº¿ç\9a\84</del>æ\9d¡ç\9b®å·²è¢«è§£å\86³。',
 'double-redirect-fixed-move' => '[[$1]]已被移动。它现在重定向至[[$2]]。',
 'double-redirect-fixed-maintenance' => '修复双重重定向自[[$1]]至[[$2]]。',
 'double-redirect-fixer' => '重定向页修复器',
@@ -2058,7 +2048,7 @@ $1',
 'nviews' => '$1次浏览',
 'nimagelinks' => '用于$1个页面中',
 'ntransclusions' => '用于$1个页面中',
-'specialpage-empty' => '该报告结果为空。',
+'specialpage-empty' => '无该报告的结果。',
 'lonelypages' => '孤立页面',
 'lonelypagestext' => '以下页面尚未被{{SITENAME}}中的其它页面链接或被之包含。',
 'uncategorizedpages' => '未归类页面',
@@ -2116,12 +2106,12 @@ $1',
 'pager-newer-n' => '前$1个',
 'pager-older-n' => '后$1个',
 'suppress' => '监督',
-'querypage-disabled' => 'æ­¤ç\89¹æ®\8a页é\9d¢ç\94±äº\8eæ\80§è\83½å\8e\9få\9b å·²è¢«ç¦\81用。',
+'querypage-disabled' => 'æ\9c¬ç\89¹æ®\8a页é\9d¢å\9b æ\80§è\83½é\97®é¢\98è\80\8cå\81\9c用。',
 
 # Book sources
 'booksources' => '网络书源',
 'booksources-search-legend' => '搜索网络书源',
-'booksources-isbn' => 'ISBN:',
+'booksources-isbn' => 'ISBN',
 'booksources-go' => '提交',
 'booksources-text' => '以下是一些网络书店的链接列表,其中可能有您要找的书籍的更多信息:',
 'booksources-invalid-isbn' => '提供的ISBN号码并不正确,请检查原始复制来源号码是否有误。',
@@ -2131,7 +2121,7 @@ $1',
 'speciallogtitlelabel' => '目标(标题或用户):',
 'log' => '日志',
 'all-logs-page' => '所有公开日志',
-'alllogstext' => '所有{{SITENAME}}公开日志的联合展示。 您可以通过选择日志类型、输入用户名(区分大小写)或相关页面(区分大小写)筛选日志条目。',
+'alllogstext' => '所有{{SITENAME}}公开日志的联合展示。可以通过选择日志类型、输入用户名(区分大小写)或相关页面(区分大小写)筛选日志条目。',
 'logempty' => '在日志中不存在匹配项。',
 'log-title-wildcard' => '搜索以该文字开头的标题',
 'showhideselectedlogentries' => '显示/隐藏所选日志项',
@@ -2155,7 +2145,7 @@ $1',
 'allpages-hide-redirects' => '隐藏重定向页',
 
 # SpecialCachedPage
-'cachedspecial-viewing-cached-ttl' => '您正在浏览本页的缓存版本,至多可能存在 $1 的延迟。',
+'cachedspecial-viewing-cached-ttl' => '你正在查看本页面至少$1前的缓存版本。',
 'cachedspecial-viewing-cached-ts' => '您正浏览此页的缓存版本,不一定是最新的完整版本。',
 'cachedspecial-refresh-now' => '查看最新的。',
 
@@ -2169,8 +2159,8 @@ $1',
 'special-categories-sort-abc' => '按字母排列',
 
 # Special:DeletedContributions
-'deletedcontributions' => '删除的用户贡献',
-'deletedcontributions-title' => '删除的用户贡献',
+'deletedcontributions' => '删除的用户贡献',
+'deletedcontributions-title' => '删除的用户贡献',
 'sp-deletedcontributions-contribs' => '贡献',
 
 # Special:LinkSearch
@@ -2200,7 +2190,7 @@ $1',
 
 # Special:ListGroupRights
 'listgrouprights' => '用户组权限',
-'listgrouprights-summary' => '以下面是一个在这个wiki中定义出来的用户权限列表,以及它们的访问权。
+'listgrouprights-summary' => '以下面是一个在这个维基中所定义出来的用户权限列表,以及它们的访问权。
 更多有关个别权限的细节可以在[[{{MediaWiki:Listgrouprights-helppage}}|这里]]找到。',
 'listgrouprights-key' => '* <span class="listgrouprights-granted">被授予的权限</span>
 * <span class="listgrouprights-revoked">被取消的权限</span>',
@@ -2218,18 +2208,17 @@ $1',
 'listgrouprights-removegroup-self-all' => '删除自己的账户的所有用户组',
 
 # E-mail user
-'mailnologin' => '没æ\9c\89å\8f\91é\80\81地址',
-'mailnologintext' => '您必须[[Special:UserLogin|登录]]并在您的[[Special:Preferences|个人设置]]中设置一个有效的电子邮件地址才能向其他用户发送电子邮件。',
+'mailnologin' => 'æ\97 ç\94µå­\90é\82®ä»¶地址',
+'mailnologintext' => '你必须[[Special:UserLogin|登录]]并在你的[[Special:Preferences|系统设置]]中拥有有效的电子邮件地址才能向其他用户发送电子邮件。',
 'emailuser' => '电邮联系',
-'emailuser-title-target' => '邮件联系该{{GENDER:$1|用户}}',
-'emailuser-title-notarget' => '邮件联系',
-'emailpage' => '邮件联系',
-'emailpagetext' => '您可以使用下面的表单向该{{GENDER:$1|用户}}发送电子邮件消息。
-您在[[Special:Preferences|个人设置]]中输入的电子邮件地址将显示为该邮件的“发件人”地址,所以收件人可以直接回复给您。',
+'emailuser-title-target' => '电邮联系该{{GENDER:$1|用户}}',
+'emailuser-title-notarget' => '电邮联系',
+'emailpage' => '电邮联系',
+'emailpagetext' => '你可以使用下面的表格发送电子邮件信息至该{{GENDER:$1|用户}}。你在[[Special:Preferences|系统设置]]中输入的电子邮件地址将显示为邮件的“发件人”地址,所以该用户将可以直接回复你。',
 'usermailererror' => 'Mail 对象返回错误:',
 'defemailsubject' => '{{SITENAME}}来自用户“$1”的电子邮件',
-'usermaildisabled' => '邮件发送功能已禁用',
-'usermaildisabledtext' => '您不可以给这个 wiki 上的其他用户发送邮件',
+'usermaildisabled' => '用户电子邮件停用',
+'usermaildisabledtext' => '你不能发送电子邮件至本wiki的其他用户',
 'noemailtitle' => '无电子邮件地址',
 'noemailtext' => '该用户还没有指定一个有效的电子邮件地址。',
 'nowikiemailtitle' => '禁止电子邮件',
@@ -2248,7 +2237,7 @@ $1',
 'emailccsubject' => '您发送给$1的消息的副本:$2',
 'emailsent' => '电子邮件已发送',
 'emailsenttext' => '您的电子邮件已经发出。',
-'emailuserfooter' => '本邮件由{{SITENAME}}的“电邮用户”功能从$1发送至$2。',
+'emailuserfooter' => '本电子邮件是通过{{SITENAME}}的“电邮联系”功能被$1发送至$2的。',
 
 # User Messenger
 'usermessage-summary' => '留下系统信息。',
@@ -2258,15 +2247,14 @@ $1',
 'watchlist' => '监视列表',
 'mywatchlist' => '监视列表',
 'watchlistfor2' => '$1的监视列表$2',
-'nowatchlist' => '的监视列表为空。',
+'nowatchlist' => '的监视列表为空。',
 'watchlistanontext' => '请$1以查看或编辑您的监视列表。',
 'watchnologin' => '未登录',
 'watchnologintext' => '您必须先[[Special:UserLogin|登录]]才能更改您的监视列表。',
 'addwatch' => '添加至监视列表',
-'addedwatchtext' => '页面“[[:$1]]”已添加至您的[[Special:Watchlist|监视列表]]。
-本页面及其讨论页面的新增更改将会列入监视列表。',
+'addedwatchtext' => '页面“[[:$1]]”已添加至你的[[Special:Watchlist|监视列表]]。本页面及其讨论页面的新增更改将会列入监视列表。',
 'removewatch' => '从监视列表中删除',
-'removedwatchtext' => '页面“[[:$1]]”已从[[Special:Watchlist|的监视列表]]中删除。',
+'removedwatchtext' => '页面“[[:$1]]”已从[[Special:Watchlist|的监视列表]]中删除。',
 'watch' => '监视',
 'watchthispage' => '监视本页',
 'unwatch' => '取消监视',
@@ -2274,9 +2262,9 @@ $1',
 'notanarticle' => '非内容页面',
 'notvisiblerev' => '上次由不同用户所作的修订版本已经删除',
 'watchnochange' => '在显示的时间段内您所监视的页面没有更改。',
-'watchlist-details' => '不包括讨论页面,您的监视列表中有$1个页面。',
+'watchlist-details' => '不计讨论页面,你的监视列表中有$1个页面。',
 'wlheader-enotif' => '* 已经启动电子邮件通知功能。',
-'wlheader-showupdated' => "* 在您上次查看后有被修改过的页面会以'''粗体'''的形式被显示",
+'wlheader-showupdated' => "*你上次访问后更改的页面以'''粗体'''显示",
 'watchmethod-recent' => '检查被监视页面的最近编辑',
 'watchmethod-list' => '查看监视页中的最新修改',
 'watchlistcontains' => '您的监视列表包含$1个页面。',
@@ -2293,39 +2281,40 @@ $1',
 'enotif_mailer' => '{{SITENAME}}通知发送器',
 'enotif_reset' => '标记所有页面为已访问',
 'enotif_impersonal_salutation' => '{{SITENAME}}用户',
-'enotif_subject_deleted' => '{{SITENAME}}的$1页面被$2删除',
-'enotif_subject_created' => '{{SITENAME}}的$1页面被$2创建',
-'enotif_subject_moved' => '{{SITENAME}}的$1页面被$2移动',
-'enotif_subject_restored' => '{{SITENAME}}的$1页面被$2恢复',
-'enotif_subject_changed' => '{{SITENAME}}的$1页面被$2修改',
-'enotif_body_intro_deleted' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}删除,见 $3 。',
-'enotif_body_intro_created' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}创建,在 $3 可以查看当前版本。',
-'enotif_body_intro_moved' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}移动,在 $3 可以查看当前版本。',
-'enotif_body_intro_restored' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}恢复,在 $3 可以查看当前版本。',
-'enotif_body_intro_changed' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}修改,在 $3 可以查看当前版本。',
-'enotif_lastvisited' => '请浏览 $1 查看从您上次访问后的所有更改。',
-'enotif_lastdiff' => '请浏览 $1 查看该更改。',
+'enotif_subject_deleted' => '{{SITENAME}}页面$1已被$2删除',
+'enotif_subject_created' => '{{SITENAME}}页面$1已被$2创建',
+'enotif_subject_moved' => '{{SITENAME}}页面$1已被$2移动',
+'enotif_subject_restored' => '{{SITENAME}}页面$1已被$2恢复',
+'enotif_subject_changed' => '{{SITENAME}}页面$1已被$2更改',
+'enotif_body_intro_deleted' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|删除}},请见$3。',
+'enotif_body_intro_created' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|创建}},请浏览$3查看当前版本。',
+'enotif_body_intro_moved' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|移动}},请浏览$3查看当前版本。',
+'enotif_body_intro_restored' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|恢复}},请浏览$3查看当前版本。',
+'enotif_body_intro_changed' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|更改}},请浏览$3查看当前版本。',
+'enotif_lastvisited' => '请浏览$1查看你上次访问后的所有更改。',
+'enotif_lastdiff' => '请浏览$1查看该更改。',
 'enotif_anon_editor' => '匿名用户$1',
-'enotif_body' => '亲爱的 $WATCHINGUSERNAME:
+'enotif_body' => '亲爱的$WATCHINGUSERNAME:
 
-$PAGEINTRO $NEWPAGE
+你好!
 
+$PAGEINTRO$NEWPAGE
 编辑摘要:$PAGESUMMARY $PAGEMINOREDIT
 
-您可以通过以下方式联系编辑者:
+你可以通过以下方式联系编者:
 电子邮件:$PAGEEDITOR_EMAIL
-wiki: $PAGEEDITOR_WIKI
-
-在您访问该页面之前,我们不会发送新增更改的通知。您也可以重设您的监视列表中所有监视页面的通知标志。
+用户页面:$PAGEEDITOR_WIKI
 
-友好的{{SITENAME}}通知系统
+在你访问该页面之前,我们不会发送新增更改的通知。
+你也可以重设你的监视列表中所有监视页面的通知标志。
 
+{{SITENAME}}通知系统
 --
 更改邮件通知设置:
 {{canonicalurl:{{#special:Preferences}}}}
 更改监视列表设置:
 {{canonicalurl:{{#special:EditWatchlist}}}}
-从监视列表中删除本页
+从监视列表中删除该页面
 $UNWATCHURL
 反馈与其他帮助:
 {{canonicalurl:{{MediaWiki:Helppage}}}}',
@@ -2413,6 +2402,7 @@ $UNWATCHURL
 'protect-fallback' => '仅允许拥有“$1”权限的用户',
 'protect-level-autoconfirmed' => '仅允许自动确认用户',
 'protect-level-sysop' => '仅允许管理员',
+'protect-summary-desc' => '[$1=$2]($3)',
 'protect-summary-cascade' => '联锁',
 'protect-expiring' => '终止于$1(UTC)',
 'protect-expiring-local' => '$1到期',
@@ -2493,13 +2483,13 @@ $1',
 'undelete-error-long' => '恢复被删除的文件时出错:
 
 $1',
-'undelete-show-file-confirm' => '确定要查看在 $2 $3 ,"<nowiki>$1</nowiki>"的已删除修订版本吗?',
+'undelete-show-file-confirm' => '确定要查看文件“<nowiki>$1</nowiki>”于$2$3被删除版本吗?',
 'undelete-show-file-submit' => '是',
 
 # Namespace form on various pages
 'namespace' => '名字空间:',
 'invert' => '反选',
-'tooltip-invert' => '选中此复选框来隐藏选定名字空间(及其相关名字空间,若该选项也被选中)范围内的页面更改',
+'tooltip-invert' => '请选择该框以隐藏指定名字空间(及相关名字空间,若被选择)的页面更改',
 'namespace_association' => '相关名字空间',
 'tooltip-namespace_association' => '选中此复选框可包括与选定名字空间相关的讨论页或子页面',
 'blanknamespace' => '(主要)',
@@ -2518,7 +2508,7 @@ $1',
 'sp-contributions-newbies-sub' => '新手',
 'sp-contributions-newbies-title' => '新手的用户贡献',
 'sp-contributions-blocklog' => '封禁日志',
-'sp-contributions-deleted' => '删除的用户贡献',
+'sp-contributions-deleted' => '删除的用户贡献',
 'sp-contributions-uploads' => '上传',
 'sp-contributions-logs' => '日志',
 'sp-contributions-talk' => '讨论',
@@ -2575,7 +2565,7 @@ $1',
 ** 不能接受的用户名',
 'ipb-hardblock' => '阻止登录用户使用该IP地址编辑',
 'ipbcreateaccount' => '阻止创建新账号',
-'ipbemailban' => '阻止用户发送邮件',
+'ipbemailban' => '阻止用户发送电子邮件',
 'ipbenableautoblock' => '自动封禁该用户最后使用的IP地址,以及他们随后试图用于编辑的所有IP地址',
 'ipbsubmit' => '封禁该用户',
 'ipbother' => '其它时间:',
@@ -2623,9 +2613,9 @@ $1',
 'infiniteblock' => '无限期',
 'expiringblock' => '$1 $2到期',
 'anononlyblock' => '仅匿名用户',
-'noautoblockblock' => 'è\87ªå\8a¨å°\81ç¦\81å·²ç¦\81用',
-'createaccountblock' => '创建帐户已禁用',
-'emailblock' => '发送邮件已禁用',
+'noautoblockblock' => 'è\87ªå\8a¨å°\81ç¦\81å\81\9c用',
+'createaccountblock' => '账户创建停用',
+'emailblock' => '电子邮件停用',
 'blocklist-nousertalk' => '不能编辑自己的讨论页面',
 'ipblocklist-empty' => '封禁列表为空。',
 'ipblocklist-no-results' => '请求的IP地址或用户名没有被封禁。',
@@ -2633,7 +2623,7 @@ $1',
 'unblocklink' => '解封',
 'change-blocklink' => '更改封禁',
 'contribslink' => '贡献',
-'emaillink' => '发送邮件',
+'emaillink' => '发送电子邮件',
 'autoblocker' => '由于您与“[[User:$1|$1]]”共享一个IP地址而被自动封禁。
 $1被封禁的理由是:“$2”',
 'blocklogpage' => '封禁日志',
@@ -2644,9 +2634,9 @@ $1被封禁的理由是:“$2”',
 'blocklogtext' => '这是用户封禁和解封操作的日志。自动封禁IP地址没有列出。请见[[Special:BlockList|封禁列表]]查看目前正在进行的阻止和封禁的列表。',
 'unblocklogentry' => '解封$1',
 'block-log-flags-anononly' => '仅限匿名用户',
-'block-log-flags-nocreate' => '创建帐户已禁用',
-'block-log-flags-noautoblock' => 'è\87ªå\8a¨å°\81ç¦\81å·²ç¦\81用',
-'block-log-flags-noemail' => '邮件功能已禁用',
+'block-log-flags-nocreate' => '账户创建停用',
+'block-log-flags-noautoblock' => 'è\87ªå\8a¨å°\81ç¦\81å\81\9c用',
+'block-log-flags-noemail' => '电子邮件停用',
 'block-log-flags-nousertalk' => '不能编辑自己的讨论页面',
 'block-log-flags-angry-autoblock' => '已启用增强型自动封禁',
 'block-log-flags-hiddenname' => '隐藏用户名',
@@ -2727,14 +2717,14 @@ $1被封禁的理由是:“$2”',
 
 在这些情况下,您在必要时必须手工移动或合并页面。",
 'movearticle' => '移动页面:',
-'moveuserpage-warning' => "'''警告:'''将移动一个用户页面。请注意,只有该页面会被移动,该用户''不''会被更名。",
+'moveuserpage-warning' => "'''警告:'''将移动一个用户页面。请注意,只有该页面会被移动,该用户''不''会被更名。",
 'movenologin' => '未登录',
 'movenologintext' => '您必须是一名登记用户并且[[Special:UserLogin|登录]]
 后才可移动一个页面。',
-'movenotallowed' => '没有权限移动页面。',
-'movenotallowedfile' => '没有权限移动文件。',
-'cant-move-user-page' => '没有权限移动用户页面(子页面除外)。',
-'cant-move-to-user-page' => '没有权限移动页面至用户页面(用户子页面除外)。',
+'movenotallowed' => '没有权限移动页面。',
+'movenotallowedfile' => '没有权限移动文件。',
+'cant-move-user-page' => '没有权限移动用户页面(子页面除外)。',
+'cant-move-to-user-page' => '没有权限移动页面至用户页面(用户子页面除外)。',
 'newtitle' => '新标题:',
 'move-watch' => '监视来源页面和目标页面',
 'movepagebtn' => '移动页面',
@@ -2896,43 +2886,43 @@ $1被封禁的理由是:“$2”',
 # JavaScriptTest
 'javascripttest' => 'JavaScript测试',
 'javascripttest-title' => '运行$1测试',
-'javascripttest-pagetext-noframework' => '此页é\9d¢è¢«ä¿\9dç\95\99ç\94¨ä½\9cæ\89§è¡\8c JavaScript 测试。',
+'javascripttest-pagetext-noframework' => 'æ\9c¬é¡µé\9d¢è¢«ä¿\9dç\95\99è¿\9bè¡\8cJavaScript测试。',
 'javascripttest-pagetext-unknownframework' => '未知的框架“$1”。',
 'javascripttest-pagetext-frameworks' => '请选择以下的框架之一:$1',
 'javascripttest-pagetext-skins' => '选择外观来运行测试:',
-'javascripttest-qunit-intro' => '请浏览 mediawiki.org 查看[$1 测试文档]。',
+'javascripttest-qunit-intro' => '请见mediawiki.org的[$1 测试说明文件]。',
 'javascripttest-qunit-heading' => 'MediaWiki JavaScript QUnit 测试套件',
 
 # Tooltip help for the actions
-'tooltip-pt-userpage' => '的用户页面',
-'tooltip-pt-anonuserpage' => '您用于编辑的 IP 地址的用户页面',
-'tooltip-pt-mytalk' => '的讨论页面',
+'tooltip-pt-userpage' => '的用户页面',
+'tooltip-pt-anonuserpage' => '你用于编辑的IP地址的用户页面',
+'tooltip-pt-mytalk' => '的讨论页面',
 'tooltip-pt-anontalk' => '有关本IP地址的编辑的讨论',
-'tooltip-pt-preferences' => '的系统设置',
-'tooltip-pt-watchlist' => '您正在监视的页面的列表',
-'tooltip-pt-mycontris' => '的贡献列表',
-'tooltip-pt-login' => '我们鼓励您登录,但这不是必须的',
-'tooltip-pt-anonlogin' => '我们鼓励您登录,但这不是必须的',
-'tooltip-pt-logout' => '注销',
+'tooltip-pt-preferences' => '的系统设置',
+'tooltip-pt-watchlist' => '你正在监视更改的页面的列表',
+'tooltip-pt-mycontris' => '的贡献列表',
+'tooltip-pt-login' => '我们鼓励你登录,不过这不是强制的',
+'tooltip-pt-anonlogin' => '我们鼓励你登录,不过这不是强制的',
+'tooltip-pt-logout' => '退出登录',
 'tooltip-ca-talk' => '有关内容页面的讨论',
-'tooltip-ca-edit' => '您可以编辑本页。请在保存前使用预览按钮查看修改。',
+'tooltip-ca-edit' => '你可以编辑本页面。请在保存前使用预览按钮。',
 'tooltip-ca-addsection' => '开始新段落',
-'tooltip-ca-viewsource' => '本页面受保护。您可以查看它的源代码。',
-'tooltip-ca-history' => '本页面的历史版本',
+'tooltip-ca-viewsource' => '本页面受到保护。你可以查看其源代码。',
+'tooltip-ca-history' => '本页面过去的版本',
 'tooltip-ca-protect' => '保护本页',
 'tooltip-ca-unprotect' => '更改本页面的保护',
 'tooltip-ca-delete' => '删除本页',
 'tooltip-ca-undelete' => '将这个页面恢复到被删除以前的状态',
 'tooltip-ca-move' => '移动本页',
-'tooltip-ca-watch' => '添加本页面至的监视列表',
-'tooltip-ca-unwatch' => '从您的监视列表中删除本页',
+'tooltip-ca-watch' => '添加本页面至的监视列表',
+'tooltip-ca-unwatch' => '从你的监视列表删除本页面',
 'tooltip-search' => '在{{SITENAME}}中搜索',
 'tooltip-search-go' => '如果相同的标题存在的话便直接前往该页面',
 'tooltip-search-fulltext' => '搜索含这些文字的页面',
 'tooltip-p-logo' => '访问首页',
 'tooltip-n-mainpage' => '访问首页',
 'tooltip-n-mainpage-description' => '访问首页',
-'tooltip-n-portal' => '关于本项目,您可以做些什么,在哪里可以找到您需要的东西',
+'tooltip-n-portal' => '关于本项目,你可以做什么,在哪里找到你需要的事物',
 'tooltip-n-currentevents' => '查看当前事件的背景信息',
 'tooltip-n-recentchanges' => '本wiki的最近更改列表',
 'tooltip-n-randompage' => '载入一个随机页面',
@@ -2950,7 +2940,7 @@ $1被封禁的理由是:“$2”',
 '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' => '查看系统信息',
@@ -2962,14 +2952,14 @@ $1被封禁的理由是:“$2”',
 'tooltip-preview' => '预览您的更改,请在保存前使用此功能!',
 'tooltip-diff' => '显示您对该文字所做的更改',
 'tooltip-compareselectedversions' => '查看此页面两个选定的修订版本间的差异。',
-'tooltip-watch' => '添加本页面至的监视列表',
+'tooltip-watch' => '添加本页面至的监视列表',
 'tooltip-watchlistedit-normal-submit' => '删除标题',
 'tooltip-watchlistedit-raw-submit' => '更新监视列表',
 'tooltip-recreate' => '重建该页面,无论是否被删除。',
 'tooltip-upload' => '开始上传',
-'tooltip-rollback' => '击“回退”恢复上一位贡献者对本页的编辑',
+'tooltip-rollback' => '击“回退”恢复上一位贡献者对本页的编辑',
 'tooltip-undo' => '“撤销”可以恢复该编辑并在预览模式下打开编辑表单。它允许在摘要中加入原因。',
-'tooltip-preferences-save' => '保存设置',
+'tooltip-preferences-save' => '保存系统设置',
 'tooltip-summary' => '请输入简短的摘要',
 
 # Stylesheets
@@ -3002,6 +2992,10 @@ $1被封禁的理由是:“$2”',
 'simple.js' => '/* 此处的JavaScript将加载于使用Simple皮肤的用户 */',
 'modern.js' => '/* 此处的JavaScript将加载于使用Modern皮肤的用户 */',
 'vector.js' => '/* 此处的JavaScript将加载于使用Vector皮肤的用户 */',
+'group-autoconfirmed.js' => '/* 此处的JavaScript将仅加载于自动确认用户 */',
+'group-bot.js' => '/* 此处的JavaScript将仅加载于机器人 */',
+'group-sysop.js' => '/* 此处的JavaScript将仅加载于管理员 */',
+'group-bureaucrat.js' => '/* 此处的JavaScript将仅加载于行政员 */',
 
 # Metadata
 'notacceptable' => '该网站服务器不能提供您的客户端能识别的数据格式。',
@@ -3045,6 +3039,7 @@ $1被封禁的理由是:“$2”',
 'pageinfo-robot-noindex' => '不可索引',
 'pageinfo-views' => '查看次数',
 'pageinfo-watchers' => '页面监视者人数',
+'pageinfo-few-watchers' => '少于$1名监视者',
 'pageinfo-redirects-name' => '重定向到本页',
 'pageinfo-subpages-name' => '本页的子页面',
 'pageinfo-subpages-value' => '$1 ($2个重定向;$3个非重定向)',
@@ -3070,7 +3065,7 @@ $1被封禁的理由是:“$2”',
 'pageinfo-protect-cascading-from' => '保护级联自',
 'pageinfo-category-info' => '分类信息',
 'pageinfo-category-pages' => '页数',
-'pageinfo-category-subcats' => '子类别数',
+'pageinfo-category-subcats' => '子分类数',
 'pageinfo-category-files' => '文件数',
 
 # Skin names
@@ -3088,8 +3083,8 @@ $1被封禁的理由是:“$2”',
 'rcpatroldisabled' => '最新更改检查被关闭',
 'rcpatroldisabledtext' => '最新更改检查的功能目前已关闭。',
 'markedaspatrollederror' => '不能标志为已检查',
-'markedaspatrollederrortext' => '您需要指定某个版本才能标记为已检查。',
-'markedaspatrollederror-noautopatrol' => '您无法将自己所作的更改标记为已检查。',
+'markedaspatrollederrortext' => '你需要指定一个版本以标记为已巡查。',
+'markedaspatrollederror-noautopatrol' => '你不能把自己的更改标记为已检查。',
 'markedaspatrollednotify' => '$1的更改已被标记为已巡查。',
 'markedaspatrollederrornotify' => '标记为已巡查失败。',
 
@@ -3114,7 +3109,7 @@ $1',
 'nextdiff' => '下一编辑→',
 
 # Media information
-'mediawarning' => "'''警告''':该类型的文件可能包含恶意代码。执行后您的系统可能会受损。",
+'mediawarning' => "'''警告''':该文件类型可能含有恶意代码。执行后你的系统可能受损。",
 'imagemaxsize' => '图像大小限制:<br /><u>(文件描述页)</u>',
 'thumbsize' => '缩略图大小:',
 'widthheightpage' => '$1×$2,$3页',
@@ -3122,11 +3117,11 @@ $1',
 'file-info-size' => '$1×$2像素,文件大小:$3,MIME类型:$4',
 'file-info-size-pages' => '$1×$2像素,文件大小:$3,MIME类型:$4,$5页',
 'file-nohires' => '没有更高的分辨率。',
-'svg-long-desc' => 'SVGæ\96\87件ï¼\8cå\9b¾å\83\8f大å°\8fï¼\9a$1 × $2像素,文件大小:$3',
-'svg-long-desc-animated' => 'å\8a¨ç\94»SVGæ\96\87件ï¼\8cå\9b¾å\83\8f大å°\8f为$1 × $2像素,文件大小:$3',
+'svg-long-desc' => 'SVGæ\96\87件ï¼\8c尺寸为$1 × $2像素,文件大小:$3',
+'svg-long-desc-animated' => 'å\8a¨ç\94»SVGæ\96\87件ï¼\8c尺寸为$1 × $2像素,文件大小:$3',
 'svg-long-error' => '无效的SVG文件:$1',
 'show-big-image' => '完全分辨率',
-'show-big-image-preview' => 'æ\9c¬é¢\84è§\88ç\9a\84大å°\8f:$1。',
+'show-big-image-preview' => 'æ\9c¬é¢\84è§\88ç\9a\84尺寸:$1。',
 'show-big-image-other' => '其他{{PLURAL:$2|分辨率}}:$1。',
 'show-big-image-size' => '$1×$2像素',
 'file-info-gif-looped' => '循环',
@@ -3150,12 +3145,16 @@ $1',
 'sp-newimages-showfrom' => '从$1 $2开始显示新文件',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'seconds-abbrev' => '$1秒',
+'minutes-abbrev' => '$1分',
+'hours-abbrev' => '$1小时',
+'days-abbrev' => '$1天',
 'seconds' => '$1秒',
 'minutes' => '$1分',
 'hours' => '$1小时',
 'days' => '$1天',
-'months' => '{{PLURAL:$1|$1个月|$1个月}}',
-'years' => '{{PLURAL:$1|$1年|$1年}}',
+'months' => '{{PLURAL:$1|$1个月}}',
+'years' => '{{PLURAL:$1|$1年}}',
 'ago' => '$1前',
 'just-now' => '刚刚',
 
@@ -3182,11 +3181,11 @@ Variants for Chinese language
 'variantname-zh' => '不转换',
 
 # Variants for Gan language
-'variantname-gan-hans' => '‪中文(简体)',
-'variantname-gan-hant' => '‪中文(繁体)',
+'variantname-gan-hans' => 'hans',
+'variantname-gan-hant' => 'hant',
 
 # Variants for Kazakh language
-'variantname-kk-cyrl' => '',
+'variantname-kk-cyrl' => 'kk-cyrl',
 
 # Metadata
 'metadata' => '原始数据',
@@ -3613,7 +3612,7 @@ Variants for Chinese language
 
 # E-mail address confirmation
 'confirmemail' => '确认邮箱地址',
-'confirmemail_noemail' => '您还没有在您的[[Special:Preferences|个人设置]]中设置有效的电子邮件地址。',
+'confirmemail_noemail' => '你还没有在你的[[Special:Preferences|系统设置]]中设置有效的电子邮件地址。',
 'confirmemail_text' => '{{SITENAME}}要求您在使用邮件功能之前验证您的邮箱地址。
 点击以下按钮可向您的邮箱发送一封确认邮件。该邮件包含有一行代码链接;
 请在您的浏览器中加载此链接以确认您的邮箱地址是有效的。',
@@ -3628,8 +3627,8 @@ Variants for Chinese language
 'confirmemail_needlogin' => '您需要$1以确认您的邮箱地址。',
 'confirmemail_success' => '您的邮箱已经被确认。您现在可以[[Special:UserLogin|登录]]并使用此网站了。',
 'confirmemail_loggedin' => '您的邮箱地址现在已被确认。',
-'confirmemail_error' => '在确认您的过程中发生错误。',
-'confirmemail_subject' => '来自{{SITENAME}}的电子邮件地址确认函',
+'confirmemail_error' => '保存你的确认时出错。',
+'confirmemail_subject' => '{{SITENAME}}电子邮件地址确认',
 'confirmemail_body' => '来自IP地址$1的用户(可能是您)在{{SITENAME}}上创建了账户“$2”,并提交了您
 的电子邮箱地址。
 
@@ -3668,8 +3667,8 @@ $3
 $5
 
 确认码会在$4过期。',
-'confirmemail_invalidated' => '邮件地址确认已取消',
-'invalidateemail' => '取消邮件地址确认',
+'confirmemail_invalidated' => '电子邮件地址确认已取消',
+'invalidateemail' => '取消电子邮件确认',
 
 # Scary transclusion
 'scarytranscludedisabled' => '[跨网站的编码转换不可用]',
@@ -3742,13 +3741,13 @@ $5
 'lag-warn-high' => '由于数据库的过度延迟,过去$1秒的更改未必会在这个列表中显示。',
 
 # Watchlist editor
-'watchlistedit-numitems' => '不包括讨论页面,您的监视列表包含$1个标题。',
-'watchlistedit-noitems' => '的监视列表中没有标题。',
+'watchlistedit-numitems' => '不计讨论页面,你的监视列表包含$1个标题。',
+'watchlistedit-noitems' => '的监视列表中没有标题。',
 'watchlistedit-normal-title' => '编辑监视列表',
 'watchlistedit-normal-legend' => '删除监视列表中的标题',
-'watchlistedit-normal-explain' => '您的监视列表中的标题会显示在下方。要删除标题,请勾选它前面的选择框并点击“{{int:Watchlistedit-normal-submit}}”。您也可以[[Special:EditWatchlist/raw|编辑原始列表]]。',
+'watchlistedit-normal-explain' => '你的监视列表中的标题显示在下方。要删除标题,请勾选它前面选择框并单击“{{int:Watchlistedit-normal-submit}}”。你也可以[[Special:EditWatchlist/raw|编辑原始列表]]。',
 'watchlistedit-normal-submit' => '删除标题',
-'watchlistedit-normal-done' => '已从您的监视列表删除了$1个标题:',
+'watchlistedit-normal-done' => '已从你的监视列表删除$1个标题:',
 'watchlistedit-raw-title' => '编辑原始监视列表',
 'watchlistedit-raw-legend' => '编辑原始监视列表',
 'watchlistedit-raw-explain' => '您的监视列表中的标题在下面显示,同时也可以可以通过编辑这个表去加入以及移除标题;一行一个标题。当完成以后,点击{{int:Watchlistedit-raw-submit}}。您也可以使用[[Special:EditWatchlist|标准编辑器]]。',
@@ -3791,11 +3790,11 @@ $5
 'version-poweredby-credits' => "本Wiki由'''[//www.mediawiki.org/ MediaWiki]'''驱动,版权所有 © 2001-$1 $2。",
 'version-poweredby-others' => '其他',
 'version-credits-summary' => '我们感谢下列人士为[[Special:Version|MediaWiki]]作出的贡献。',
-'version-license-info' => 'MediaWiki 是一款自由软件;您可根据自由软件基金会所发表的 GNU 通用公共许可证条款规定,无论您依据的是本授权的第二版或(您自行选择的)任一日后发行的版本,将本程序再发布与/或做出修改
+'version-license-info' => "MediaWiki是自由软件,你可以依据自由软件基金会发行的'''GNU公众授权协议'''第2版或任意后续版本的条款,传播和/或修改本软件
 
-MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任;也没有对适售性或特定目的适用性所为的默示性担保。详情请参照 GNU 通用公共许可证条款
+MediaWiki发表时预期有用,但对此'''无任何保证''',亦无隐含的'''可以销售'''或'''适合特定目的'''的保证。详情请见GNU公众授权协议
 
-您应已收到附随于本程序的[{{SERVER}}{{SCRIPTPATH}}/COPYING GNU 通用公共许可证副本];如果没有,请发送邮件至自由软件基金会:51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA,或[//www.gnu.org/licenses/old-licenses/gpl-2.0.html 在线阅读]。',
+你应该已经接受本程序附带的[{{SERVER}}{{SCRIPTPATH}}/COPYING GNU公众授权协议的副本]。如果没有,请写信至美国马萨诸塞州波士顿富兰克林大街51号5楼自由软件基金会,邮编MA 02110-1301(Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA),或[//www.gnu.org/licenses/old-licenses/gpl-2.0.html 在线阅读该协议]。",
 'version-software' => '已安装的软件',
 'version-software-product' => '产品',
 'version-software-version' => '版本',
@@ -3809,7 +3808,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'filepath' => '文件路径',
 'filepath-page' => '文件名:',
 'filepath-submit' => '提交',
-'filepath-summary' => 'æ­¤ç\89¹æ®\8a页é\9d¢è¿\94å\9b\9eæ\96\87件ç\9a\84å®\8cæ\95´è·¯å¾\84ã\80\82å\9b¾å\83\8fä¼\9a以å®\8cæ\95´ç\9a\84å\88\86辨ç\8e\87æ\98¾ç¤ºï¼\8cå\85¶å®\83ç\9a\84æ\96\87件类å\9e\8bä¹\9få°\86ç\9b´æ\8e¥é\80\9aè¿\87å\85³è\81\94ç\9a\84åº\94ç\94¨ç¨\8båº\8f打开。',
+'filepath-summary' => 'æ\9c¬ç\89¹æ®\8a页é\9d¢è¿\94å\9b\9eæ\96\87件ç\9a\84å®\8cæ\95´è·¯å¾\84ã\80\82å\9b¾å\83\8f以å®\8cæ\95´å\88\86辨ç\8e\87æ\98¾ç¤ºï¼\8cå\85¶å®\83æ\96\87件类å\9e\8b以å\85³è\81\94ç¨\8båº\8fç\9b´æ\8e¥打开。',
 
 # Special:FileDuplicateSearch
 'fileduplicatesearch' => '搜索重复文件',
@@ -3836,7 +3835,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'specialpages-group-highuse' => '高度使用页面',
 'specialpages-group-pages' => '页面列表',
 'specialpages-group-pagetools' => '页面工具',
-'specialpages-group-wiki' => 'Wiki数据与工具',
+'specialpages-group-wiki' => '数据与工具',
 'specialpages-group-redirects' => '重定向特殊页面',
 'specialpages-group-spam' => '反垃圾链接工具',
 
@@ -3877,7 +3876,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'compare-submit' => '对比',
 'compare-invalid-title' => '您指定的标题无效。',
 'compare-title-not-exists' => '您指定的标题不存在。',
-'compare-revision-not-exists' => '您指定的修订版本不存在。',
+'compare-revision-not-exists' => '你指定的版本不存在。',
 
 # Database error messages
 'dberr-header' => '本wiki出现了问题',
@@ -3934,15 +3933,15 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'logentry-newusers-newusers' => '已创建用户帐户 $1',
 'logentry-newusers-create' => '创建用户帐户$1',
 'logentry-newusers-create2' => '创建用户帐户 $3 由 $1',
+'logentry-newusers-byemail' => '$1创建用户$3并将密码用电子邮件发送',
 'logentry-newusers-autocreate' => '账户$1被自动创建',
-'newuserlog-byemail' => '密码已用电子邮件发送',
 'logentry-rights-rights' => '$1将$3的用户组从$4改为$5',
 'logentry-rights-rights-legacy' => '$1更改$3的用户组',
 'logentry-rights-autopromote' => '$1的用户组已自动从$4改为$5',
 'rightsnone' => '(无)',
 
 # Feedback
-'feedback-bugornote' => '如果您准备好详细描述一个技术问题,请[$1 报告bug]。或者您也可以使用下面的简单表格。您的评论将被添加至页面“[$3 $2]”,附有您的用户名和所使用的浏览器。',
+'feedback-bugornote' => '如果你准备好详细描述一个技术问题,请[$1 报告bug]。或者你可以使用下面的简单表格。你的评论将被添加至页面“[$3 $2]”,附有你的用户名和使用的浏览器。',
 'feedback-subject' => '主题:',
 'feedback-message' => '信息:',
 'feedback-cancel' => '取消',
@@ -3951,7 +3950,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'feedback-error1' => '错误:从API返回无法识别的结果',
 'feedback-error2' => '错误:编辑失败',
 'feedback-error3' => '错误:API没有响应',
-'feedback-thanks' => '谢谢!的反馈已发布至页面“[$2 $1]”。',
+'feedback-thanks' => '谢谢!的反馈已发布至页面“[$2 $1]”。',
 'feedback-close' => '完成',
 'feedback-bugcheck' => '请检查本bug是否为[$1 已知bug]。',
 'feedback-bugnew' => '我检查了。报告新bug',
@@ -3992,13 +3991,14 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'api-error-ok-but-empty' => '内部错误:服务器没有响应。',
 'api-error-overwrite' => '不允许覆盖现有文件。',
 'api-error-stashfailed' => '内部错误:服务器保存临时文件失败。',
+'api-error-publishfailed' => '内部错误:服务器发布临时文件失败。',
 'api-error-timeout' => '服务器没有在预期内响应。',
 'api-error-unclassified' => '出现未知错误。',
 'api-error-unknown-code' => '未知错误:$1',
 'api-error-unknown-error' => '内部错误:尝试上传文件时出错。',
 'api-error-unknown-warning' => '未知的警告:$1',
 'api-error-unknownerror' => '未知错误:$1。',
-'api-error-uploaddisabled' => '该 wiki 禁用上传功能。',
+'api-error-uploaddisabled' => '该wiki停用上传。',
 'api-error-verification-error' => '该文件可能损坏或扩展名错误。',
 
 # Durations
index 01534a2..b550cab 100644 (file)
@@ -109,12 +109,14 @@ $specialPageAliases = array(
        'Allmessages'               => array( '所有信息' ),
        'Allpages'                  => array( '所有頁面' ),
        'Ancientpages'              => array( '最早頁面' ),
+       'Badtitle'                  => array( '無效標題' ),
        'Blankpage'                 => array( '空白頁面' ),
        'Block'                     => array( '查封用戶' ),
        'Blockme'                   => array( '封禁我' ),
        'Booksources'               => array( '網絡書源' ),
        'BrokenRedirects'           => array( '損壞的重定向頁' ),
        'Categories'                => array( '頁面分類' ),
+       'ChangeEmail'               => array( '修改郵箱' ),
        'ChangePassword'            => array( '修改密碼' ),
        'ComparePages'              => array( '頁面比較' ),
        'Confirmemail'              => array( '確認電子郵件' ),
@@ -132,6 +134,7 @@ $specialPageAliases = array(
        'Filepath'                  => array( '文件路徑' ),
        'Import'                    => array( '導入頁面' ),
        'Invalidateemail'           => array( '不可識別的電郵地址' ),
+       'JavaScriptTest'            => array( 'JavaScript測試' ),
        'BlockList'                 => array( '封禁列表' ),
        'LinkSearch'                => array( '搜索網頁鏈接' ),
        'Listadmins'                => array( '管理員列表' ),
@@ -148,6 +151,7 @@ $specialPageAliases = array(
        'MIMEsearch'                => array( 'MIME搜索' ),
        'Mostcategories'            => array( '最多分類頁面' ),
        'Mostimages'                => array( '最多鏈接文件' ),
+       'Mostinterwikis'            => array( '最多跨維基連結' ),
        'Mostlinked'                => array( '最多鏈接頁面' ),
        'Mostlinkedcategories'      => array( '最多鏈接分類' ),
        'Mostlinkedtemplates'       => array( '最多鏈接模板' ),
@@ -202,6 +206,44 @@ $specialPageAliases = array(
        'Withoutinterwiki'          => array( '沒有跨語言鏈接的頁面' ),
 );
 
+$magicWords = array(
+       'notoc'                     => array( '0', '__無目錄__', '__无目录__', '__NOTOC__' ),
+       'nogallery'                 => array( '0', '__無圖庫__', '__无图库__', '__NOGALLERY__' ),
+       'forcetoc'                  => array( '0', '__強制目錄__', '__强显目录__', '__FORCETOC__' ),
+       'toc'                       => array( '0', '__目錄__', '__目录__', '__TOC__' ),
+       'noeditsection'             => array( '0', '__無段落編輯__', '__无段落编辑__', '__NOEDITSECTION__' ),
+       'currentmonth'              => array( '1', '本月', 'CURRENTMONTH', 'CURRENTMONTH2' ),
+       'currentmonthabbrev'        => array( '1', '本月簡稱', '本月简称', 'CURRENTMONTHABBREV' ),
+       'currentday'                => array( '1', '今天', 'CURRENTDAY' ),
+       'currenttime'               => array( '1', '當前時間', '此時', '此时', '当前时间', 'CURRENTTIME' ),
+       'img_thumbnail'             => array( '1', '縮圖', '缩略图', 'thumbnail', 'thumb' ),
+       'img_manualthumb'           => array( '1', '縮圖=$1', '缩略图=$1', 'thumbnail=$1', 'thumb=$1' ),
+       'img_right'                 => array( '1', '右', 'right' ),
+       'img_left'                  => array( '1', '左', 'left' ),
+       'img_none'                  => array( '1', '無', '无', 'none' ),
+       'img_width'                 => array( '1', '$1像素', '$1px' ),
+       'img_center'                => array( '1', '置中', '居中', 'center', 'centre' ),
+       'img_framed'                => array( '1', '有框', 'framed', 'enframed', 'frame' ),
+       'img_frameless'             => array( '1', '無框', '无框', 'frameless' ),
+       'img_page'                  => array( '1', '頁=$1', '$1頁', '页数=$1', '$1页', 'page=$1', 'page $1' ),
+       'img_link'                  => array( '1', '連結=$1', '链接=$1', 'link=$1' ),
+       'sitename'                  => array( '1', '網站名稱', '站点名称', 'SITENAME' ),
+       'ns'                        => array( '0', '名字空間', '名字空间:', 'NS:' ),
+       'nse'                       => array( '0', '名字空間E', '名字空间E:', 'NSE:' ),
+       'localurl'                  => array( '0', '本地URL', '本地URL:', 'LOCALURL:' ),
+       'localurle'                 => array( '0', '本地URLE', '本地URLE:', 'LOCALURLE:' ),
+       'pageid'                    => array( '0', '頁面ID', '页面ID', 'PAGEID' ),
+       'server'                    => array( '0', '伺服器', '服务器', 'SERVER' ),
+       'servername'                => array( '0', '伺服器名稱', '服务器名', 'SERVERNAME' ),
+       'gender'                    => array( '0', '性別:', '性别:', 'GENDER:' ),
+       'notitleconvert'            => array( '0', '__不轉換標題__', '__不转换标题__', '__NOTITLECONVERT__', '__NOTC__' ),
+       'nocontentconvert'          => array( '0', '__不轉換內容__', '__不转换内容__', '__NOCONTENTCONVERT__', '__NOCC__' ),
+       'displaytitle'              => array( '1', '顯示標題', '显示标题', 'DISPLAYTITLE' ),
+       'currentversion'            => array( '1', '當前版本', '当前版本', 'CURRENTVERSION' ),
+       'hiddencat'                 => array( '1', '__隱藏分類__', '__隐藏分类__', '__HIDDENCAT__' ),
+       'staticredirect'            => array( '1', '__靜態重定向__', '__静态重定向__', '__STATICREDIRECT__' ),
+);
+
 $bookstoreList = array(
        '博客來書店' => 'http://www.books.com.tw/exep/prod/booksfile.php?item=$1',
        '三民書店' => 'http://www.sanmin.com.tw/page-qsearch.asp?ct=search_isbn&qu=$1',
@@ -476,7 +518,7 @@ $1',
 'youhavenewmessages' => '您有$1($2)。',
 'newmessageslink' => '新訊息',
 'newmessagesdifflink' => '最後更改',
-'youhavenewmessagesfromusers' => '你有來自{{PLURAL:$3| 另一位用戶| $3位用戶}}的$1 ( $2 )。',
+'youhavenewmessagesfromusers' => '你有來自{{PLURAL:$3|另一位用戶|$3位用戶}}的$1($2)。',
 'youhavenewmessagesmanyusers' => '你有來自多位用戶的$1( $2 )。',
 'newmessageslinkplural' => '{{PLURAL:$1|一項新訊息|新訊息}}',
 'newmessagesdifflinkplural' => '最新{{PLURAL:$1|更改|更改}}',
@@ -628,7 +670,7 @@ $2',
 不要忘記設置[[Special:Preferences|{{SITENAME}}的個人參數]]。',
 'yourname' => '用戶名:',
 'yourpassword' => '您的密碼:',
-'yourpasswordagain' => '再次輸入密:',
+'yourpasswordagain' => '再次輸入密:',
 'remembermypassword' => '在這個瀏覽器上記住我的登入資訊(可維持 $1 {{PLURAL:$1|天|天}})',
 'securelogin-stick-https' => '登入後繼續以HTTPS連接',
 'yourdomainname' => '您的網域:',
@@ -648,7 +690,7 @@ $2',
 'gotaccount' => '已經擁有帳號?$1。',
 'gotaccountlink' => '登入',
 'userlogin-resetlink' => '忘記了你的登錄信息?',
-'createaccountmail' => '通過電郵',
+'createaccountmail' => '使用一個臨時的隨機密碼,並將它發送到以下指定的電子郵件地址',
 'createaccountreason' => '理由:',
 'badretype' => '您所輸入的密碼並不相同。',
 'userexists' => '!您所輸入的用戶名稱已經存在,請另選一個名稱。',
@@ -933,7 +975,8 @@ $2
 '''不要在未獲授權的情況下發表!'''",
 'longpageerror' => "'''錯誤:您所提交的文本長度有{{PLURAL:$1|1|$1}}KB,這大於{{PLURAL:$2|1|$2}}KB的最大值。 '''
 因此,該文本無法保存。",
-'readonlywarning' => "'''警告: 資料庫被鎖定以進行維護,所以您目前將無法保存您的修改。'''您或許希望先將本段文字複製並保存到文字檔案,然後等一會兒再修改。
+'readonlywarning' => "'''警告: 資料庫被鎖定以進行維護,所以您目前將無法保存您的修改。'''
+您可先複製您的文字並保存到文字檔案,然後等一會兒再修改。
 
 鎖定資料庫的管理員有如下解釋:$1",
 'protectedpagewarning' => "'''警告:本頁已經被保護,只有擁有管理員許可權的用戶才可修改。'''
@@ -1221,7 +1264,7 @@ $1",
 'search-interwiki-default' => '$1項結果:',
 'search-interwiki-more' => '(更多)',
 'search-relatedarticle' => '相關',
-'mwsuggest-disable' => '停用AJAX建議',
+'mwsuggest-disable' => '停用搜尋建議',
 'searcheverything-enable' => '在所有名字空間中搜尋',
 'searchrelated' => '相關',
 'searchall' => '所有',
@@ -2338,6 +2381,7 @@ $UNWATCHURL
 'protect-fallback' => '僅允許有「$1」權限的用戶',
 'protect-level-autoconfirmed' => '僅允許自動確認使用者',
 'protect-level-sysop' => '僅允許管理員',
+'protect-summary-desc' => '[$1=$2]($3)',
 'protect-summary-cascade' => '連鎖',
 'protect-expiring' => '終止於 $1 (UTC)',
 'protect-expiring-local' => '$1到期',
@@ -2630,10 +2674,8 @@ $1被封禁的理由是“$2”',
 如果您選擇不去做的話,請檢查[[Special:DoubleRedirects|雙重]]或[[Special:BrokenRedirects|損壞重定向]]連結。
 您應當負責確定所有連結依然會連到指定的頁面。
 
-注意如果新頁面已經有內容的話,頁面將'''不會'''被移動,
-除非新頁面是重定向頁,而且沒有修訂歷史。
-這意味著您再必要時可以在移動到新頁面後再移回老的頁面,
-同時您也無法覆蓋現有頁面。
+注意如果新頁面已經有內容的話,頁面將'''不會'''被移動,除非新頁面是重定向頁,而且沒有修訂歷史。
+這意味著您再必要時可以在移動到新頁面後再移回老的頁面,同時您也無法覆蓋現有頁面。
 
 '''警告!'''
 對一個經常被訪問的頁面而言這可能是一個重大與唐突的更改;
@@ -2981,6 +3023,7 @@ $1被封禁的理由是“$2”',
 'pageinfo-robot-noindex' => '不可索引',
 'pageinfo-views' => '觀看次數',
 'pageinfo-watchers' => '頁面監視者數目',
+'pageinfo-few-watchers' => '少於$1名監視者',
 'pageinfo-redirects-name' => '重定向到此頁',
 'pageinfo-subpages-name' => '此頁面的子頁面',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|重定向|重定向}}; $3 {{PLURAL:$3|非重定向|非重定向}})',
@@ -3770,7 +3813,7 @@ MediaWiki是基於使用目的而加以發佈,然而不負任何擔保責任
 'specialpages-group-highuse' => '高度使用頁面',
 'specialpages-group-pages' => '頁面清單',
 'specialpages-group-pagetools' => '頁面工具',
-'specialpages-group-wiki' => 'Wiki 資料和工具',
+'specialpages-group-wiki' => '資料和工具',
 'specialpages-group-redirects' => '重新定向特殊頁面',
 'specialpages-group-spam' => '反垃圾工具',
 
@@ -3868,8 +3911,8 @@ MediaWiki是基於使用目的而加以發佈,然而不負任何擔保責任
 'logentry-newusers-newusers' => '已建立用戶「$1」',
 'logentry-newusers-create' => '已建立用戶「$1」',
 'logentry-newusers-create2' => '用戶「$1」建立用戶「$3」',
+'logentry-newusers-byemail' => '$1建立用戶$3並電郵密碼給他',
 'logentry-newusers-autocreate' => '帳戶$1被自動創建',
-'newuserlog-byemail' => '密碼已由電子郵件寄出',
 'logentry-rights-rights' => '$1將$3的權限從$4改為$5',
 'logentry-rights-rights-legacy' => '$1更改$3的權限',
 'logentry-rights-autopromote' => '$1的權限自動從$4改為$5',
@@ -3925,7 +3968,8 @@ MediaWiki是基於使用目的而加以發佈,然而不負任何擔保責任
 'api-error-nomodule' => '內部錯誤:缺少上傳模塊集。',
 'api-error-ok-but-empty' => '內部錯誤:伺服器沒有響應。',
 'api-error-overwrite' => '不允許覆蓋現有檔案。',
-'api-error-stashfailed' => '內部錯誤:伺服器保存臨時文件失敗。',
+'api-error-stashfailed' => '內部錯誤:伺服器保存臨時檔案失敗。',
+'api-error-publishfailed' => '內部錯誤:伺服器發佈臨時檔案失敗。',
 'api-error-timeout' => '伺服器沒有在預期的時間內回應。',
 'api-error-unclassified' => '發生未知錯誤。',
 'api-error-unknown-code' => '未知錯誤:$1',
index 6bb0666..590cad2 100644 (file)
@@ -32,7 +32,7 @@
  * @ingroup Maintenance
  */
 class SevenZipStream {
-       var $stream;
+       protected $stream;
 
        private function stripPath( $path ) {
                $prefix = 'mediawiki.compress.7z://';
index b0371c0..a13453d 100644 (file)
@@ -342,7 +342,7 @@ abstract class Maintenance {
         */
        protected function error( $err, $die = 0 ) {
                $this->outputChanneled( false );
-               if ( php_sapi_name() == 'cli' ) {
+               if ( PHP_SAPI == 'cli' ) {
                        fwrite( STDERR, $err . "\n" );
                } else {
                        print $err;
@@ -513,8 +513,11 @@ abstract class Maintenance {
                define( 'MEDIAWIKI', true );
 
                $wgCommandLineMode = true;
+
                # Turn off output buffering if it's on
-               @ob_end_flush();
+               while( ob_get_level() > 0 ) {
+                       ob_end_flush();
+               }
 
                $this->validateParamsAndArgs();
        }
@@ -920,7 +923,7 @@ abstract class Maintenance {
                if ( !is_readable( $settingsFile ) ) {
                        $this->error( "A copy of your installation's LocalSettings.php\n" .
                                                "must exist and be readable in the source directory.\n" .
-                                               "Use --conf to specify it." , true );
+                                               "Use --conf to specify it.", true );
                }
                $wgCommandLineMode = true;
                return $settingsFile;
@@ -936,13 +939,9 @@ abstract class Maintenance {
                $dbw = $this->getDB( DB_MASTER );
                $dbw->begin( __METHOD__ );
 
-               $tbl_arc = $dbw->tableName( 'archive' );
-               $tbl_rev = $dbw->tableName( 'revision' );
-               $tbl_txt = $dbw->tableName( 'text' );
-
                # Get "active" text records from the revisions table
                $this->output( 'Searching for active text records in revisions table...' );
-               $res = $dbw->query( "SELECT DISTINCT rev_text_id FROM $tbl_rev" );
+               $res = $dbw->select( 'revision', 'rev_text_id', array(), __METHOD__, array( 'DISTINCT' ) );
                foreach ( $res as $row ) {
                        $cur[] = $row->rev_text_id;
                }
@@ -950,16 +949,19 @@ abstract class Maintenance {
 
                # Get "active" text records from the archive table
                $this->output( 'Searching for active text records in archive table...' );
-               $res = $dbw->query( "SELECT DISTINCT ar_text_id FROM $tbl_arc" );
+               $res = $dbw->select( 'archive', 'ar_text_id', array(), __METHOD__, array( 'DISTINCT' ) );
                foreach ( $res as $row ) {
-                       $cur[] = $row->ar_text_id;
+                       # old pre-MW 1.5 records can have null ar_text_id's.
+                       if ( $row->ar_text_id !== null ) {
+                               $cur[] = $row->ar_text_id;
+                       }
                }
                $this->output( "done.\n" );
 
                # Get the IDs of all text records not in these sets
                $this->output( 'Searching for inactive text records...' );
-               $set = implode( ', ', $cur );
-               $res = $dbw->query( "SELECT old_id FROM $tbl_txt WHERE old_id NOT IN ( $set )" );
+               $cond = 'old_id NOT IN ( ' . $dbw->makeList( $cur ) . ' )';
+               $res = $dbw->select( 'text', 'old_id', array( $cond ), __METHOD__, array( 'DISTINCT' ) );
                $old = array();
                foreach ( $res as $row ) {
                        $old[] = $row->old_id;
@@ -973,8 +975,7 @@ abstract class Maintenance {
                # Delete as appropriate
                if ( $delete && $count ) {
                        $this->output( 'Deleting...' );
-                       $set = implode( ', ', $old );
-                       $dbw->query( "DELETE FROM $tbl_txt WHERE old_id IN ( $set )" );
+                       $dbw->delete( 'text', array( 'old_id' => $old ), __METHOD__ );
                        $this->output( "done.\n" );
                }
 
@@ -1207,7 +1208,7 @@ abstract class Maintenance {
                        $encPrompt = wfEscapeShellArg( $prompt );
                        $command = "read -er -p $encPrompt && echo \"\$REPLY\"";
                        $encCommand = wfEscapeShellArg( $command );
-                       $line = wfShellExec( "$bash -c $encCommand", $retval );
+                       $line = wfShellExec( "$bash -c $encCommand", $retval, array(), array( 'walltime' => 0 ) );
 
                        if ( $retval == 0 ) {
                                return $line;
index 30b568d..2555475 100644 (file)
@@ -8,7 +8,9 @@ test:
 
 doc:
        php mwdocgen.php --all
-       @echo 'Doc generation done. Look at ./docs/html/'
+       ./mwjsduck-gen
+       @echo 'PHP documentation (by Doxygen) in ./docs/html/'
+       @echo 'JS documentation (by JSDuck) in ./docs/js/'
 
 man:
        php mwdocgen.php --all --generate-man
index 0e12a1c..cc0a7e1 100644 (file)
@@ -48,9 +48,9 @@ class BaseDump {
        var $infiles = null;
 
        function BaseDump( $infile ) {
-               $this->infiles = explode(';',$infile);
+               $this->infiles = explode( ';', $infile );
                $this->reader = new XMLReader();
-               $infile = array_shift($this->infiles);
+               $infile = array_shift( $this->infiles );
                if (defined( 'LIBXML_PARSEHUGE' ) ) {
                        $this->reader->open( $infile, null, LIBXML_PARSEHUGE );
                }
index 9fa7c8e..10c5cd0 100644 (file)
 require_once( __DIR__ . '/Benchmarker.php' );
 
 function bfNormalizeTitleStrTr( $str ) {
-    return strtr( $str, '_', ' ' );
+       return strtr( $str, '_', ' ' );
 }
 
 function bfNormalizeTitleStrReplace( $str ) {
-    return str_replace( '_', ' ', $str );
+       return str_replace( '_', ' ', $str );
 }
 
 /**
index f276fc1..861610b 100644 (file)
@@ -46,7 +46,7 @@ class ChangePassword extends Maintenance {
                } elseif ( $this->hasOption( "userid" ) ) {
                        $user = User::newFromId( $this->getOption( 'userid' ) );
                } else {
-                       $this->error( "A \"user\" or \"userid\" must be set to change the password for" , true );
+                       $this->error( "A \"user\" or \"userid\" must be set to change the password for", true );
                }
                if ( !$user || !$user->getId() ) {
                        $this->error( "No such user: " . $this->getOption( 'user' ), true );
index 0a22f58..1e44e23 100644 (file)
@@ -368,4 +368,3 @@ class CheckSyntax extends Maintenance {
 
 $maintClass = "CheckSyntax";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 9838569..a41423a 100644 (file)
@@ -44,7 +44,7 @@ class CleanupSpam extends Maintenance {
                $username = wfMessage( 'spambot_username' )->text();
                $wgUser = User::newFromName( $username );
                if ( !$wgUser ) {
-                       $this->error( "Invalid username", true );
+                       $this->error( "Invalid username specified in 'spambot_username' message: $username", true );
                }
                // Create the user if necessary
                if ( !$wgUser->getId() ) {
index aebdee1..4e3c7fa 100644 (file)
@@ -134,6 +134,17 @@ class CopyFileBackend extends Maintenance {
                $ops = array();
                $fsFiles = array();
                $copiedRel = array(); // for output message
+
+               // Download the batch of source files into backend cache...
+               if ( $this->hasOption( 'missingonly' ) ) {
+                       $srcPaths = array();
+                       foreach ( $srcPathsRel as $srcPathRel ) {
+                               $srcPaths[] = $src->getRootStoragePath() . "/$backendRel/$srcPathRel";
+                       }
+                       $fsFiles = $src->getLocalReferenceMulti( array( 'srcs' => $srcPaths, 'latest' => 1 ) );
+               }
+
+               // Determine what files need to be copied over...
                foreach ( $srcPathsRel as $srcPathRel ) {
                        $srcPath = $src->getRootStoragePath() . "/$backendRel/$srcPathRel";
                        $dstPath = $dst->getRootStoragePath() . "/$backendRel/$srcPathRel";
@@ -144,8 +155,9 @@ class CopyFileBackend extends Maintenance {
                                $this->output( "Already have $srcPathRel.\n" );
                                continue; // assume already copied...
                        }
-                       // Note: getLocalReference() is fast for FS backends
-                       $fsFile = $src->getLocalReference( array( 'src' => $srcPath, 'latest' => 1 ) );
+                       $fsFile = array_key_exists( $srcPath, $fsFiles )
+                               ? $fsFiles[$srcPath]
+                               : $src->getLocalReference( array( 'src' => $srcPath, 'latest' => 1 ) );
                        if ( !$fsFile ) {
                                $this->error( "Could not get local copy of $srcPath.", 1 ); // die
                        } elseif ( !$fsFile->exists() ) {
@@ -167,6 +179,7 @@ class CopyFileBackend extends Maintenance {
                        $copiedRel[] = $srcPathRel;
                }
 
+               // Copy in the batch of source files...
                $t_start = microtime( true );
                $status = $dst->doQuickOperations( $ops, array( 'bypassReadOnly' => 1 ) );
                if ( !$status->isOK() ) {
index cc09703..792ee6c 100644 (file)
@@ -27,7 +27,7 @@
  * @ingroup Maintenance
  */
 class DeleteArchivedFilesImplementation {
-       static public function doDelete( $output, $force ) {
+       public static function doDelete( $output, $force ) {
                # Data should come off the master, wrapped in a transaction
                $dbw = wfGetDB( DB_MASTER );
                $dbw->begin( __METHOD__ );
index 414d41a..dd8e3dd 100644 (file)
@@ -36,7 +36,7 @@ class DeleteArchivedRevisionsImplementation {
         * purgeRedundantText().  See Maintenance for a description of
         * those methods.
         */
-       static public function doDelete( $maint ) {
+       public static function doDelete( $maint ) {
                $dbw = wfGetDB( DB_MASTER );
 
                $dbw->begin( __METHOD__ );
diff --git a/maintenance/deleteEqualMessages.php b/maintenance/deleteEqualMessages.php
new file mode 100644 (file)
index 0000000..38e6956
--- /dev/null
@@ -0,0 +1,143 @@
+<?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
+ * @ingroup Maintenance
+ */
+
+require_once( __DIR__ . '/Maintenance.php' );
+
+/**
+ * Maintenance script that deletes all pages in the MediaWiki namespace
+ * of which the content is equal to the system default.
+ *
+ * @ingroup Maintenance
+ */
+class DeleteEqualMessages extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Deletes all pages in the MediaWiki namespace that are equal to the default message";
+               $this->addOption( 'delete', 'Actually delete the pages' );
+               $this->addOption( 'delete-talk', 'Don\'t leave orphaned talk pages behind' );
+               $this->addOption( 'lang-code', 'Check for subpages of this lang-code (default: root page against content language)', false, true );
+       }
+
+       public function execute() {
+               global $wgUser, $wgContLang;
+
+               $doDelete = $this->hasOption( 'delete' );
+               $doDeleteTalk = $this->hasOption( 'delete-talk' );
+               $forLangCode = $this->getOption( 'lang-code' );
+
+               if ( $forLangCode ) {
+                       $langObj = Language::factory( $forLangCode );
+                       $langCode = $langObj->getCode();
+                       $nonContLang = true;
+               } else {
+                       $langObj = $wgContLang;
+                       $langCode = $wgContLang->getCode();
+                       $nonContLang = false;
+               }
+
+               $this->output( "Checking for pages with default message..." );
+
+               /* Based on SpecialAllmessages::reallyDoQuery #filter=modified */
+
+               $messageNames = Language::getLocalisationCache()->getSubitemList( 'en', 'messages' );
+               // Normalise message names for NS_MEDIAWIKI page_title
+               $messageNames = array_map( array( $langObj, 'ucfirst' ), $messageNames );
+               // TODO: Do the below for each language code (e.g. delete /xxx subpage if equal to MessagesXxx)
+               // Right now it only takes care of the root override, which is enough since most wikis aren't multi-lang wikis.
+               $statuses = AllmessagesTablePager::getCustomisedStatuses( $messageNames, $langCode, $nonContLang );
+
+               $relevantPages = 0;
+               $equalPages = 0;
+               $equalPagesTalks = 0;
+               $results = array();
+               foreach ( $messageNames as $key ) {
+                       $customised = isset( $statuses['pages'][$key] );
+                       if ( $customised ) {
+                               $actual = wfMessage( $key )->inLanguage( $langCode )->plain();
+                               $default = wfMessage( $key )->inLanguage( $langCode )->useDatabase( false )->plain();
+
+                               $relevantPages++;
+                               if ( $actual === $default ) {
+                                       $hasTalk = isset( $statuses['talks'][$key] );
+                                       $results[] = array(
+                                               'title' => $key,
+                                               'hasTalk' => $hasTalk,
+                                       );
+                                       $equalPages++;
+                                       if ( $hasTalk ) {
+                                               $equalPagesTalks++;
+                                       }
+                               }
+                       }
+               }
+
+               if ( $equalPages === 0 ) {
+                       // No more equal messages left
+                       $this->output( "done.\n" );
+                       return;
+               }
+
+               $this->output( "\n{$relevantPages} pages in the MediaWiki namespace override messages." );
+               $this->output( "\n{$equalPages} pages are equal to the default message ({$equalPagesTalks} talk pages).\n" );
+
+               if ( !$doDelete ) {
+                       $this->output( "\nRun the script again with --delete to delete these pages" );
+                       if ( $equalPagesTalks !== 0 ) {
+                               $this->output( " (include --delete-talk to also delete the talk pages)" );
+                       }
+                       $this->output( "\n" );
+                       return;
+               }
+
+               $user = User::newFromName( 'MediaWiki default' );
+               if ( !$user ) {
+                       $this->error( "Invalid username", true );
+               }
+               $wgUser = $user;
+
+               // Hide deletions from RecentChanges
+               $user->addGroup( 'bot' );
+
+               // Handle deletion
+               $this->output( "\n...deleting equal messages (this may take a long time!)...", 'msg' );
+               $dbw = wfGetDB( DB_MASTER );
+               foreach ( $results as $result ) {
+                       wfWaitForSlaves();
+                       $dbw->ping();
+                       $dbw->begin( __METHOD__ );
+                       $title = Title::makeTitle( NS_MEDIAWIKI, $result['title'] );
+                       $page = WikiPage::factory( $title );
+                       $error = ''; // Passed by ref
+                       $page->doDeleteArticle( 'No longer required', false, 0, false, $error, $user );
+                       if ( $result['hasTalk'] && $doDeleteTalk ) {
+                               $title = Title::makeTitle( NS_MEDIAWIKI_TALK, $result['title'] );
+                               $page = WikiPage::factory( $title );
+                               $error = ''; // Passed by ref
+                               $page->doDeleteArticle( 'Orphaned talk page of no longer required message', false, 0, false, $error, $user );
+                       }
+                       $dbw->commit( __METHOD__ );
+               }
+               $this->output( "done!\n", 'msg' );
+       }
+}
+
+$maintClass = "DeleteEqualMessages";
+require_once( RUN_MAINTENANCE_IF_MAIN );
index 4f82a63..114aefd 100644 (file)
@@ -101,4 +101,3 @@ class DeleteOldRevisions extends Maintenance {
 
 $maintClass = "DeleteOldRevisions";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index dcbf739..f0da9a8 100644 (file)
@@ -91,4 +91,3 @@ class DeleteOrphanedRevisions extends Maintenance {
 
 $maintClass = "DeleteOrphanedRevisions";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index ac96f45..1d5070b 100644 (file)
@@ -21,7 +21,7 @@
  * @file
  */
 
-if ( php_sapi_name() != 'cli-server' ) {
+if ( PHP_SAPI != 'cli-server' ) {
        die( "This script can only be run by php's cli-server sapi." );
 }
 
index 2bb2a0f..15b0016 100644 (file)
@@ -111,8 +111,18 @@ try {
 
        // Potentially debug globals
        $maintenance->globals();
+
+       // Perform deferred updates.
+       DeferredUpdates::doUpdates( 'commit' );
+
+       // log profiling info
+       wfLogProfilingData();
+
+       // Commit and close up!
+       $factory = wfGetLBFactory();
+       $factory->commitMasterChanges();
+       $factory->shutdown();
 } catch ( MWException $mwe ) {
        echo( $mwe->getText() );
        exit( 1 );
 }
-
index 153fdd7..08aae29 100644 (file)
@@ -76,4 +76,3 @@ class DumpLinks extends Maintenance {
 
 $maintClass = "DumpLinks";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index ad4c12f..93fc3e7 100644 (file)
@@ -93,4 +93,3 @@ class EditCLI extends Maintenance {
 
 $maintClass = "EditCLI";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 69cf548..95f46ff 100644 (file)
@@ -80,5 +80,3 @@ while ( ( $line = Maintenance::readconsole() ) !== false ) {
 }
 
 print "\n";
-
-
index d98cfe3..4cb5e10 100644 (file)
@@ -55,7 +55,8 @@ class TestFileOpPerformance extends Maintenance {
 
                $profiler = Profiler::instance();
                $profiler->setTemplated( true );
-               $profiler->logData(); // prints
+
+               //NOTE: as of MW1.21, $profiler->logData() is called implicitly by doMaintenance.php.
        }
 
        protected function doPerfTest( FileBackend $backend ) {
index 600ca97..691ed80 100644 (file)
@@ -76,5 +76,3 @@ class MaintenanceFormatInstallDoc extends Maintenance {
 
 $maintClass = 'MaintenanceFormatInstallDoc';
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
-
index b72430a..6bb44a1 100644 (file)
@@ -747,7 +747,7 @@ class wikiFuzz {
        /**
         ** Randomly returns one element of the input array.
         */
-       static public function chooseInput( array $input ) {
+       public static function chooseInput( array $input ) {
                $randindex = wikiFuzz::randnum( count( $input ) - 1 );
                return $input[$randindex];
        }
@@ -761,7 +761,7 @@ class wikiFuzz {
         * @param $start int
         * @return int
         */
-       static public function randnum( $finish, $start = 0 ) {
+       public static function randnum( $finish, $start = 0 ) {
                return mt_rand( $start, $finish );
        }
 
@@ -769,7 +769,7 @@ class wikiFuzz {
         * Returns a mix of random text and random wiki syntax.
         * @return string
         */
-       static private function randstring() {
+       private static function randstring() {
                $thestring = "";
 
                for ( $i = 0; $i < 40; $i++ ) {
@@ -801,7 +801,7 @@ class wikiFuzz {
         *        or random data from "other".
         * @return string
         */
-       static private function makestring() {
+       private static function makestring() {
                $what = wikiFuzz::randnum( 2 );
                if ( $what == 0 ) {
                        return wikiFuzz::randstring();
@@ -818,7 +818,7 @@ class wikiFuzz {
         * @param $matches
         * @return string
         */
-       static private function stringEscape( $matches ) {
+       private static function stringEscape( $matches ) {
                return sprintf( "\\x%02x", ord( $matches[1] ) );
        }
 
@@ -828,7 +828,7 @@ class wikiFuzz {
         * @param $str string
         * @return string
         */
-       static public function makeTitleSafe( $str ) {
+       public static function makeTitleSafe( $str ) {
                $legalTitleChars = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF";
                return preg_replace_callback(
                                "/([^$legalTitleChars])/", 'wikiFuzz::stringEscape',
@@ -839,7 +839,7 @@ class wikiFuzz {
         ** Returns a string of fuzz text.
         * @return string
         */
-       static private function loop() {
+       private static function loop() {
                switch ( wikiFuzz::randnum( 3 ) ) {
                        case 1: // an opening tag, with parameters.
                                $string = "";
@@ -868,7 +868,7 @@ class wikiFuzz {
         * Returns one of the three styles of random quote: ', ", and nothing.
         * @return string
         */
-       static private function getRandQuote() {
+       private static function getRandQuote() {
                switch ( wikiFuzz::randnum( 3 ) ) {
                        case 1 : return "'";
                        case 2 : return "\"";
@@ -881,7 +881,7 @@ class wikiFuzz {
         * @param $maxtypes int
         * @return string
         */
-       static public function makeFuzz( $maxtypes = 2 ) {
+       public static function makeFuzz( $maxtypes = 2 ) {
                $page = "";
                for ( $k = 0; $k < $maxtypes; $k++ ) {
                        $page .= wikiFuzz::loop();
@@ -2709,5 +2709,3 @@ for ( $count = 0; true; $count++ ) {
                break;
        }
 }
-
-
diff --git a/maintenance/getConfiguration.php b/maintenance/getConfiguration.php
new file mode 100644 (file)
index 0000000..83b5b02
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Print serialized output of MediaWiki config vars
+ *
+ * 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
+ * @author Tim Starling
+ * @author Antoine Musso
+ */
+
+require_once( __DIR__ . '/Maintenance.php' );
+
+/**
+ * Print serialized output of MediaWiki config vars
+ *
+ * @ingroup Maintenance
+ */
+class GetConfiguration extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Get serialized MediaWiki site configuration";
+               $this->addOption( 'settings', 'Space-separated list of wg* variables', true, true );
+               $this->addOption( 'format', 'PHP or JSON', true, true );
+               $this->addOption( 'wiki', 'Wiki ID', true, true );
+       }
+
+       public function execute() {
+               $res = array();
+               foreach ( explode( ' ', $this->getOption( 'settings' ) ) as $name ) {
+                       if ( !preg_match( '/^wg[A-Z]/', $name ) ) {
+                               throw new MWException( "Variable '$name' does start with 'wg'." );
+                       } elseif ( !isset( $GLOBALS[$name] ) ) {
+                               throw new MWException( "Variable '$name' is not set." );
+                       } elseif ( !$this->isAllowedVariable( $GLOBALS[$name] ) ) {
+                               throw new MWException( "Variable '$name' includes non-array, non-scalar, items." );
+                       }
+                       $res[$name] = $GLOBALS[$name];
+               }
+
+               $out = null;
+               switch( $this->getOption( 'format' ) ) {
+                       case 'PHP':
+                               $out = serialize( $res );
+                               break;
+                       case 'JSON':
+                               $out = FormatJson::encode( $res );
+                               break;
+                       default:
+                               throw new MWException( "Invalid serialization format given." );
+               }
+               if ( !is_string( $out ) ) {
+                       throw new MWException( "Failed to serialize the requested settings." );
+               }
+
+               $this->output( $out . "\n" );
+       }
+
+       private function isAllowedVariable( $value ) {
+               if ( is_array( $value ) ) {
+                       foreach ( $value as $k => $v ) {
+                               if ( !$this->isAllowedVariable( $v ) ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               } elseif ( is_scalar( $value ) ) {
+                       return true;
+               }
+               return false;
+       }
+}
+
+$maintClass = "GetConfiguration";
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/jsduck/MetaTags.rb b/maintenance/jsduck/MetaTags.rb
new file mode 100644 (file)
index 0000000..84e4021
--- /dev/null
@@ -0,0 +1,53 @@
+# See also:
+# - https://github.com/senchalabs/jsduck/wiki/Tags
+# - https://github.com/senchalabs/jsduck/wiki/Custom-tags
+require 'jsduck/meta_tag'
+
+class ContextTag < JsDuck::MetaTag
+  def initialize
+    @name = 'context'
+  end
+
+  # @param tags All matches of this tag on one class.
+  def to_html(tags)
+    return '<h3 class="pa">Context</h3>' +  render_long_context(tags.last)
+  end
+
+  def render_long_context(tag)
+    if tag =~ /\A([^\s]+)/m
+      name = $1
+      return format("`this` : {@link #{name}}")
+    end
+  end
+end
+
+class SeeTag < JsDuck::MetaTag
+  def initialize
+    @name = 'see'
+    @multiline = true
+  end
+
+  # @param tags All matches of this tag on one class.
+  def to_html(tags)
+    doc = []
+    doc << '<h3 class="pa">Related</h3>'
+    doc << [
+        '<ul>',
+        tags.map {|tag| render_long_see(tag) },
+        '</ul>',
+      ]
+    doc
+  end
+
+  def render_long_see(tag)
+    if tag =~ /\A([^\s]+)( .*)?\Z/m
+      name = $1
+      doc = $2 ? ': ' + $2 : ''
+      return [
+        '<li>',
+        format("{@link #{name}} #{doc}"),
+        '</li>'
+      ]
+    end
+  end
+end
diff --git a/maintenance/jsduck/categories.json b/maintenance/jsduck/categories.json
new file mode 100644 (file)
index 0000000..4a8ba8c
--- /dev/null
@@ -0,0 +1,54 @@
+[
+       {
+               "name": "MediaWiki",
+               "groups": [
+                       {
+                               "name": "Base",
+                               "classes": [
+                                       "mw",
+                                       "mw.Map",
+                                       "mw.Message",
+                                       "mw.loader",
+                                       "mw.html",
+                                       "mw.html.Cdata",
+                                       "mw.html.Raw"
+                               ]
+                       },
+                       {
+                               "name": "General",
+                               "classes": [
+                                       "mw.Title",
+                                       "mw.notification",
+                                       "mw.util",
+                                       "mw.plugin.notify"
+                               ]
+                       },
+                       {
+                               "name": "API",
+                               "classes": ["mw.Api*"]
+                       }
+               ]
+       },
+       {
+               "name": "jQuery",
+               "groups": [
+                       {
+                               "name": "Core",
+                               "classes": ["jQuery", "jQuery.Event", "jQuery.Promise", "jQuery.Deferred", "jQuery.jqXHR"]
+                       },
+                       {
+                               "name": "Plugins",
+                               "classes": ["jQuery.plugin.*"]
+                       }
+               ]
+       },
+       {
+               "name": "Misc",
+               "groups": [
+                       {
+                               "name": "Native",
+                               "classes": ["Array", "Boolean", "Date", "Function", "Number", "Object", "RegExp", "String"]
+                       }
+               ]
+       }
+]
diff --git a/maintenance/jsduck/config.json b/maintenance/jsduck/config.json
new file mode 100644 (file)
index 0000000..c4705d8
--- /dev/null
@@ -0,0 +1,18 @@
+{
+       "--title": "MediaWiki Code Documentation",
+       "--categories": "./categories.json",
+       "--meta-tags": "./MetaTags.rb",
+       "--warnings": ["-no_doc"],
+       "--builtin-classes": true,
+       "--output": "../../docs/js",
+       "--": [
+               "./external.js",
+               "../../resources/mediawiki/mediawiki.js",
+               "../../resources/mediawiki/mediawiki.util.js",
+               "../../resources/mediawiki/mediawiki.Title.js",
+               "../../resources/mediawiki/mediawiki.notify.js",
+               "../../resources/mediawiki/mediawiki.notification.js",
+               "../../resources/mediawiki.api",
+               "../../resources/jquery/jquery.localize.js"
+       ]
+}
\ No newline at end of file
diff --git a/maintenance/jsduck/eg-iframe.html b/maintenance/jsduck/eg-iframe.html
new file mode 100644 (file)
index 0000000..f53b404
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>MediaWiki Examples</title>
+    <script>
+        function loadInlineExample(code, options, callback) {
+            try {
+                document.body.innerHTML = '';
+                eval(code);
+                callback && callback(true);
+            } catch (e) {
+                document.body.innerHTML = document.createTextNode(e);
+                callback && callback(false, e);
+            }
+        }
+    </script>
+</head>
+<body></body>
+</html>
diff --git a/maintenance/jsduck/external.js b/maintenance/jsduck/external.js
new file mode 100644 (file)
index 0000000..8ab102f
--- /dev/null
@@ -0,0 +1,26 @@
+/**
+ * @class jQuery
+ */
+
+/**
+ * @method ajax
+ * @return {jqXHR}
+ */
+
+/**
+ * @class jQuery.Event
+ */
+
+/**
+ * @class jQuery.Promise
+ */
+
+/**
+ * @class jQuery.Deferred
+ * @mixins jQuery.Promise
+ */
+
+/**
+ * @class jQuery.jqXHR
+ * @alternateClassName jqXHR
+ */
index 3ad0864..3df1169 100644 (file)
@@ -51,7 +51,7 @@ class DatabaseLag extends Maintenance {
                                unset( $lags[0] );
                                echo gmdate( 'H:i:s' ) . ' ';
                                foreach ( $lags as $lag ) {
-                                       printf( "%-12s " , $lag === false ? 'false' : $lag );
+                                       printf( "%-12s ", $lag === false ? 'false' : $lag );
                                }
                                echo "\n";
                                sleep( 5 );
@@ -61,7 +61,7 @@ class DatabaseLag extends Maintenance {
                        $lags = $lb->getLagTimes();
                        foreach ( $lags as $i => $lag ) {
                                $name = $lb->getServerName( $i );
-                               $this->output( sprintf( "%-20s %s\n" , $name, $lag === false ? 'false' : $lag ) );
+                               $this->output( sprintf( "%-20s %s\n", $name, $lag === false ? 'false' : $lag ) );
                        }
                }
        }
index e2ad6a7..12823c0 100644 (file)
@@ -61,18 +61,80 @@ class GenerateCollationData extends Maintenance {
 
        public function execute() {
                $this->dataDir = $this->getOption( 'data-dir', '.' );
-               if ( !file_exists( "{$this->dataDir}/allkeys.txt" ) ) {
-                       $this->error( "Unable to find allkeys.txt. Please download it from " .
-                               "http://www.unicode.org/Public/UCA/latest/allkeys.txt and specify " .
-                               "its location with --data-dir=<DIR>" );
-                       exit( 1 );
-               }
-               if ( !file_exists( "{$this->dataDir}/ucd.all.grouped.xml" ) ) {
-                       $this->error( "Unable to find ucd.all.grouped.xml. Please download it " .
-                               "from http://www.unicode.org/Public/6.0.0/ucdxml/ucd.all.grouped.zip " .
-                               "and specify its location with --data-dir=<DIR>" );
+
+               $allkeysPresent = file_exists( "{$this->dataDir}/allkeys.txt" );
+               $ucdallPresent = file_exists( "{$this->dataDir}/ucd.all.grouped.xml" );
+
+               // As of January 2013, these links work for all versions of Unicode
+               // between 5.1 and 6.2, inclusive.
+               $allkeysURL = "http://www.unicode.org/Public/UCA/<Unicode version>/allkeys.txt";
+               $ucdallURL = "http://www.unicode.org/Public/<Unicode version>/ucdxml/ucd.all.grouped.zip";
+
+               if ( !$allkeysPresent || !$ucdallPresent ) {
+                       $icuVersion = IcuCollation::getICUVersion();
+                       $unicodeVersion = IcuCollation::getUnicodeVersionForICU();
+
+                       $error = "";
+
+                       if ( !$allkeysPresent ) {
+                               $error .= "Unable to find allkeys.txt. "
+                                       . "Download it and specify its location with --data-dir=<DIR>. "
+                                       . "\n\n";
+                       }
+                       if ( !$ucdallPresent ) {
+                               $error .= "Unable to find ucd.all.grouped.xml. "
+                                       . "Download it, unzip, and specify its location with --data-dir=<DIR>. "
+                                       . "\n\n";
+                       }
+
+                       $versionKnown = false;
+                       if ( !$icuVersion ) {
+                               // Unknown version - either very old intl,
+                               // or PHP < 5.3.7 which does not expose this information
+                               $error .= "As MediaWiki could not determine the version of ICU library used by your PHP's "
+                                       . "intl extension it can't suggest which file version to download. "
+                                       . "This can be caused by running a very old version of intl or PHP < 5.3.7. "
+                                       . "If you are sure everything is all right, find out the ICU version "
+                                       . "by running phpinfo(), check what is the Unicode version it is using "
+                                       . "at http://site.icu-project.org/download, then try finding appropriate data file(s) at:";
+                       } elseif ( version_compare( $icuVersion, "4.0", "<" ) ) {
+                               // Extra old version
+                               $error .= "You are using outdated version of ICU ($icuVersion), intended for "
+                                       . ( $unicodeVersion ? "Unicode $unicodeVersion" : "an unknown version of Unicode" )
+                                       . "; this file might not be avalaible for it, and it's not supported by MediaWiki. "
+                                       ." You are on your own; consider upgrading PHP's intl extension or try "
+                                       . "one of the files available at:";
+                       } elseif ( version_compare( $icuVersion, "51.0", ">=" ) ) {
+                               // Extra recent version
+                               $error .= "You are using ICU $icuVersion, released after this script was last updated. "
+                                       . "Check what is the Unicode version it is using at http://site.icu-project.org/download . "
+                                       . "It can't be guaranteed everything will work, but appropriate file(s) should "
+                                       . "be available at:";
+                       } else {
+                               // ICU 4.0 to 50.x
+                               $versionKnown = true;
+                               $error .= "You are using ICU $icuVersion, intended for "
+                                       . ( $unicodeVersion ? "Unicode $unicodeVersion" : "an unknown version of Unicode" )
+                                       . ". Appropriate file(s) should be available at:";
+                       }
+                       $error .= "\n";
+
+                       if ( $versionKnown && $unicodeVersion ) {
+                               $allkeysURL = str_replace( "<Unicode version>", "$unicodeVersion.0", $allkeysURL );
+                               $ucdallURL = str_replace( "<Unicode version>", "$unicodeVersion.0", $ucdallURL );
+                       }
+
+                       if ( !$allkeysPresent ) {
+                               $error .= "* $allkeysURL\n";
+                       }
+                       if ( !$ucdallPresent ) {
+                               $error .= "* $ucdallURL\n";
+                       }
+
+                       $this->error( $error );
                        exit( 1 );
                }
+
                $debugOutFileName = $this->getOption( 'debug-output' );
                if ( $debugOutFileName ) {
                        $this->debugOutFile = fopen( $debugOutFileName, 'w' );
index 33163d4..c03162c 100644 (file)
  * @ingroup MaintenanceLanguage
  */
 
-require_once( __DIR__ . '/../Maintenance.php' );
-
 require_once( __DIR__ . '/../../includes/normal/UtfNormalUtil.php' );
 
+require_once( __DIR__ . '/../Maintenance.php' );
+
 /**
  * Generates normalizer data files for Arabic and Malayalam.
  * For NFC see includes/normal.
index b1c16ad..420e842 100644 (file)
@@ -508,7 +508,7 @@ class languages {
 
 
                        if ( isset( $messages[$key] ) ) {
-                               $messages[$key] = implode( $messages[$key],", " );
+                               $messages[$key] = implode( $messages[$key], ", " );
                        }
                }
                return $messages;
index 87bc1c2..3b2292f 100644 (file)
@@ -214,7 +214,6 @@ $wgIgnoredMessages = array(
        '1movedto2',
        '1movedto2_redir',
        'move-redirect-suppressed',
-       // 'newuserlog-byemail',
        'newuserlog-create-entry',
        'newuserlog-create2-entry',
        'newuserlog-autocreate-entry',
index 50a6f2e..e2997c4 100644 (file)
@@ -2702,6 +2702,7 @@ $wgMessageStructure = array(
                'pageinfo-robot-noindex',
                'pageinfo-views',
                'pageinfo-watchers',
+               'pageinfo-few-watchers',
                'pageinfo-redirects-name',
                'pageinfo-redirects-value',
                'pageinfo-subpages-name',
@@ -3735,8 +3736,8 @@ $wgMessageStructure = array(
                'logentry-newusers-newusers',
                'logentry-newusers-create',
                'logentry-newusers-create2',
+               'logentry-newusers-byemail',
                'logentry-newusers-autocreate',
-               'newuserlog-byemail',
                'logentry-rights-rights',
                'logentry-rights-rights-legacy',
                'logentry-rights-autopromote',
@@ -3761,7 +3762,6 @@ $wgMessageStructure = array(
                '1movedto2',
                '1movedto2_redir',
                'move-redirect-suppressed',
-               // 'newuserlog-byemail',
                'newuserlog-create-entry',
                'newuserlog-create2-entry',
                'newuserlog-autocreate-entry',
@@ -3823,6 +3823,7 @@ $wgMessageStructure = array(
                'api-error-ok-but-empty',
                'api-error-overwrite',
                'api-error-stashfailed',
+               'api-error-publishfailed',
                'api-error-timeout',
                'api-error-unclassified',
                'api-error-unknown-code',
index 751e744..4f00496 100644 (file)
  * @ingroup MaintenanceLanguage
  */
 
+if ( PHP_SAPI != 'cli' ) {
+       die( "Run me from the command line please.\n" );
+}
+
 if ( !isset( $argv[1] ) ) {
        print "Usage: php {$argv[0]} <filename>\n";
        exit( 1 );
index 4358989..01fbac7 100644 (file)
@@ -23,7 +23,7 @@
  * @ingroup LockManager Maintenance
  */
 
-if ( php_sapi_name() !== 'cli' ) {
+if ( PHP_SAPI !== 'cli' ) {
        die( "This is not a valid entry point.\n" );
 }
 error_reporting( E_ALL );
@@ -79,9 +79,9 @@ class LockServerDaemon {
                foreach ( array( 'address', 'port', 'authKey' ) as $par ) {
                        if ( !isset( $config[$par] ) ) {
                                die( "Usage: php LockServerDaemon.php " .
-                                       "--address <address> --port <port> --authkey <key> " .
+                                       "--address <address> --port <port> --authKey <key> " .
                                        "[--lockTimeout <seconds>] " .
-                                       "[--maxLocks <integer>] [--maxClients <integer>] [--maxBacklog <integer>]"
+                                       "[--maxLocks <integer>] [--maxClients <integer>] [--maxBacklog <integer>]\n"
                                );
                        }
                }
index cea6433..62596b2 100644 (file)
@@ -82,6 +82,9 @@ class MergeMessageFileList extends Maintenance {
                if ( $this->hasOption( 'output' ) ) {
                        $mmfl['output'] = $this->getOption( 'output' );
                }
+               if ( $this->hasOption( 'quiet' ) ) {
+                       $mmfl['quiet'] = true;
+               }
        }
 }
 
@@ -92,7 +95,9 @@ foreach ( $mmfl['setupFiles'] as $fileName ) {
                continue;
        }
        $fileName = str_replace( '$IP', $IP, $fileName );
-       fwrite( STDERR, "Loading data from $fileName\n" );
+       if ( empty( $mmfl['quiet'] ) ) {
+               fwrite( STDERR, "Loading data from $fileName\n" );
+       }
        include_once( $fileName );
 }
 fwrite( STDERR, "\n" );
@@ -120,4 +125,3 @@ if ( isset( $mmfl['output'] ) ) {
 } else {
        echo $s;
 }
-
index 6e01291..5e505eb 100644 (file)
@@ -43,7 +43,7 @@
 # Variables / Configuration
 #
 
-if ( php_sapi_name() != 'cli' ) {
+if ( PHP_SAPI != 'cli' ) {
        echo 'Run "' . __FILE__ . '" from the command line.';
        die( -1 );
 }
@@ -131,7 +131,7 @@ function generateConfigFile( $doxygenTemplate, $outputDirectory, $stripFromPath,
        );
        $tmpCfg = str_replace( array_keys( $replacements ), array_values( $replacements ), $template );
        $tmpFileName = tempnam( wfTempDir(), 'mwdocgen-' );
-       file_put_contents( $tmpFileName , $tmpCfg ) or die( "Could not write doxygen configuration to file $tmpFileName\n" );
+       file_put_contents( $tmpFileName, $tmpCfg ) or die( "Could not write doxygen configuration to file $tmpFileName\n" );
 
        return $tmpFileName;
 }
diff --git a/maintenance/mwjsduck-gen b/maintenance/mwjsduck-gen
new file mode 100755 (executable)
index 0000000..fbd428f
--- /dev/null
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+jsduck --config=$(cd $(dirname $0)/..; pwd)/maintenance/jsduck/config.json && echo 'JSDuck execution finished.'
index 17a3f2e..6cc8566 100644 (file)
@@ -18,7 +18,6 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @todo Make this work on PostgreSQL and maybe other database servers
  * @ingroup Maintenance
  */
 
@@ -33,86 +32,65 @@ class nextJobDB extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = "Pick a database that has pending jobs";
-               $this->addOption( 'type', "The type of job to search for", false, true );
+               $this->addOption( 'type', "Search by job type", false, true );
+               $this->addOption( 'types', "Space separated list of job types to search for", false, true );
        }
 
        public function execute() {
-               global $wgMemc;
+               global $wgMemc, $wgJobTypesExcludedFromDefaultQueue;
 
-               $type = $this->getOption( 'type', false );
+               $type = false; // job type required/picked
 
-               $memcKey = 'jobqueue:dbs:v3';
-               $pendingDbInfo = $wgMemc->get( $memcKey );
-
-               // If the cache entry wasn't present, is stale, or in .1% of cases otherwise,
-               // regenerate the cache. Use any available stale cache if another process is
-               // currently regenerating the pending DB information.
-               if ( !is_array( $pendingDbInfo )
-                       || ( time() - $pendingDbInfo['timestamp'] ) > 300 // 5 minutes
-                       || mt_rand( 0, 999 ) == 0
-               ) {
-                       if ( $wgMemc->add( "$memcKey:rebuild", 1, 1800 ) ) { // lock
-                               $pendingDbInfo = array(
-                                       'pendingDBs' => $this->getPendingDbs(),
-                                       'timestamp'  => time()
-                               );
-                               for ( $attempts=1; $attempts <= 25; ++$attempts ) {
-                                       if ( $wgMemc->add( "$memcKey:lock", 1, 60 ) ) { // lock
-                                               $wgMemc->set( $memcKey, $pendingDbInfo );
-                                               $wgMemc->delete( "$memcKey:lock" ); // unlock
-                                               break;
-                                       }
-                               }
-                               $wgMemc->delete( "$memcKey:rebuild" ); // unlock
-                       }
+               if ( $this->hasOption( 'types' ) ) {
+                       $types = explode( ' ', $this->getOption( 'types' ) );
+               } elseif ( $this->hasOption( 'type' ) ) {
+                       $types = array( $this->getOption( 'type' ) );
+               } else {
+                       $types = false;
                }
 
-               if ( !is_array( $pendingDbInfo ) || !$pendingDbInfo['pendingDBs'] ) {
+               // Handle any required periodic queue maintenance
+               $this->executeReadyPeriodicTasks();
+
+               // Get all the queues with jobs in them
+               $pendingDBs = JobQueueAggregator::singleton()->getAllReadyWikiQueues();
+               if ( !count( $pendingDBs ) ) {
                        return; // no DBs with jobs or cache is both empty and locked
                }
 
-               $pendingDBs = $pendingDbInfo['pendingDBs']; // convenience
                do {
                        $again = false;
 
-                       if ( $type === false ) {
-                               $candidates = call_user_func_array( 'array_merge', $pendingDBs );
-                       } elseif ( isset( $pendingDBs[$type] ) ) {
-                               $candidates = $pendingDBs[$type];
-                       } else {
-                               $candidates = array();
+                       $candidates = array(); // list of (type, db)
+                       // Flatten the tree of candidates into a flat list so that a random
+                       // item can be selected, weighing each queue (type/db tuple) equally.
+                       foreach ( $pendingDBs as $type => $dbs ) {
+                               if (
+                                       ( is_array( $types ) && in_array( $type, $types ) ) ||
+                                       ( $types === false && !in_array( $type, $wgJobTypesExcludedFromDefaultQueue ) )
+                               ) {
+                                       foreach ( $dbs as $db ) {
+                                               $candidates[] = array( $type, $db );
+                                       }
+                               }
                        }
-                       if ( !$candidates ) {
-                               return;
+                       if ( !count( $candidates ) ) {
+                               return; // no jobs for this type
                        }
 
-                       $candidates = array_values( $candidates );
-                       $db = $candidates[ mt_rand( 0, count( $candidates ) - 1 ) ];
-                       if ( !$this->checkJob( $type, $db ) ) {
-                               if ( $type === false ) {
-                                       // There are no jobs available in the current database
-                                       foreach ( $pendingDBs as $type2 => $dbs ) {
-                                               $pendingDBs[$type2] = array_diff( $pendingDBs[$type2], array( $db ) );
-                                       }
-                               } else {
-                                       // There are no jobs of this type available in the current database
-                                       $pendingDBs[$type] = array_diff( $pendingDBs[$type], array( $db ) );
-                               }
-                               // Update the cache to remove the outdated information.
-                               // Make sure that this does not race (especially with full rebuilds).
-                               $pendingDbInfo['pendingDBs'] = $pendingDBs;
-                               if ( $wgMemc->add( "$memcKey:lock", 1, 60 ) ) { // lock
-                                       $curInfo = $wgMemc->get( $memcKey );
-                                       if ( $curInfo && $curInfo['timestamp'] === $pendingDbInfo['timestamp'] ) {
-                                               $wgMemc->set( $memcKey, $pendingDbInfo );
-                                       }
-                                       $wgMemc->delete( "$memcKey:lock" ); // unlock
-                               }
+                       list( $type, $db ) = $candidates[ mt_rand( 0, count( $candidates ) - 1 ) ];
+                       if ( !$this->checkJob( $type, $db ) ) { // queue is actually empty?
+                               $pendingDBs[$type] = array_diff( $pendingDBs[$type], $db );
+                               JobQueueAggregator::singleton()->notifyQueueEmpty( $db, $type );
                                $again = true;
                        }
                } while ( $again );
 
-               $this->output( $db . "\n" );
+               if ( $this->hasOption( 'types' ) ) {
+                       $this->output( $db . " " . $type . "\n" );
+               } else {
+                       $this->output( $db . "\n" );
+               }
        }
 
        /**
@@ -122,36 +100,31 @@ class nextJobDB extends Maintenance {
         * @param $dbName string
         * @return bool
         */
-       function checkJob( $type, $dbName ) {
-               $group = JobQueueGroup::singleton( $dbName );
-               if ( $type === false ) {
-                       foreach ( $group->getDefaultQueueTypes() as $type ) {
-                               if ( !$group->get( $type )->isEmpty() ) {
-                                       return true;
-                               }
-                       }
-                       return false;
-               } else {
-                       return !$group->get( $type )->isEmpty();
-               }
+       private function checkJob( $type, $dbName ) {
+               return !JobQueueGroup::singleton( $dbName )->get( $type )->isEmpty();
        }
 
        /**
-        * Get all databases that have a pending job
-        * @return array
+        * Do all ready periodic jobs for all databases every 5 minutes (and .1% of the time)
+        * @return integer
         */
-       private function getPendingDbs() {
-               global $wgLocalDatabases;
-
-               $pendingDBs = array(); // (job type => (db list))
-               foreach ( $wgLocalDatabases as $db ) {
-                       $types = JobQueueGroup::singleton( $db )->getQueuesWithJobs();
-                       foreach ( $types as $type ) {
-                               $pendingDBs[$type][] = $db;
+       private function executeReadyPeriodicTasks() {
+               global $wgLocalDatabases, $wgMemc;
+
+               $count = 0;
+               $memcKey = 'jobqueue:periodic:lasttime';
+               $timestamp = (int)$wgMemc->get( $memcKey ); // UNIX timestamp or 0
+               if ( ( time() - $timestamp ) > 300 || mt_rand( 0, 999 ) == 0 ) { // 5 minutes
+                       if ( $wgMemc->add( "$memcKey:rebuild", 1, 1800 ) ) { // lock
+                               foreach ( $wgLocalDatabases as $db ) {
+                                       $count += JobQueueGroup::singleton( $db )->executeReadyPeriodicTasks();
+                               }
+                               $wgMemc->set( $memcKey, time() );
+                               $wgMemc->delete( "$memcKey:rebuild" ); // unlock
                        }
                }
 
-               return $pendingDBs;
+               return $count;
        }
 }
 
index 059b6fe..fa9d512 100644 (file)
@@ -83,4 +83,3 @@ class PopulateLogUsertext extends LoggedUpdateMaintenance {
 
 $maintClass = "PopulateLogUsertext";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
diff --git a/maintenance/postgres/archives/patch-sites.sql b/maintenance/postgres/archives/patch-sites.sql
new file mode 100644 (file)
index 0000000..a4f9ed9
--- /dev/null
@@ -0,0 +1,31 @@
+CREATE SEQUENCE sites_site_id_seq;
+CREATE TABLE sites (
+  site_id           INTEGER     NOT NULL    PRIMARY KEY DEFAULT nextval('sites_site_id_seq'),
+  site_global_key   TEXT        NOT NULL,
+  site_type         TEXT        NOT NULL,
+  site_group        TEXT        NOT NULL,
+  site_source       TEXT        NOT NULL,
+  site_language     TEXT        NOT NULL,
+  site_protocol     TEXT        NOT NULL,
+  site_domain       TEXT        NOT NULL,
+  site_data         TEXT        NOT NULL,
+  site_forward      SMALLINT    NOT NULL,
+  site_config       TEXT        NOT NULL
+);
+CREATE UNIQUE INDEX site_global_key ON sites (site_global_key);
+CREATE INDEX site_type ON sites (site_type);
+CREATE INDEX site_group ON sites (site_group);
+CREATE INDEX site_source ON sites (site_source);
+CREATE INDEX site_language ON sites (site_language);
+CREATE INDEX site_protocol ON sites (site_protocol);
+CREATE INDEX site_domain ON sites (site_domain);
+CREATE INDEX site_forward ON sites (site_forward);
+
+CREATE TABLE site_identifiers (
+  si_site   INTEGER NOT NULL,
+  si_type   TEXT    NOT NULL,
+  si_key    TEXT    NOT NULL
+);
+CREATE UNIQUE INDEX si_type_key ON site_identifiers (si_type, si_key);
+CREATE INDEX si_site ON site_identifiers (si_site);
+CREATE INDEX si_key ON site_identifiers (si_key);
index bb1ea0a..9cbabfd 100644 (file)
@@ -531,12 +531,14 @@ CREATE TABLE job (
   job_timestamp       TIMESTAMPTZ,
   job_params          TEXT      NOT NULL,
   job_random          INTEGER   NOT NULL DEFAULT 0,
+  job_attempts        INTEGER   NOT NULL DEFAULT 0,
   job_token           TEXT      NOT NULL DEFAULT '',
   job_token_timestamp TIMESTAMPTZ,
   job_sha1            TEXT NOT NULL DEFAULT ''
 );
 CREATE INDEX job_sha1 ON job (job_sha1);
 CREATE INDEX job_cmd_token ON job (job_cmd, job_token, job_random);
+CREATE INDEX job_cmd_token_id ON job (job_cmd, job_token, job_id);
 CREATE INDEX job_cmd_namespace_title ON job (job_cmd, job_namespace, job_title);
 CREATE INDEX job_timestamp_idx ON job (job_timestamp);
 
@@ -698,3 +700,35 @@ CREATE TABLE module_deps (
   md_deps    TEXT  NOT NULL
 );
 CREATE UNIQUE INDEX md_module_skin ON module_deps (md_module, md_skin);
+
+CREATE SEQUENCE sites_site_id_seq;
+CREATE TABLE sites (
+  site_id           INTEGER     NOT NULL    PRIMARY KEY DEFAULT nextval('sites_site_id_seq'),
+  site_global_key   TEXT        NOT NULL,
+  site_type         TEXT        NOT NULL,
+  site_group        TEXT        NOT NULL,
+  site_source       TEXT        NOT NULL,
+  site_language     TEXT        NOT NULL,
+  site_protocol     TEXT        NOT NULL,
+  site_domain       TEXT        NOT NULL,
+  site_data         TEXT        NOT NULL,
+  site_forward      SMALLINT    NOT NULL,
+  site_config       TEXT        NOT NULL
+);
+CREATE UNIQUE INDEX site_global_key ON sites (site_global_key);
+CREATE INDEX site_type ON sites (site_type);
+CREATE INDEX site_group ON sites (site_group);
+CREATE INDEX site_source ON sites (site_source);
+CREATE INDEX site_language ON sites (site_language);
+CREATE INDEX site_protocol ON sites (site_protocol);
+CREATE INDEX site_domain ON sites (site_domain);
+CREATE INDEX site_forward ON sites (site_forward);
+
+CREATE TABLE site_identifiers (
+  si_site   INTEGER NOT NULL,
+  si_type   TEXT    NOT NULL,
+  si_key    TEXT    NOT NULL
+);
+CREATE UNIQUE INDEX si_type_key ON site_identifiers (si_type, si_key);
+CREATE INDEX si_site ON site_identifiers (si_site);
+CREATE INDEX si_key ON site_identifiers (si_key);
index 87fc997..bb3d68b 100644 (file)
@@ -95,4 +95,3 @@ class PreprocessDump extends DumpIterator {
 
 $maintClass = "PreprocessDump";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 10892c4..2ccf703 100644 (file)
@@ -21,7 +21,7 @@
  * @ingroup Maintenance
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( 1 );
 }
 
index 58fe880..b72c417 100644 (file)
@@ -32,22 +32,27 @@ class PurgeList extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = "Send purge requests for listed pages to squid";
-               $this->addOption( 'purge', 'Whether to update page_touched.' , false, false );
+               $this->addOption( 'purge', 'Whether to update page_touched.', false, false );
                $this->addOption( 'namespace', 'Namespace number', false, true );
+               $this->addOption( 'all', 'Purge all pages', false, false );
+               $this->addOption( 'delay', 'Number of seconds to delay between each purge', false, true );
+               $this->addOption( 'verbose', 'Show more output', false, false, 'v' );
                $this->setBatchSize( 100 );
        }
 
        public function execute() {
-               if( $this->hasOption( 'namespace' ) ) {
-                       $this->purgeNamespace();
+               if ( $this->hasOption( 'all' ) ) {
+                       $this->purgeNamespace( false );
+               } elseif ( $this->hasOption( 'namespace' ) ) {
+                       $this->purgeNamespace( intval( $this->getOption( 'namespace') ) );
                } else {
-                       $this->purgeList();
+                       $this->doPurge();
                }
                $this->output( "Done!\n" );
        }
 
        /** Purge URL coming from stdin */
-       private function purgeList() {
+       private function doPurge() {
                $stdin = $this->getStdin();
                $urls = array();
 
@@ -69,56 +74,41 @@ class PurgeList extends Maintenance {
                                }
                        }
                }
+               $this->output( "Purging " . count( $urls ). " urls\n" );
                $this->sendPurgeRequest( $urls );
        }
 
-       /** Purge a namespace given by --namespace */
-       private function purgeNamespace() {
+       /** Purge a namespace or all pages */
+       private function purgeNamespace( $namespace = false ) {
                $dbr = wfGetDB( DB_SLAVE );
-               $ns = $dbr->addQuotes( $this->getOption( 'namespace') );
-
-               $result = $dbr->select(
-                       array( 'page' ),
-                       array( 'page_namespace', 'page_title' ),
-                       array( "page_namespace = $ns" ),
-                       __METHOD__,
-                       array( 'ORDER BY' => 'page_id' )
-               );
-
-               $start   = 0;
-               $end = $result->numRows();
-               $this->output( "Will purge $end pages from namespace $ns\n" );
-
-               # Do remaining chunk
-               $end += $this->mBatchSize - 1;
-               $blockStart = $start;
-               $blockEnd = $start + $this->mBatchSize - 1;
-
-               while( $blockEnd <= $end ) {
-                       # Select pages we will purge:
-                       $result = $dbr->select(
-                               array( 'page' ),
-                               array( 'page_namespace', 'page_title' ),
-                               array( "page_namespace = $ns" ),
+               $startId = 0;
+               if ( $namespace === false ) {
+                       $conds = array();
+               } else {
+                       $conds = array( 'page_namespace' => $namespace );
+               }
+               while ( true ) {
+                       $res = $dbr->select( 'page', 
+                               array( 'page_id', 'page_namespace', 'page_title' ),
+                               $conds + array( 'page_id > ' . $dbr->addQuotes( $startId ) ),
                                __METHOD__,
-                               array( # conditions
-                                       'ORDER BY' => 'page_id',
-                                       'LIMIT'    => $this->mBatchSize,
-                                       'OFFSET'   => $blockStart,
+                               array(
+                                       'LIMIT' => $this->mBatchSize,
+                                       'ORDER BY' => 'page_id'
+
                                )
                        );
-                       # Initialize/reset URLs to be purged
+                       if ( !$res->numRows() ) {
+                               break;
+                       }
                        $urls = array();
-                       foreach( $result as $row ) {
+                       foreach ( $res as $row ) {
                                $title = Title::makeTitle( $row->page_namespace, $row->page_title );
                                $url = $title->getInternalUrl();
                                $urls[] = $url;
+                               $startId = $row->page_id;
                        }
-
                        $this->sendPurgeRequest( $urls );
-
-                       $blockStart += $this->mBatchSize;
-                       $blockEnd   += $this->mBatchSize;
                }
        }
 
@@ -127,9 +117,23 @@ class PurgeList extends Maintenance {
         * @param $urls array List of URLS to purge from squids
         */
        private function sendPurgeRequest( $urls ) {
-               $this->output( "Purging " . count( $urls ). " urls\n" );
-               $u = new SquidUpdate( $urls );
-               $u->doUpdate();
+               if ( $this->hasOption( 'delay' ) ) {
+                       $delay = floatval( $this->getOption( 'delay' ) );
+                       foreach ( $urls as $url ) {
+                               if ( $this->hasOption( 'verbose' ) ) {
+                                       $this->output( $url . "\n" );
+                               }
+                               $u = new SquidUpdate( array( $url ) );
+                               $u->doUpdate();
+                               usleep( $delay * 1e6 );
+                       }
+               } else {
+                       if ( $this->hasOption( 'verbose' ) ) {
+                               $this->output( implode( "\n", $urls ) . "\n"  );
+                       }
+                       $u = new SquidUpdate( $urls );
+                       $u->doUpdate();
+               }
        }
 
 }
index a91abf9..2d79f36 100644 (file)
@@ -180,4 +180,3 @@ class ReassignEdits extends Maintenance {
 
 $maintClass = "ReassignEdits";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 12da7a8..55f5b4a 100644 (file)
@@ -53,7 +53,7 @@ class RefreshImageMetadata extends Maintenance {
                $this->addOption( 'start', 'Name of file to start with', false, true );
                $this->addOption( 'end', 'Name of file to end with', false, true );
 
-               $this->addOption( 'mime', '(Inefficient!) Only refresh files with this mime type. Can accept wild-card image/*' , false, true );
+               $this->addOption( 'mime', '(Inefficient!) Only refresh files with this mime type. Can accept wild-card image/*', false, true );
                $this->addOption( 'metadata-contains', '(Inefficient!) Only refresh files where the img_metadata field contains this string. Can be used if its known a specific property was being extracted incorrectly.', false, true );
 
        }
index 8d2819d..f9557ce 100644 (file)
@@ -76,32 +76,50 @@ class RunJobs extends Maintenance {
                $n = 0;
 
                $group = JobQueueGroup::singleton();
+               // Handle any required periodic queue maintenance
+               $count = $group->executeReadyPeriodicTasks();
+               if ( $count > 0 ) {
+                       $this->runJobsLog( "Executed $count periodic queue task(s)." );
+               }
+
                do {
                        $job = ( $type === false )
                                ? $group->pop( JobQueueGroup::TYPE_DEFAULT, JobQueueGroup::USE_CACHE )
-                               : $group->get( $type )->pop(); // job from a single queue
+                               : $group->pop( $type ); // job from a single queue
                        if ( $job ) { // found a job
-                               // Perform the job (logging success/failure and runtime)...
-                               $t = microtime( true );
                                $this->runJobsLog( $job->toString() . " STARTING" );
-                               $status = $job->run();
-                               $group->ack( $job ); // done
-                               $t = microtime( true ) - $t;
-                               $timeMs = intval( $t * 1000 );
+
+                               // Run the job...
+                               $t = microtime( true );
+                               try {
+                                       $status = $job->run();
+                                       $error = $job->getLastError();
+                               } catch ( MWException $e ) {
+                                       $status = false;
+                                       $error = get_class( $e ) . ': ' . $e->getMessage();
+                               }
+                               $timeMs = intval( ( microtime( true ) - $t ) * 1000 );
+
+                               // Mark the job as done on success or when the job cannot be retried
+                               if ( $status !== false || !$job->allowRetries() ) {
+                                       $group->ack( $job ); // done
+                               }
+
                                if ( !$status ) {
-                                       $this->runJobsLog( $job->toString() . " t=$timeMs error={$job->error}" );
+                                       $this->runJobsLog( $job->toString() . " t=$timeMs error={$error}" );
                                } else {
                                        $this->runJobsLog( $job->toString() . " t=$timeMs good" );
                                }
+
                                // Break out if we hit the job count or wall time limits...
                                if ( $maxJobs && ++$n >= $maxJobs ) {
                                        break;
-                               }
-                               if ( $maxTime && ( time() - $startTime ) > $maxTime ) {
+                               } elseif ( $maxTime && ( time() - $startTime ) > $maxTime ) {
                                        break;
                                }
+
                                // Don't let any slaves/backups fall behind...
-                               $group->get( $type )->waitForBackups();
+                               $group->get( $job->getType() )->waitForBackups();
                        }
                } while ( $job ); // stop when there are no jobs
        }
index 982c7cb..3036406 100644 (file)
@@ -59,7 +59,7 @@ class ShowStats extends Maintenance {
                $max_length_value = $max_length_desc = 0;
                foreach ( $fields as $field => $desc ) {
                        $max_length_value = max( $max_length_value, strlen( $stats->$field ) );
-                       $max_length_desc  = max( $max_length_desc , strlen( $desc ) ) ;
+                       $max_length_desc  = max( $max_length_desc strlen( $desc ) ) ;
                }
 
                // Show them
@@ -71,4 +71,3 @@ class ShowStats extends Maintenance {
 
 $maintClass = "ShowStats";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 72e6775..ef1ec54 100644 (file)
@@ -33,13 +33,19 @@ class MwSql extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = "Send SQL queries to a MediaWiki database";
+               $this->addOption( 'cluster', 'Use an external cluster by name', false, true );
        }
 
        public function execute() {
-               $dbw = wfGetDB( DB_MASTER );
-               if ( $this->hasArg() ) {
-                       $fileName = $this->getArg();
-                       $file = fopen( $fileName, 'r' );
+               // Get a DB handle (with this wiki's DB select) from the appropriate load balancer
+               if ( $this->hasOption( 'cluster' ) ) {
+                       $lb = wfGetLBFactory()->getExternalLB( $this->getOption( 'cluster' ) );
+                       $dbw = $lb->getConnection( DB_MASTER ); // master for external LB
+               } else {
+                       $dbw = wfGetDB( DB_MASTER ); // master for primary LB for this wiki
+               }
+               if ( $this->hasArg( 0 ) ) {
+                       $file = fopen( $this->getArg( 0 ), 'r' );
                        if ( !$file ) {
                                $this->error( "Unable to open input file", true );
                        }
@@ -105,6 +111,7 @@ class MwSql extends Maintenance {
        public function sqlPrintResult( $res, $db ) {
                if ( !$res ) {
                        // Do nothing
+                       return;
                } elseif ( is_object( $res ) && $res->numRows() ) {
                        foreach ( $res as $row ) {
                                $this->output( print_r( $row, true ) );
index 623dd7b..979e68a 100644 (file)
@@ -4,5 +4,4 @@ CREATE TABLE /*$wgDBprefix*/blobs (
        blob_id integer UNSIGNED NOT NULL AUTO_INCREMENT,
        blob_text longblob,
        PRIMARY KEY  (blob_id)
-) ENGINE=MyISAM MAX_ROWS=100000000 AVG_ROW_LENGTH=100000;
-
+) ENGINE=InnoDB;
index d394558..30cbcf1 100644 (file)
@@ -349,4 +349,3 @@ class FixBug20757 extends Maintenance {
 
 $maintClass = 'FixBug20757';
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index e4a2a45..1049e0c 100644 (file)
@@ -124,5 +124,3 @@ function moveToExternal( $cluster, $maxID, $minID = 1 ) {
                }
        }
 }
-
-
index fe62ddf..5e5cc8f 100644 (file)
@@ -809,4 +809,3 @@ class CgzCopyTransaction {
                }
        }
 }
-
index 0f5cd2b..414eab8 100644 (file)
@@ -110,4 +110,3 @@ function resolveStub( $id, $stubText, $flags ) {
                ), $fname
        );
 }
-
index 1afecc4..3187c31 100644 (file)
@@ -113,4 +113,3 @@ SQL;
 
 $maintClass = 'StorageTypeStats';
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 9487bbf..e13e1b1 100644 (file)
@@ -99,4 +99,3 @@ foreach ( $keys as $id => $key ) {
 }
 $t += microtime( true );
 printf( "Decompression time: %5.2f ms\n", $t * 1000 );
-
index 1cb97f9..c52f07c 100644 (file)
@@ -70,4 +70,3 @@ class DummyTermColorer {
                return '';
        }
 }
-
index 31bae8e..be45a11 100644 (file)
 
 /**
  * Look for duplicate user table entries and optionally prune them.
+ *
+ * This is still used by our MysqlUpdater at:
+ * includes/installer/MysqlUpdater.php
+ *
  * @ingroup Maintenance
  */
 class UserDupes {
-       var $db;
-       var $reassigned;
-       var $trimmed;
-       var $failed;
+       private $db;
+       private $reassigned;
+       private $trimmed;
+       private $failed;
        private $outputCallback;
 
        function __construct( &$database, $outputCallback ) {
index 2181e44..1e1f24b 100644 (file)
@@ -33,4 +33,3 @@ $uo = new userOptions( $options, $args );
 $uo->run();
 
 print "Done.\n";
-
index 655be43..df83928 100644 (file)
@@ -31,6 +31,7 @@ require_once( __DIR__ . '/Maintenance.php' );
  */
 class WaitForSlave extends Maintenance {
        public function __construct() {
+               parent::__construct();
                $this->addArg( 'maxlag', 'How long to wait for the slaves, default 10 seconds', false );
        }
        public function execute() {
index 95f028a..cb8b1be 100644 (file)
@@ -22,7 +22,7 @@
 
 require_once( __DIR__ . '/includes/WebStart.php' );
 
-if( $wgRequest->getVal( 'ctype' ) == 'application/xml' ) {
+if ( $wgRequest->getVal( 'ctype' ) == 'application/xml' ) {
        // Makes testing tweaks about a billion times easier
        $ctype = 'application/xml';
 } else {
@@ -65,7 +65,7 @@ print Xml::element( 'Image',
                'height' => 16,
                'width' => 16,
                'type' => 'image/x-icon' ),
-       wfExpandUrl( $wgFavicon , PROTO_CURRENT ) );
+       wfExpandUrl( $wgFavicon, PROTO_CURRENT ) );
 
 $urls = array();
 
@@ -78,7 +78,7 @@ $urls[] = array(
        'method' => 'get',
        'template' => $searchPage->getCanonicalURL( 'search={searchTerms}' ) );
 
-if( $wgEnableAPI ) {
+if ( $wgEnableAPI ) {
        // JSON interface for search suggestions.
        // Supported in Firefox 2 and later.
        $urls[] = array(
@@ -91,7 +91,7 @@ if( $wgEnableAPI ) {
 // general way than overriding the whole search engine...
 wfRunHooks( 'OpenSearchUrls', array( &$urls ) );
 
-foreach( $urls as $attribs ) {
+foreach ( $urls as $attribs ) {
        print Xml::element( 'Url', $attribs );
 }
 
index 0e4131b..4117d97 100644 (file)
@@ -34,113 +34,111 @@ if ( isset( $_SERVER['MW_COMPILED'] ) ) {
        require ( __DIR__ . '/includes/WebStart.php' );
 }
 
-
 header( 'Content-Type: text/html; charset=utf-8' );
 
 ?>
 <!DOCTYPE html>
 <html>
 <head>
-<meta charset="UTF-8">
-<title>Profiling data</title>
-<style>
-       /* noc.wikimedia.org/base.css */
-
-       * {
-               margin: 0;
-               padding: 0;
-       }
-
-       body {
-               padding: 0.5em 1em;
-               background: #fff;
-               font: 14px/1.6 sans-serif;
-               color: #333;
-       }
+       <meta charset="UTF-8">
+       <title>Profiling data</title>
+       <style>
+               /* noc.wikimedia.org/base.css */
+
+               * {
+                       margin: 0;
+                       padding: 0;
+               }
 
-       p, ul, ol, table {
-               margin: 0.5em 0;
-       }
+               body {
+                       padding: 0.5em 1em;
+                       background: #fff;
+                       font: 14px/1.6 sans-serif;
+                       color: #333;
+               }
 
-       a {
-               color: #0645AD;
-               text-decoration: none;
-       }
+               p, ul, ol, table {
+                       margin: 0.5em 0;
+               }
 
-       a:hover {
-               text-decoration: underline;
-       }
+               a {
+                       color: #0645AD;
+                       text-decoration: none;
+               }
 
-       /*!
-        * Bootstrap v2.1.1
-        *
-        * Copyright 2012 Twitter, Inc
-        * Licensed under the Apache License v2.0
-        * http://www.apache.org/licenses/LICENSE-2.0
-        *
-        * Designed and built with all the love in the world @twitter by @mdo and @fat.
-        */
-
-       table {
-               max-width: 100%;
-               background-color: transparent;
-               border-collapse: collapse;
-               border-spacing: 0;
-       }
+               a:hover {
+                       text-decoration: underline;
+               }
 
-       .table {
-               width: 100%;
-               margin-bottom: 20px;
-       }
+               /*!
+                * Bootstrap v2.1.1
+                *
+                * Copyright 2012 Twitter, Inc
+                * Licensed under the Apache License v2.0
+                * http://www.apache.org/licenses/LICENSE-2.0
+                *
+                * Designed and built with all the love in the world @twitter by @mdo and @fat.
+                */
+
+               table {
+                       max-width: 100%;
+                       background-color: transparent;
+                       border-collapse: collapse;
+                       border-spacing: 0;
+               }
 
-       .table th,
-       .table td {
-               padding: 0.1em;
-               text-align: left;
-               vertical-align: top;
-               border-top: 1px solid #ddd;
-       }
+               .table {
+                       width: 100%;
+                       margin-bottom: 20px;
+               }
 
-       .table th {
-               font-weight: bold;
-       }
+               .table th,
+               .table td {
+                       padding: 0.1em;
+                       text-align: left;
+                       vertical-align: top;
+                       border-top: 1px solid #ddd;
+               }
 
-       .table thead th {
-               vertical-align: bottom;
-       }
+               .table th {
+                       font-weight: bold;
+               }
 
-       .table thead:first-child tr:first-child th,
-       .table thead:first-child tr:first-child td {
-               border-top: 0;
-       }
+               .table thead th {
+                       vertical-align: bottom;
+               }
 
-       .table tbody + tbody {
-               border-top: 2px solid #ddd;
-       }
+               .table thead:first-child tr:first-child th,
+               .table thead:first-child tr:first-child td {
+                       border-top: 0;
+               }
 
-       .table-condensed th,
-       .table-condensed td {
-               padding: 4px 5px;
-       }
+               .table tbody + tbody {
+                       border-top: 2px solid #ddd;
+               }
 
-       .table-striped tbody tr:nth-child(odd) td,
-       .table-striped tbody tr:nth-child(odd) th {
-               background-color: #f9f9f9;
-       }
+               .table-condensed th,
+               .table-condensed td {
+                       padding: 4px 5px;
+               }
 
-       .table-hover tbody tr:hover td,
-       .table-hover tbody tr:hover th {
-               background-color: #f5f5f5;
-       }
+               .table-striped tbody tr:nth-child(odd) td,
+               .table-striped tbody tr:nth-child(odd) th {
+                       background-color: #f9f9f9;
+               }
 
-       hr {
-               margin: 20px 0;
-               border: 0;
-               border-top: 1px solid #eee;
-               border-bottom: 1px solid #fff;
-       }
+               .table-hover tbody tr:hover td,
+               .table-hover tbody tr:hover th {
+                       background-color: #f5f5f5;
+               }
 
-</style>
+               hr {
+                       margin: 20px 0;
+                       border: 0;
+                       border-top: 1px solid #eee;
+                       border-bottom: 1px solid #fff;
+               }
+       </style>
 </head>
 <body>
 <?php
@@ -153,7 +151,7 @@ if ( !$wgEnableProfileInfo ) {
 
 $dbr = wfGetDB( DB_SLAVE );
 
-if( !$dbr->tableExists( 'profiling' ) ) {
+if ( !$dbr->tableExists( 'profiling' ) ) {
        echo '<p>No <code>profiling</code> table exists, so we can\'t show you anything.</p>'
                . '<p>If you want to log profiling data, enable <code>$wgProfileToDatabase</code>'
                . ' in your LocalSettings.php and run <code>maintenance/update.php</code> to'
@@ -163,9 +161,11 @@ if( !$dbr->tableExists( 'profiling' ) ) {
 }
 
 $expand = array();
-if ( isset( $_REQUEST['expand'] ) )
-       foreach( explode( ',', $_REQUEST['expand'] ) as $f )
+if ( isset( $_REQUEST['expand'] ) ) {
+       foreach ( explode( ',', $_REQUEST['expand'] ) as $f ) {
                $expand[$f] = true;
+       }
+}
 
 class profile_point {
        var $name;
@@ -212,19 +212,21 @@ class profile_point {
                        $extet = " <a id=\"{$anchor}\" href=\"{$url}#{$anchor}\">[–]</a>";
                }
                ?>
-               <tr>
-               <th><div style="margin-left: <?php echo (int)$indent; ?>em;">
-                       <?php echo htmlspecialchars( str_replace( ',', ', ', $this->name() ) ) . $extet ?>
-               </div></th>
+       <tr>
+               <th>
+                       <div style="margin-left: <?php echo (int)$indent; ?>em;">
+                               <?php echo htmlspecialchars( str_replace( ',', ', ', $this->name() ) ) . $extet ?>
+                       </div>
+               </th>
                <td class="mw-profileinfo-timep"><?php echo @wfPercent( $this->time() / self::$totaltime * 100 ); ?></td>
                <td class="mw-profileinfo-memoryp"><?php echo @wfPercent( $this->memory() / self::$totalmemory * 100 ); ?></td>
                <td class="mw-profileinfo-count"><?php echo $this->count(); ?></td>
                <td class="mw-profileinfo-cpr"><?php echo round( sprintf( '%.2f', $this->callsPerRequest() ), 2 ); ?></td>
                <td class="mw-profileinfo-tpc"><?php echo round( sprintf( '%.2f', $this->timePerCall() ), 2 ); ?></td>
-               <td class="mw-profileinfo-mpc"><?php echo round( sprintf( '%.2f' ,$this->memoryPerCall() / 1024 ), 2 ); ?></td>
+               <td class="mw-profileinfo-mpc"><?php echo round( sprintf( '%.2f'$this->memoryPerCall() / 1024 ), 2 ); ?></td>
                <td class="mw-profileinfo-tpr"><?php echo @round( sprintf( '%.2f', $this->time() / self::$totalcount ), 2 ); ?></td>
-               <td class="mw-profileinfo-mpr"><?php echo @round( sprintf( '%.2f' ,$this->memory() / self::$totalcount / 1024 ), 2 ); ?></td>
-               </tr>
+               <td class="mw-profileinfo-mpr"><?php echo @round( sprintf( '%.2f'$this->memory() / self::$totalcount / 1024 ), 2 ); ?></td>
+       </tr>
                <?php
                if ( $ex ) {
                        foreach ( $this->children as $child ) {
@@ -274,135 +276,140 @@ class profile_point {
        }
 };
 
-function compare_point(profile_point $a, profile_point $b) {
+function compare_point( profile_point $a, profile_point $b ) {
        global $sort;
        switch ( $sort ) {
-       case 'name':
-               return strcmp( $a->name(), $b->name() );
-       case 'time':
-               return $a->time() > $b->time() ? -1 : 1;
-       case 'memory':
-               return $a->memory() > $b->memory() ? -1 : 1;
-       case 'count':
-               return $a->count() > $b->count() ? -1 : 1;
-       case 'time_per_call':
-               return $a->timePerCall() > $b->timePerCall() ? -1 : 1;
-       case 'memory_per_call':
-               return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1;
-       case 'calls_per_req':
-               return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1;
-       case 'time_per_req':
-               return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1;
-       case 'memory_per_req':
-               return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1;
+               case 'name':
+                       return strcmp( $a->name(), $b->name() );
+               case 'time':
+                       return $a->time() > $b->time() ? -1 : 1;
+               case 'memory':
+                       return $a->memory() > $b->memory() ? -1 : 1;
+               case 'count':
+                       return $a->count() > $b->count() ? -1 : 1;
+               case 'time_per_call':
+                       return $a->timePerCall() > $b->timePerCall() ? -1 : 1;
+               case 'memory_per_call':
+                       return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1;
+               case 'calls_per_req':
+                       return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1;
+               case 'time_per_req':
+                       return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1;
+               case 'memory_per_req':
+                       return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1;
        }
 }
 
 $sorts = array( 'time', 'memory', 'count', 'calls_per_req', 'name',
        'time_per_call', 'memory_per_call', 'time_per_req', 'memory_per_req' );
 $sort = 'time';
-if ( isset( $_REQUEST['sort'] ) && in_array( $_REQUEST['sort'], $sorts ) )
+if ( isset( $_REQUEST['sort'] ) && in_array( $_REQUEST['sort'], $sorts ) ) {
        $sort = $_REQUEST['sort'];
+}
 
 $res = $dbr->select( 'profiling', '*', array(), 'profileinfo.php', array( 'ORDER BY' => 'pf_name ASC' ) );
 
-if (isset( $_REQUEST['filter'] ) )
+if ( isset( $_REQUEST['filter'] ) ) {
        $filter = $_REQUEST['filter'];
-else
+} else {
        $filter = '';
+}
 
 ?>
 <form method="get" action="profileinfo.php">
-<p>
-<input type="text" name="filter" value="<?php echo htmlspecialchars($filter); ?>">
-<input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort); ?>">
-<input type="hidden" name="expand" value="<?php echo htmlspecialchars(implode(",", array_keys($expand))); ?>">
-<input type="submit" value="Filter">
-</p>
+       <p>
+               <input type="text" name="filter" value="<?php echo htmlspecialchars( $filter ); ?>">
+               <input type="hidden" name="sort" value="<?php echo htmlspecialchars( $sort ); ?>">
+               <input type="hidden" name="expand" value="<?php echo htmlspecialchars( implode( ",", array_keys( $expand ) ) ); ?>">
+               <input type="submit" value="Filter">
+       </p>
 </form>
 
 <table class="mw-profileinfo-table table table-striped table-hover">
        <thead>
-               <tr>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'name' ); ?>">Name</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'time' ); ?>">Time (%)</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'memory' ); ?>">Memory (%)</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'count' ); ?>">Count</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'calls_per_req' ); ?>">Calls/req</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_call' ); ?>">ms/call</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_call' ); ?>">kb/call</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_req' ); ?>">ms/req</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_req' ); ?>">kb/req</a></th>
-               </tr>
+       <tr>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'name' ); ?>">Name</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'time' ); ?>">Time (%)</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'memory' ); ?>">Memory (%)</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'count' ); ?>">Count</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'calls_per_req' ); ?>">Calls/req</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_call' ); ?>">ms/call</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_call' ); ?>">kb/call</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_req' ); ?>">ms/req</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_req' ); ?>">kb/req</a></th>
+       </tr>
        </thead>
        <tbody>
-<?php
-profile_point::$totaltime = 0.0;
-profile_point::$totalcount = 0;
-profile_point::$totalmemory = 0.0;
-
-function getEscapedProfileUrl( $_filter = false, $_sort = false, $_expand = false ) {
-       global $filter, $sort, $expand;
-
-       if ( $_expand === false )
-               $_expand = $expand;
-
-       return htmlspecialchars(
-               '?' .
-               wfArrayToCGI( array(
-                       'filter' => $_filter ? $_filter : $filter,
-                       'sort' => $_sort ? $_sort : $sort,
-                       'expand' => implode( ',', array_keys( $_expand ) )
-               ) )
-       );
-}
+       <?php
+       profile_point::$totaltime = 0.0;
+       profile_point::$totalcount = 0;
+       profile_point::$totalmemory = 0.0;
 
-$points = array();
-$queries = array();
-$sqltotal = 0.0;
-
-$last = false;
-foreach( $res as $o ) {
-       $next = new profile_point( $o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory );
-       if( $next->name() == '-total' ) {
-               profile_point::$totaltime = $next->time();
-               profile_point::$totalcount = $next->count();
-               profile_point::$totalmemory = $next->memory();
-       }
-       if ( $last !== false ) {
-               if ( preg_match( '/^'.preg_quote( $last->name(), '/' ).'/', $next->name() ) ) {
-                       $last->add_child($next);
-                       continue;
+       function getEscapedProfileUrl( $_filter = false, $_sort = false, $_expand = false ) {
+               global $filter, $sort, $expand;
+
+               if ( $_expand === false ) {
+                       $_expand = $expand;
+               }
+
+               return htmlspecialchars(
+                       '?' .
+                               wfArrayToCgi( array(
+                                       'filter' => $_filter ? $_filter : $filter,
+                                       'sort' => $_sort ? $_sort : $sort,
+                                       'expand' => implode( ',', array_keys( $_expand ) )
+                               ) )
+               );
+       }
+
+       $points = array();
+       $queries = array();
+       $sqltotal = 0.0;
+
+       $last = false;
+       foreach ( $res as $o ) {
+               $next = new profile_point( $o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory );
+               if ( $next->name() == '-total' ) {
+                       profile_point::$totaltime = $next->time();
+                       profile_point::$totalcount = $next->count();
+                       profile_point::$totalmemory = $next->memory();
+               }
+               if ( $last !== false ) {
+                       if ( preg_match( '/^' . preg_quote( $last->name(), '/' ) . '/', $next->name() ) ) {
+                               $last->add_child( $next );
+                               continue;
+                       }
+               }
+               $last = $next;
+               if ( preg_match( '/^query: /', $next->name() ) || preg_match( '/^query-m: /', $next->name() ) ) {
+                       $sqltotal += $next->time();
+                       $queries[] = $next;
+               } else {
+                       $points[] = $next;
                }
        }
-       $last = $next;
-       if ( preg_match( '/^query: /', $next->name() ) || preg_match( '/^query-m: /', $next->name() ) ) {
-               $sqltotal += $next->time();
-               $queries[] = $next;
-       } else {
-               $points[] = $next;
-       }
-}
 
-$s = new profile_point( 'SQL Queries', 0, $sqltotal, 0, 0 );
-foreach ( $queries as $q )
-       $s->add_child($q);
-$points[] = $s;
+       $s = new profile_point( 'SQL Queries', 0, $sqltotal, 0, 0 );
+       foreach ( $queries as $q )
+               $s->add_child( $q );
+       $points[] = $s;
 
-usort( $points, 'compare_point' );
+       usort( $points, 'compare_point' );
 
-foreach ( $points as $point ) {
-       if ( strlen( $filter ) && !strstr( $point->name(), $filter ) )
-               continue;
+       foreach ( $points as $point ) {
+               if ( strlen( $filter ) && !strstr( $point->name(), $filter ) ) {
+                       continue;
+               }
 
-       $point->display( $expand );
-}
-?>
+               $point->display( $expand );
+       }
+       ?>
        </tbody>
 </table>
 <hr>
-<p>Total time: <code><?php printf('%5.02f', profile_point::$totaltime); ?></code></p>
-<p>Total memory: <code><?php printf('%5.02f', profile_point::$totalmemory / 1024 ); ?></code></p>
-<hr>
+<p>Total time: <code><?php printf( '%5.02f', profile_point::$totaltime ); ?></code></p>
+
+<p>Total memory: <code><?php printf( '%5.02f', profile_point::$totalmemory / 1024 ); ?></code></p>
+<hr />
 </body>
 </html>
index f279c84..51bf05f 100644 (file)
@@ -149,10 +149,6 @@ return array(
                'scripts' => 'resources/jquery/jquery.client.js',
                'targets' => array( 'desktop', 'mobile' ),
        ),
-       'jquery.collapsibleTabs' => array(
-               'scripts' => 'resources/jquery/jquery.collapsibleTabs.js',
-               'dependencies' => 'jquery.delayedBind',
-       ),
        'jquery.color' => array(
                'scripts' => 'resources/jquery/jquery.color.js',
                'dependencies' => 'jquery.colorUtil',
@@ -199,6 +195,7 @@ return array(
        ),
        'jquery.json' => array(
                'scripts' => 'resources/jquery/jquery.json.js',
+               'targets' => array( 'mobile', 'desktop' ),
        ),
        'jquery.localize' => array(
                'scripts' => 'resources/jquery/jquery.localize.js',
@@ -658,6 +655,7 @@ return array(
        ),
        'mediawiki.searchSuggest' => array(
                'scripts' => 'resources/mediawiki/mediawiki.searchSuggest.js',
+               'styles' => 'resources/mediawiki/mediawiki.searchSuggest.css',
                'messages' => array(
                        'searchsuggest-search',
                        'searchsuggest-containing',
@@ -926,6 +924,9 @@ return array(
                ),
                'dependencies' => array( 'mediawiki.libs.jpegmeta', 'mediawiki.util' ),
        ),
+       'mediawiki.special.userlogin.signup' => array(
+               'scripts' => 'resources/mediawiki.special/mediawiki.special.userLogin.signup.js',
+       ),
        'mediawiki.special.javaScriptTest' => array(
                'scripts' => 'resources/mediawiki.special/mediawiki.special.javaScriptTest.js',
                'messages' => array_merge( Skin::getSkinNameMessages(), array(
index ae6f2b0..b0bd685 100644 (file)
                                        // Strings which precede a version number in a user agent string - combined and used as match 1 in
                                        // version detectection
                                        versionPrefixes = [
-                                               'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
+                                               'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
                                                'lynx', 'msie', 'safari', 'ps3'
                                        ],
                                        // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
                                        versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)',
                                        // Names of known browsers
                                        names = [
-                                               'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
+                                               'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
                                                'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq'
                                        ],
                                        // Tanslations for conforming browser names
 
                        var conditions, dir, i, op, val;
                        profile = $.isPlainObject( profile ) ? profile : $.client.profile();
-
                        dir = $( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr';
                        // Check over each browser condition to determine if we are running in a compatible client
                        if ( typeof map[dir] !== 'object' || map[dir][profile.name] === undefined ) {
                                return true;
                        }
                        conditions = map[dir][profile.name];
+                       if ( conditions === false ) {
+                               return false;
+                       }
                        for ( i = 0; i < conditions.length; i++ ) {
                                op = conditions[i][0];
                                val = conditions[i][1];
-                               if ( val === false ) {
-                                       return false;
-                               }
                                if ( typeof val === 'string' ) {
                                        if ( !( eval( 'profile.version' + op + '"' + val + '"' ) ) ) {
                                                return false;
                                        }
                                }
                        }
+
                        return true;
                }
        };
diff --git a/resources/jquery/jquery.collapsibleTabs.js b/resources/jquery/jquery.collapsibleTabs.js
deleted file mode 100644 (file)
index 9b8f8fc..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Collapsible tabs jQuery Plugin
- */
-( function ( $ ) {
-       $.fn.collapsibleTabs = function ( options ) {
-               // return if the function is called on an empty jquery object
-               if ( !this.length ) {
-                       return this;
-               }
-               // Merge options into the defaults
-               var $settings = $.extend( {}, $.collapsibleTabs.defaults, options );
-
-               this.each( function () {
-                       var $el = $( this );
-                       // add the element to our array of collapsible managers
-                       $.collapsibleTabs.instances = ( $.collapsibleTabs.instances.length === 0 ?
-                               $el : $.collapsibleTabs.instances.add( $el ) );
-                       // attach the settings to the elements
-                       $el.data( 'collapsibleTabsSettings', $settings );
-                       // attach data to our collapsible elements
-                       $el.children( $settings.collapsible ).each( function () {
-                               $.collapsibleTabs.addData( $( this ) );
-                       } );
-               } );
-
-               // if we haven't already bound our resize hanlder, bind it now
-               if ( !$.collapsibleTabs.boundEvent ) {
-                       $( window )
-                               .delayedBind( '500', 'resize', function ( ) {
-                                       $.collapsibleTabs.handleResize();
-                               } );
-               }
-               // call our resize handler to setup the page
-               $.collapsibleTabs.handleResize();
-               return this;
-       };
-       $.collapsibleTabs = {
-               instances: [],
-               boundEvent: null,
-               defaults: {
-                       expandedContainer: '#p-views ul',
-                       collapsedContainer: '#p-cactions ul',
-                       collapsible: 'li.collapsible',
-                       shifting: false,
-                       expandCondition: function ( eleWidth ) {
-                               return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() )
-                                       < ( $( '#right-navigation' ).position().left - eleWidth );
-                       },
-                       collapseCondition: function () {
-                               return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() )
-                                       > $( '#right-navigation' ).position().left;
-                       }
-               },
-               addData: function ( $collapsible ) {
-                       var $settings = $collapsible.parent().data( 'collapsibleTabsSettings' );
-                       if ( $settings !== null ) {
-                               $collapsible.data( 'collapsibleTabsSettings', {
-                                       expandedContainer: $settings.expandedContainer,
-                                       collapsedContainer: $settings.collapsedContainer,
-                                       expandedWidth: $collapsible.width(),
-                                       prevElement: $collapsible.prev()
-                               } );
-                       }
-               },
-               getSettings: function ( $collapsible ) {
-                       var $settings = $collapsible.data( 'collapsibleTabsSettings' );
-                       if ( $settings === undefined ) {
-                               $.collapsibleTabs.addData( $collapsible );
-                               $settings = $collapsible.data( 'collapsibleTabsSettings' );
-                       }
-                       return $settings;
-               },
-               /**
-                * @param {jQuery.Event} e
-                */
-               handleResize: function () {
-                       $.collapsibleTabs.instances.each( function () {
-                               var $el = $( this ),
-                                       data = $.collapsibleTabs.getSettings( $el );
-
-                               if ( data.shifting ) {
-                                       return;
-                               }
-
-                               // if the two navigations are colliding
-                               if ( $el.children( data.collapsible ).length > 0 && data.collapseCondition() ) {
-
-                                       $el.trigger( 'beforeTabCollapse' );
-                                       // move the element to the dropdown menu
-                                       $.collapsibleTabs.moveToCollapsed( $el.children( data.collapsible + ':last' ) );
-                               }
-
-                               // if there are still moveable items in the dropdown menu,
-                               // and there is sufficient space to place them in the tab container
-                               if ( $( data.collapsedContainer + ' ' + data.collapsible ).length > 0
-                                               && data.expandCondition( $.collapsibleTabs.getSettings( $( data.collapsedContainer ).children(
-                                                               data.collapsible + ':first' ) ).expandedWidth ) ) {
-                                       //move the element from the dropdown to the tab
-                                       $el.trigger( 'beforeTabExpand' );
-                                       $.collapsibleTabs
-                                               .moveToExpanded( data.collapsedContainer + ' ' + data.collapsible + ':first' );
-                               }
-                       });
-               },
-               moveToCollapsed: function ( ele ) {
-                       var $moving = $( ele ),
-                               data = $.collapsibleTabs.getSettings( $moving ),
-                               dataExp = $.collapsibleTabs.getSettings( data.expandedContainer );
-                       dataExp.shifting = true;
-                       $moving
-                               .detach()
-                               .prependTo( data.collapsedContainer )
-                               .data( 'collapsibleTabsSettings', data );
-                       dataExp.shifting = false;
-                       $.collapsibleTabs.handleResize();
-               },
-               moveToExpanded: function ( ele ) {
-                       var $moving = $( ele ),
-                               data = $.collapsibleTabs.getSettings( $moving ),
-                               dataExp = $.collapsibleTabs.getSettings( data.expandedContainer );
-                       dataExp.shifting = true;
-                       // remove this element from where it's at and put it in the dropdown menu
-                       $moving.detach().insertAfter( data.prevElement ).data( 'collapsibleTabsSettings', data );
-                       dataExp.shifting = false;
-                       $.collapsibleTabs.handleResize();
-               }
-       };
-
-}( jQuery ) );
index 3e786ec..d9a2b19 100644 (file)
@@ -1,9 +1,31 @@
 /**
- * Simple Placeholder-based Localization
+ * @class jQuery.plugin.localize
+ */
+( function ( $, mw ) {
+
+/**
+ * Gets a localized message, using parameters from options if present.
+ * @ignore
+ *
+ * @param {Object} options
+ * @param {string} key
+ * @returns {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
+ * 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
+ * `<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:
  * Appends something like this to the body...
  *     <p>You may not get there all in one piece.</p>
  *
- */
-( function ( $, mw ) {
-
-/**
- * Gets a localized message, using parameters from options if present.
- *
- * @function
- * @param {String} key Message key to get localized message for
- * @returns {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.
- *
  * @method
  * @param {Object} options Map of options to be used while localizing
- * @param {String} options.prefix String to prepend to all message keys
+ * @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
- * @returns {jQuery} This selection
+ * @return {jQuery}
  */
 $.fn.localize = function ( options ) {
        var $target = this,
@@ -162,4 +162,9 @@ $.fn.localize = function ( options ) {
 // Let IE know about the msg tag before it's used...
 document.createElement( 'msg' );
 
+/**
+ * @class jQuery
+ * @mixins jQuery.plugin.localize
+ */
+
 }( jQuery, mediaWiki ) );
index 55970e0..d7fc0c8 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * QUnit v1.10.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.11.0 - A JavaScript Unit Testing Framework
  *
  * http://qunitjs.com
  *
@@ -20,7 +20,7 @@
 
 /** Resets */
 
-#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
        margin: 0;
        padding: 0;
 }
        color: #000;
 }
 
-#qunit-tests ol {
+#qunit-tests li .runtime {
+       float: right;
+       font-size: smaller;
+}
+
+.qunit-assert-list {
        margin-top: 0.5em;
        padding: 0.5em;
 
        -webkit-border-radius: 5px;
 }
 
+.qunit-collapsed {
+       display: none;
+}
+
 #qunit-tests table {
        border-collapse: collapse;
        margin-top: .2em;
index d4f17b5..302545f 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * QUnit v1.10.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.11.0 - A JavaScript Unit Testing Framework
  *
  * http://qunitjs.com
  *
@@ -11,6 +11,7 @@
 (function( window ) {
 
 var QUnit,
+       assert,
        config,
        onErrorFnPrev,
        testId = 0,
@@ -20,18 +21,67 @@ var QUnit,
        // Keep a local reference to Date (GH-283)
        Date = window.Date,
        defined = {
-       setTimeout: typeof window.setTimeout !== "undefined",
-       sessionStorage: (function() {
-               var x = "qunit-test-string";
-               try {
-                       sessionStorage.setItem( x, x );
-                       sessionStorage.removeItem( x );
-                       return true;
-               } catch( e ) {
-                       return false;
+               setTimeout: typeof window.setTimeout !== "undefined",
+               sessionStorage: (function() {
+                       var x = "qunit-test-string";
+                       try {
+                               sessionStorage.setItem( x, x );
+                               sessionStorage.removeItem( x );
+                               return true;
+                       } catch( e ) {
+                               return false;
+                       }
+               }())
+       },
+       /**
+        * Provides a normalized error string, correcting an issue
+        * with IE 7 (and prior) where Error.prototype.toString is
+        * not properly implemented
+        *
+        * Based on http://es5.github.com/#x15.11.4.4
+        *
+        * @param {String|Error} error
+        * @return {String} error message
+        */
+       errorString = function( error ) {
+               var name, message,
+                       errorString = error.toString();
+               if ( errorString.substring( 0, 7 ) === "[object" ) {
+                       name = error.name ? error.name.toString() : "Error";
+                       message = error.message ? error.message.toString() : "";
+                       if ( name && message ) {
+                               return name + ": " + message;
+                       } else if ( name ) {
+                               return name;
+                       } else if ( message ) {
+                               return message;
+                       } else {
+                               return "Error";
+                       }
+               } else {
+                       return errorString;
                }
-       }())
-};
+       },
+       /**
+        * Makes a clone of an object using only Array or Object as base,
+        * and copies over the own enumerable properties.
+        *
+        * @param {Object} obj
+        * @return {Object} New object with only the own properties (recursively).
+        */
+       objectValues = function( obj ) {
+               // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
+               /*jshint newcap: false */
+               var key, val,
+                       vals = QUnit.is( "array", obj ) ? [] : {};
+               for ( key in obj ) {
+                       if ( hasOwn.call( obj, key ) ) {
+                               val = obj[key];
+                               vals[key] = val === Object(val) ? objectValues(val) : val;
+                       }
+               }
+               return vals;
+       };
 
 function Test( settings ) {
        extend( this, settings );
@@ -44,11 +94,11 @@ Test.count = 0;
 Test.prototype = {
        init: function() {
                var a, b, li,
-        tests = id( "qunit-tests" );
+                       tests = id( "qunit-tests" );
 
                if ( tests ) {
                        b = document.createElement( "strong" );
-                       b.innerHTML = this.name;
+                       b.innerHTML = this.nameHtml;
 
                        // `a` initialized at top of scope
                        a = document.createElement( "a" );
@@ -92,6 +142,7 @@ Test.prototype = {
                        teardown: function() {}
                }, this.moduleTestEnvironment );
 
+               this.started = +new Date();
                runLoggingCallbacks( "testStart", QUnit, {
                        name: this.testName,
                        module: this.module
@@ -111,7 +162,7 @@ Test.prototype = {
                try {
                        this.testEnvironment.setup.call( this.testEnvironment );
                } catch( e ) {
-                       QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
+                       QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
                }
        },
        run: function() {
@@ -120,22 +171,28 @@ Test.prototype = {
                var running = id( "qunit-testresult" );
 
                if ( running ) {
-                       running.innerHTML = "Running: <br/>" + this.name;
+                       running.innerHTML = "Running: <br/>" + this.nameHtml;
                }
 
                if ( this.async ) {
                        QUnit.stop();
                }
 
+               this.callbackStarted = +new Date();
+
                if ( config.notrycatch ) {
                        this.callback.call( this.testEnvironment, QUnit.assert );
+                       this.callbackRuntime = +new Date() - this.callbackStarted;
                        return;
                }
 
                try {
                        this.callback.call( this.testEnvironment, QUnit.assert );
+                       this.callbackRuntime = +new Date() - this.callbackStarted;
                } catch( e ) {
-                       QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) );
+                       this.callbackRuntime = +new Date() - this.callbackStarted;
+
+                       QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
                        // else next test will carry the responsibility
                        saveGlobal();
 
@@ -148,38 +205,43 @@ Test.prototype = {
        teardown: function() {
                config.current = this;
                if ( config.notrycatch ) {
+                       if ( typeof this.callbackRuntime === "undefined" ) {
+                               this.callbackRuntime = +new Date() - this.callbackStarted;
+                       }
                        this.testEnvironment.teardown.call( this.testEnvironment );
                        return;
                } else {
                        try {
                                this.testEnvironment.teardown.call( this.testEnvironment );
                        } catch( e ) {
-                               QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
+                               QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
                        }
                }
                checkPollution();
        },
        finish: function() {
                config.current = this;
-               if ( config.requireExpects && this.expected == null ) {
+               if ( config.requireExpects && this.expected === null ) {
                        QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
-               } else if ( this.expected != null && this.expected != this.assertions.length ) {
+               } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
                        QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
-               } else if ( this.expected == null && !this.assertions.length ) {
+               } else if ( this.expected === null && !this.assertions.length ) {
                        QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
                }
 
-               var assertion, a, b, i, li, ol,
+               var i, assertion, a, b, time, li, ol,
                        test = this,
                        good = 0,
                        bad = 0,
                        tests = id( "qunit-tests" );
 
+               this.runtime = +new Date() - this.started;
                config.stats.all += this.assertions.length;
                config.moduleStats.all += this.assertions.length;
 
                if ( tests ) {
                        ol = document.createElement( "ol" );
+                       ol.className = "qunit-assert-list";
 
                        for ( i = 0; i < this.assertions.length; i++ ) {
                                assertion = this.assertions[i];
@@ -208,22 +270,22 @@ Test.prototype = {
                        }
 
                        if ( bad === 0 ) {
-                               ol.style.display = "none";
+                               addClass( ol, "qunit-collapsed" );
                        }
 
                        // `b` initialized at top of scope
                        b = document.createElement( "strong" );
-                       b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+                       b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
 
                        addEvent(b, "click", function() {
-                               var next = b.nextSibling.nextSibling,
-                                       display = next.style.display;
-                               next.style.display = display === "none" ? "block" : "none";
+                               var next = b.parentNode.lastChild,
+                                       collapsed = hasClass( next, "qunit-collapsed" );
+                               ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
                        });
 
                        addEvent(b, "dblclick", function( e ) {
                                var target = e && e.target ? e.target : window.event.srcElement;
-                               if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
+                               if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
                                        target = target.parentNode;
                                }
                                if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
@@ -231,13 +293,19 @@ Test.prototype = {
                                }
                        });
 
+                       // `time` initialized at top of scope
+                       time = document.createElement( "span" );
+                       time.className = "runtime";
+                       time.innerHTML = this.runtime + " ms";
+
                        // `li` initialized at top of scope
                        li = id( this.id );
                        li.className = bad ? "fail" : "pass";
                        li.removeChild( li.firstChild );
                        a = li.firstChild;
                        li.appendChild( b );
-                       li.appendChild ( a );
+                       li.appendChild( a );
+                       li.appendChild( time );
                        li.appendChild( ol );
 
                } else {
@@ -255,7 +323,8 @@ Test.prototype = {
                        module: this.module,
                        failed: bad,
                        passed: this.assertions.length - bad,
-                       total: this.assertions.length
+                       total: this.assertions.length,
+                       duration: this.runtime
                });
 
                QUnit.reset();
@@ -321,7 +390,7 @@ QUnit = {
 
        test: function( testName, expected, callback, async ) {
                var test,
-                       name = "<span class='test-name'>" + escapeInnerText( testName ) + "</span>";
+                       nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
 
                if ( arguments.length === 2 ) {
                        callback = expected;
@@ -329,11 +398,11 @@ QUnit = {
                }
 
                if ( config.currentModule ) {
-                       name = "<span class='module-name'>" + config.currentModule + "</span>: " + name;
+                       nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
                }
 
                test = new Test({
-                       name: name,
+                       nameHtml: nameHtml,
                        testName: testName,
                        expected: expected,
                        async: async,
@@ -360,6 +429,18 @@ QUnit = {
        },
 
        start: function( count ) {
+               // QUnit hasn't been initialized yet.
+               // Note: RequireJS (et al) may delay onLoad
+               if ( config.semaphore === undefined ) {
+                       QUnit.begin(function() {
+                               // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+                               setTimeout(function() {
+                                       QUnit.start( count );
+                               });
+                       });
+                       return;
+               }
+
                config.semaphore -= count || 1;
                // don't start until equal number of stop-calls
                if ( config.semaphore > 0 ) {
@@ -368,6 +449,8 @@ QUnit = {
                // ignore if start is called more often then stop
                if ( config.semaphore < 0 ) {
                        config.semaphore = 0;
+                       QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+                       return;
                }
                // A slight delay, to avoid any current callbacks
                if ( defined.setTimeout ) {
@@ -403,11 +486,14 @@ QUnit = {
        }
 };
 
+// `assert` initialized at top of scope
 // Asssert helpers
-// All of these must call either QUnit.push() or manually do:
+// All of these must either call QUnit.push() or manually do:
 // - runLoggingCallbacks( "log", .. );
 // - config.current.assertions.push({ .. });
-QUnit.assert = {
+// We attach it to the QUnit object *after* we expose the public API,
+// otherwise `assert` will become a global variable in browsers (#341).
+assert = {
        /**
         * Asserts rough true-ish result.
         * @name ok
@@ -428,14 +514,14 @@ QUnit.assert = {
                                message: msg
                        };
 
-               msg = escapeInnerText( msg || (result ? "okay" : "failed" ) );
+               msg = escapeText( msg || (result ? "okay" : "failed" ) );
                msg = "<span class='test-message'>" + msg + "</span>";
 
                if ( !result ) {
                        source = sourceFromStacktrace( 2 );
                        if ( source ) {
                                details.source = source;
-                               msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr></table>";
+                               msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
                        }
                }
                runLoggingCallbacks( "log", QUnit, details );
@@ -453,6 +539,7 @@ QUnit.assert = {
         * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
         */
        equal: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
                QUnit.push( expected == actual, actual, expected, message );
        },
 
@@ -461,9 +548,30 @@ QUnit.assert = {
         * @function
         */
        notEqual: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
                QUnit.push( expected != actual, actual, expected, message );
        },
 
+       /**
+        * @name propEqual
+        * @function
+        */
+       propEqual: function( actual, expected, message ) {
+               actual = objectValues(actual);
+               expected = objectValues(expected);
+               QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+       },
+
+       /**
+        * @name notPropEqual
+        * @function
+        */
+       notPropEqual: function( actual, expected, message ) {
+               actual = objectValues(actual);
+               expected = objectValues(expected);
+               QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+       },
+
        /**
         * @name deepEqual
         * @function
@@ -496,8 +604,9 @@ QUnit.assert = {
                QUnit.push( expected !== actual, actual, expected, message );
        },
 
-       throws: function( block, expected, message ) {
+       "throws": function( block, expected, message ) {
                var actual,
+                       expectedOutput = expected,
                        ok = false;
 
                // 'expected' is optional
@@ -518,18 +627,20 @@ QUnit.assert = {
                        // we don't want to validate thrown error
                        if ( !expected ) {
                                ok = true;
+                               expectedOutput = null;
                        // expected is a regexp
                        } else if ( QUnit.objectType( expected ) === "regexp" ) {
-                               ok = expected.test( actual );
+                               ok = expected.test( errorString( actual ) );
                        // expected is a constructor
                        } else if ( actual instanceof expected ) {
                                ok = true;
                        // expected is a validation function which returns true is validation passed
                        } else if ( expected.call( {}, actual ) === true ) {
+                               expectedOutput = null;
                                ok = true;
                        }
 
-                       QUnit.push( ok, actual, null, message );
+                       QUnit.push( ok, actual, expectedOutput, message );
                } else {
                        QUnit.pushFailure( message, null, 'No exception was thrown.' );
                }
@@ -538,15 +649,16 @@ QUnit.assert = {
 
 /**
  * @deprecate since 1.8.0
- * Kept assertion helpers in root for backwards compatibility
+ * Kept assertion helpers in root for backwards compatibility.
  */
-extend( QUnit, QUnit.assert );
+extend( QUnit, assert );
 
 /**
  * @deprecated since 1.9.0
- * Kept global "raises()" for backwards compatibility
+ * Kept root "raises()" for backwards compatibility.
+ * (Note that we don't introduce assert.raises).
  */
-QUnit.raises = QUnit.assert.throws;
+QUnit.raises = assert[ "throws" ];
 
 /**
  * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
@@ -622,6 +734,15 @@ config = {
        moduleDone: []
 };
 
+// Export global variables, unless an 'exports' object exists,
+// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
+if ( typeof exports === "undefined" ) {
+       extend( window, QUnit );
+
+       // Expose QUnit object
+       window.QUnit = QUnit;
+}
+
 // Initialize more QUnit.config and QUnit.urlParams
 (function() {
        var i,
@@ -655,18 +776,11 @@ config = {
        QUnit.isLocal = location.protocol === "file:";
 }());
 
-// Export global variables, unless an 'exports' object exists,
-// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
-if ( typeof exports === "undefined" ) {
-       extend( window, QUnit );
-
-       // Expose QUnit object
-       window.QUnit = QUnit;
-}
-
 // Extend QUnit object,
 // these after set here because they should not be exposed as global functions
 extend( QUnit, {
+       assert: assert,
+
        config: config,
 
        // Initialize the configuration options
@@ -681,7 +795,7 @@ extend( QUnit, {
                        autorun: false,
                        filter: "",
                        queue: [],
-                       semaphore: 0
+                       semaphore: 1
                });
 
                var tests, banner, result,
@@ -689,7 +803,7 @@ extend( QUnit, {
 
                if ( qunit ) {
                        qunit.innerHTML =
-                               "<h1 id='qunit-header'>" + escapeInnerText( document.title ) + "</h1>" +
+                               "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
                                "<h2 id='qunit-banner'></h2>" +
                                "<div id='qunit-testrunner-toolbar'></div>" +
                                "<h2 id='qunit-userAgent'></h2>" +
@@ -745,7 +859,7 @@ extend( QUnit, {
 
        // Safe object type checking
        is: function( type, obj ) {
-               return QUnit.objectType( obj ) == type;
+               return QUnit.objectType( obj ) === type;
        },
 
        objectType: function( obj ) {
@@ -757,7 +871,8 @@ extend( QUnit, {
                                return "null";
                }
 
-               var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || "";
+               var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+                       type = match && match[1] || "";
 
                switch ( type ) {
                        case "Number":
@@ -794,16 +909,16 @@ extend( QUnit, {
                                expected: expected
                        };
 
-               message = escapeInnerText( message ) || ( result ? "okay" : "failed" );
+               message = escapeText( message ) || ( result ? "okay" : "failed" );
                message = "<span class='test-message'>" + message + "</span>";
                output = message;
 
                if ( !result ) {
-                       expected = escapeInnerText( QUnit.jsDump.parse(expected) );
-                       actual = escapeInnerText( QUnit.jsDump.parse(actual) );
+                       expected = escapeText( QUnit.jsDump.parse(expected) );
+                       actual = escapeText( QUnit.jsDump.parse(actual) );
                        output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
 
-                       if ( actual != expected ) {
+                       if ( actual !== expected ) {
                                output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
                                output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
                        }
@@ -812,7 +927,7 @@ extend( QUnit, {
 
                        if ( source ) {
                                details.source = source;
-                               output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>";
+                               output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
                        }
 
                        output += "</table>";
@@ -839,19 +954,19 @@ extend( QUnit, {
                                message: message
                        };
 
-               message = escapeInnerText( message ) || "error";
+               message = escapeText( message ) || "error";
                message = "<span class='test-message'>" + message + "</span>";
                output = message;
 
                output += "<table>";
 
                if ( actual ) {
-                       output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeInnerText( actual ) + "</pre></td></tr>";
+                       output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
                }
 
                if ( source ) {
                        details.source = source;
-                       output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>";
+                       output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
                }
 
                output += "</table>";
@@ -876,7 +991,8 @@ extend( QUnit, {
                        querystring += encodeURIComponent( key ) + "=" +
                                encodeURIComponent( params[ key ] ) + "&";
                }
-               return window.location.pathname + querystring.slice( 0, -1 );
+               return window.location.protocol + "//" + window.location.host +
+                       window.location.pathname + querystring.slice( 0, -1 );
        },
 
        extend: extend,
@@ -907,7 +1023,7 @@ extend( QUnit.constructor.prototype, {
        // testStart: { name }
        testStart: registerLoggingCallback( "testStart" ),
 
-       // testDone: { name, failed, passed, total }
+       // testDone: { name, failed, passed, total, duration }
        testDone: registerLoggingCallback( "testDone" ),
 
        // moduleStart: { name }
@@ -925,9 +1041,10 @@ QUnit.load = function() {
        runLoggingCallbacks( "begin", QUnit, {} );
 
        // Initialize the config, saving the execution queue
-       var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter,
-           numModules = 0,
-           moduleFilterHtml = "",
+       var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+               urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
+               numModules = 0,
+               moduleFilterHtml = "",
                urlConfigHtml = "",
                oldconfig = extend( {}, config );
 
@@ -948,14 +1065,24 @@ QUnit.load = function() {
                        };
                }
                config[ val.id ] = QUnit.urlParams[ val.id ];
-               urlConfigHtml += "<input id='qunit-urlconfig-" + val.id + "' name='" + val.id + "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + " title='" + val.tooltip + "'><label for='qunit-urlconfig-" + val.id + "' title='" + val.tooltip + "'>" + val.label + "</label>";
+               urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+                       "' name='" + escapeText( val.id ) +
+                       "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
+                       " title='" + escapeText( val.tooltip ) +
+                       "'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+                       "' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
        }
 
-       moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + ( config.module === undefined  ? "selected" : "" ) + ">< All Modules ></option>";
+       moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+               ( config.module === undefined  ? "selected='selected'" : "" ) +
+               ">< All Modules ></option>";
+
        for ( i in config.modules ) {
                if ( config.modules.hasOwnProperty( i ) ) {
                        numModules += 1;
-                       moduleFilterHtml += "<option value='" + encodeURIComponent(i) + "' " + ( config.module === i ? "selected" : "" ) + ">" + i + "</option>";
+                       moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(i) ) + "' " +
+                               ( config.module === i ? "selected='selected'" : "" ) +
+                               ">" + escapeText(i) + "</option>";
                }
        }
        moduleFilterHtml += "</select>";
@@ -1014,22 +1141,28 @@ QUnit.load = function() {
                label.innerHTML = "Hide passed tests";
                toolbar.appendChild( label );
 
-               urlConfigCheckboxes = document.createElement( 'span' );
-               urlConfigCheckboxes.innerHTML = urlConfigHtml;
-               addEvent( urlConfigCheckboxes, "change", function( event ) {
-                       var params = {};
-                       params[ event.target.name ] = event.target.checked ? true : undefined;
+               urlConfigCheckboxesContainer = document.createElement("span");
+               urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
+               urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
+               // For oldIE support:
+               // * Add handlers to the individual elements instead of the container
+               // * Use "click" instead of "change"
+               // * Fallback from event.target to event.srcElement
+               addEvents( urlConfigCheckboxes, "click", function( event ) {
+                       var params = {},
+                               target = event.target || event.srcElement;
+                       params[ target.name ] = target.checked ? true : undefined;
                        window.location = QUnit.url( params );
                });
-               toolbar.appendChild( urlConfigCheckboxes );
+               toolbar.appendChild( urlConfigCheckboxesContainer );
 
                if (numModules > 1) {
                        moduleFilter = document.createElement( 'span' );
                        moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
                        moduleFilter.innerHTML = moduleFilterHtml;
-                       addEvent( moduleFilter, "change", function() {
+                       addEvent( moduleFilter.lastChild, "change", function() {
                                var selectBox = moduleFilter.getElementsByTagName("select")[0],
-                                   selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+                                       selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
 
                                window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
                        });
@@ -1106,7 +1239,7 @@ function done() {
                        " milliseconds.<br/>",
                        "<span class='passed'>",
                        passed,
-                       "</span> tests of <span class='total'>",
+                       "</span> assertions of <span class='total'>",
                        config.stats.all,
                        "</span> passed, <span class='failed'>",
                        config.stats.bad,
@@ -1199,7 +1332,7 @@ function validTest( test ) {
 function extractStacktrace( e, offset ) {
        offset = offset === undefined ? 3 : offset;
 
-       var stack, include, i, regex;
+       var stack, include, i;
 
        if ( e.stacktrace ) {
                // Opera
@@ -1213,7 +1346,7 @@ function extractStacktrace( e, offset ) {
                if ( fileName ) {
                        include = [];
                        for ( i = offset; i < stack.length; i++ ) {
-                               if ( stack[ i ].indexOf( fileName ) != -1 ) {
+                               if ( stack[ i ].indexOf( fileName ) !== -1 ) {
                                        break;
                                }
                                include.push( stack[ i ] );
@@ -1242,17 +1375,27 @@ function sourceFromStacktrace( offset ) {
        }
 }
 
-function escapeInnerText( s ) {
+/**
+ * Escape text for attribute or text content.
+ */
+function escapeText( s ) {
        if ( !s ) {
                return "";
        }
        s = s + "";
-       return s.replace( /[\&<>]/g, function( s ) {
+       // Both single quotes and double quotes (for attributes)
+       return s.replace( /['"<>&]/g, function( s ) {
                switch( s ) {
-                       case "&": return "&amp;";
-                       case "<": return "&lt;";
-                       case ">": return "&gt;";
-                       default: return s;
+                       case '\'':
+                               return '&#039;';
+                       case '"':
+                               return '&quot;';
+                       case '<':
+                               return '&lt;';
+                       case '>':
+                               return '&gt;';
+                       case '&':
+                               return '&amp;';
                }
        });
 }
@@ -1300,7 +1443,7 @@ function saveGlobal() {
        }
 }
 
-function checkPollution( name ) {
+function checkPollution() {
        var newGlobals,
                deletedGlobals,
                old = config.pollution;
@@ -1349,16 +1492,53 @@ function extend( a, b ) {
        return a;
 }
 
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
 function addEvent( elem, type, fn ) {
+       // Standards-based browsers
        if ( elem.addEventListener ) {
                elem.addEventListener( type, fn, false );
-       } else if ( elem.attachEvent ) {
-               elem.attachEvent( "on" + type, fn );
+       // IE
        } else {
-               fn();
+               elem.attachEvent( "on" + type, fn );
        }
 }
 
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+       var i = elems.length;
+       while ( i-- ) {
+               addEvent( elems[i], type, fn );
+       }
+}
+
+function hasClass( elem, name ) {
+       return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
+
+function addClass( elem, name ) {
+       if ( !hasClass( elem, name ) ) {
+               elem.className += (elem.className ? " " : "") + name;
+       }
+}
+
+function removeClass( elem, name ) {
+       var set = " " + elem.className + " ";
+       // Class name may appear multiple times
+       while ( set.indexOf(" " + name + " ") > -1 ) {
+               set = set.replace(" " + name + " " , " ");
+       }
+       // If possible, trim it for prettiness, but not neccecarily
+       elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set );
+}
+
 function id( name ) {
        return !!( typeof document !== "undefined" && document && document.getElementById ) &&
                document.getElementById( name );
@@ -1372,7 +1552,6 @@ function registerLoggingCallback( key ) {
 
 // Supports deprecated method of completely overwriting logging callbacks
 function runLoggingCallbacks( key, scope, args ) {
-       //debugger;
        var i, callbacks;
        if ( QUnit.hasOwnProperty( key ) ) {
                QUnit[ key ].call(scope, args );
@@ -1414,6 +1593,7 @@ QUnit.equiv = (function() {
 
                        // for string, boolean, number and null
                        function useStrictEquality( b, a ) {
+                               /*jshint eqeqeq:false */
                                if ( b instanceof a.constructor || a instanceof b.constructor ) {
                                        // to catch short annotaion VS 'new' annotation of a
                                        // declaration
@@ -1610,7 +1790,8 @@ QUnit.jsDump = (function() {
 
        var reName = /^function (\w+)/,
                jsDump = {
-                       parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance
+                       // type is used mostly internally, you can fix a (custom)type in advance
+                       parse: function( obj, type, stack ) {
                                stack = stack || [ ];
                                var inStack, res,
                                        parser = this.parsers[ type || this.typeOf(obj) ];
@@ -1618,18 +1799,16 @@ QUnit.jsDump = (function() {
                                type = typeof parser;
                                inStack = inArray( obj, stack );
 
-                               if ( inStack != -1 ) {
+                               if ( inStack !== -1 ) {
                                        return "recursion(" + (inStack - stack.length) + ")";
                                }
-                               //else
-                               if ( type == "function" )  {
+                               if ( type === "function" )  {
                                        stack.push( obj );
                                        res = parser.call( this, obj, stack );
                                        stack.pop();
                                        return res;
                                }
-                               // else
-                               return ( type == "string" ) ? parser : this.parsers.error;
+                               return ( type === "string" ) ? parser : this.parsers.error;
                        },
                        typeOf: function( obj ) {
                                var type;
@@ -1656,6 +1835,8 @@ QUnit.jsDump = (function() {
                                        ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
                                ) {
                                        type = "array";
+                               } else if ( obj.constructor === Error.prototype.constructor ) {
+                                       type = "error";
                                } else {
                                        type = typeof obj;
                                }
@@ -1664,7 +1845,8 @@ QUnit.jsDump = (function() {
                        separator: function() {
                                return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
                        },
-                       indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
+                       // extra can be a number, shortcut for increasing-calling-decreasing
+                       indent: function( extra ) {
                                if ( !this.multiline ) {
                                        return "";
                                }
@@ -1693,13 +1875,16 @@ QUnit.jsDump = (function() {
                        parsers: {
                                window: "[Window]",
                                document: "[Document]",
-                               error: "[ERROR]", //when no parser is found, shouldn"t happen
+                               error: function(error) {
+                                       return "Error(\"" + error.message + "\")";
+                               },
                                unknown: "[Unknown]",
                                "null": "null",
                                "undefined": "undefined",
                                "function": function( fn ) {
                                        var ret = "function",
-                                               name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE
+                                               // functions never have name in IE
+                                               name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
 
                                        if ( name ) {
                                                ret += " " + name;
@@ -1715,13 +1900,9 @@ QUnit.jsDump = (function() {
                                object: function( map, stack ) {
                                        var ret = [ ], keys, key, val, i;
                                        QUnit.jsDump.up();
-                                       if ( Object.keys ) {
-                                               keys = Object.keys( map );
-                                       } else {
-                                               keys = [];
-                                               for ( key in map ) {
-                                                       keys.push( key );
-                                               }
+                                       keys = [];
+                                       for ( key in map ) {
+                                               keys.push( key );
                                        }
                                        keys.sort();
                                        for ( i = 0; i < keys.length; i++ ) {
@@ -1733,21 +1914,34 @@ QUnit.jsDump = (function() {
                                        return join( "{", ret, "}" );
                                },
                                node: function( node ) {
-                                       var a, val,
+                                       var len, i, val,
                                                open = QUnit.jsDump.HTML ? "&lt;" : "<",
                                                close = QUnit.jsDump.HTML ? "&gt;" : ">",
                                                tag = node.nodeName.toLowerCase(),
-                                               ret = open + tag;
-
-                                       for ( a in QUnit.jsDump.DOMAttrs ) {
-                                               val = node[ QUnit.jsDump.DOMAttrs[a] ];
-                                               if ( val ) {
-                                                       ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" );
+                                               ret = open + tag,
+                                               attrs = node.attributes;
+
+                                       if ( attrs ) {
+                                               for ( i = 0, len = attrs.length; i < len; i++ ) {
+                                                       val = attrs[i].nodeValue;
+                                                       // IE6 includes all attributes in .attributes, even ones not explicitly set.
+                                                       // Those have values like undefined, null, 0, false, "" or "inherit".
+                                                       if ( val && val !== "inherit" ) {
+                                                               ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
+                                                       }
                                                }
                                        }
-                                       return ret + close + open + "/" + tag + close;
+                                       ret += close;
+
+                                       // Show content of TextNode or CDATASection
+                                       if ( node.nodeType === 3 || node.nodeType === 4 ) {
+                                               ret += node.nodeValue;
+                                       }
+
+                                       return ret + open + "/" + tag + close;
                                },
-                               functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function
+                               // function calls it internally, it's the arguments part of the function
+                               functionArgs: function( fn ) {
                                        var args,
                                                l = fn.length;
 
@@ -1757,54 +1951,34 @@ QUnit.jsDump = (function() {
 
                                        args = new Array(l);
                                        while ( l-- ) {
-                                               args[l] = String.fromCharCode(97+l);//97 is 'a'
+                                               // 97 is 'a'
+                                               args[l] = String.fromCharCode(97+l);
                                        }
                                        return " " + args.join( ", " ) + " ";
                                },
-                               key: quote, //object calls it internally, the key part of an item in a map
-                               functionCode: "[code]", //function calls it internally, it's the content of the function
-                               attribute: quote, //node calls it internally, it's an html attribute value
+                               // object calls it internally, the key part of an item in a map
+                               key: quote,
+                               // function calls it internally, it's the content of the function
+                               functionCode: "[code]",
+                               // node calls it internally, it's an html attribute value
+                               attribute: quote,
                                string: quote,
                                date: quote,
-                               regexp: literal, //regex
+                               regexp: literal,
                                number: literal,
                                "boolean": literal
                        },
-                       DOMAttrs: {
-                               //attributes to dump from nodes, name=>realName
-                               id: "id",
-                               name: "name",
-                               "class": "className"
-                       },
-                       HTML: false,//if true, entities are escaped ( <, >, \t, space and \n )
-                       indentChar: "  ",//indentation unit
-                       multiline: true //if true, items in a collection, are separated by a \n, else just a space.
+                       // if true, entities are escaped ( <, >, \t, space and \n )
+                       HTML: false,
+                       // indentation unit
+                       indentChar: "  ",
+                       // if true, items in a collection, are separated by a \n, else just a space.
+                       multiline: true
                };
 
        return jsDump;
 }());
 
-// from Sizzle.js
-function getText( elems ) {
-       var i, elem,
-               ret = "";
-
-       for ( i = 0; elems[i]; i++ ) {
-               elem = elems[i];
-
-               // Get the text from text nodes and CDATA nodes
-               if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
-                       ret += elem.nodeValue;
-
-               // Traverse everything else, except comment nodes
-               } else if ( elem.nodeType !== 8 ) {
-                       ret += getText( elem.childNodes );
-               }
-       }
-
-       return ret;
-}
-
 // from jquery.js
 function inArray( elem, array ) {
        if ( array.indexOf ) {
@@ -1835,13 +2009,14 @@ function inArray( elem, array ) {
  * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
  */
 QUnit.diff = (function() {
+       /*jshint eqeqeq:false, eqnull:true */
        function diff( o, n ) {
                var i,
                        ns = {},
                        os = {};
 
                for ( i = 0; i < n.length; i++ ) {
-                       if ( ns[ n[i] ] == null ) {
+                       if ( !hasOwn.call( ns, n[i] ) ) {
                                ns[ n[i] ] = {
                                        rows: [],
                                        o: null
@@ -1851,7 +2026,7 @@ QUnit.diff = (function() {
                }
 
                for ( i = 0; i < o.length; i++ ) {
-                       if ( os[ o[i] ] == null ) {
+                       if ( !hasOwn.call( os, o[i] ) ) {
                                os[ o[i] ] = {
                                        rows: [],
                                        n: null
@@ -1864,7 +2039,7 @@ QUnit.diff = (function() {
                        if ( !hasOwn.call( ns, i ) ) {
                                continue;
                        }
-                       if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) {
+                       if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
                                n[ ns[i].rows[0] ] = {
                                        text: n[ ns[i].rows[0] ],
                                        row: os[i].rows[0]
@@ -1970,7 +2145,7 @@ QUnit.diff = (function() {
 
 // for CommonJS enviroments, export everything
 if ( typeof exports !== "undefined" ) {
-       extend(exports, QUnit);
+       extend( exports, QUnit );
 }
 
 // get at whatever the global object is, like window in browsers
index ac579db..44382f0 100644 (file)
@@ -79,13 +79,16 @@ $.suggestions = {
         * @param {Boolean} delayed Whether or not to delay this by the currently configured amount of time
         */
        update: function ( context, delayed ) {
-               // Only fetch if the value in the textbox changed and is not empty
+               // Only fetch if the value in the textbox changed and is not empty, or if the results were hidden
                // if the textbox is empty then clear the result div, but leave other settings intouched
                function maybeFetch() {
                        if ( context.data.$textbox.val().length === 0 ) {
                                context.data.$container.hide();
                                context.data.prevText = '';
-                       } else if ( context.data.$textbox.val() !== context.data.prevText ) {
+                       } else if (
+                               context.data.$textbox.val() !== context.data.prevText ||
+                               !context.data.$container.is( ':visible' )
+                       ) {
                                if ( typeof context.config.fetch === 'function' ) {
                                        context.data.prevText = context.data.$textbox.val();
                                        context.config.fetch.call( context.data.$textbox, context.data.$textbox.val() );
@@ -113,7 +116,7 @@ $.suggestions = {
                        setTimeout( function () {
                                // Render special
                                var $special = context.data.$container.find( '.suggestions-special' );
-                               context.config.special.render.call( $special, context.data.$textbox.val() );
+                               context.config.special.render.call( $special, context.data.$textbox.val(), context );
                        }, 1 );
                }
        },
@@ -125,7 +128,7 @@ $.suggestions = {
         */
        configure: function ( context, property, value ) {
                var newCSS,
-                       $autoEllipseMe, $result, $results, $span,
+                       $autoEllipseMe, $result, $results, childrenWidth,
                        i, expWidth, matchedText, maxWidth, text;
 
                // Validate creation using fallback values
@@ -237,33 +240,34 @@ $.suggestions = {
                                                                        context.data.selectedWithMouse = true;
                                                                        $.suggestions.highlight(
                                                                                context,
-                                                                               $(this).closest( '.suggestions-results div' ),
+                                                                               $(this).closest( '.suggestions-results .suggestions-result' ),
                                                                                false
                                                                        );
                                                                } )
                                                                .appendTo( $results );
                                                        // Allow custom rendering
                                                        if ( typeof context.config.result.render === 'function' ) {
-                                                               context.config.result.render.call( $result, context.config.suggestions[i] );
+                                                               context.config.result.render.call( $result, context.config.suggestions[i], context );
                                                        } else {
                                                                // Add <span> with text
-                                                               if( context.config.highlightInput ) {
-                                                                       matchedText = context.data.prevText;
-                                                               }
                                                                $result.append( $( '<span>' )
                                                                                .css( 'whiteSpace', 'nowrap' )
                                                                                .text( text )
                                                                        );
+                                                       }
 
-                                                               // Widen results box if needed
-                                                               // New width is only calculated here, applied later
-                                                               $span = $result.children( 'span' );
-                                                               if ( $span.outerWidth() > $result.width() && $span.outerWidth() > expWidth ) {
-                                                                       // factor in any padding, margin, or border space on the parent
-                                                                       expWidth = $span.outerWidth() + ( context.data.$container.width() - $span.parent().width());
-                                                               }
-                                                               $autoEllipseMe = $autoEllipseMe.add( $result );
+                                                       if ( context.config.highlightInput ) {
+                                                               matchedText = context.data.prevText;
                                                        }
+
+                                                       // Widen results box if needed
+                                                       // New width is only calculated here, applied later
+                                                       childrenWidth = $result.children().outerWidth();
+                                                       if ( childrenWidth > $result.width() && childrenWidth > expWidth ) {
+                                                               // factor in any padding, margin, or border space on the parent
+                                                               expWidth = childrenWidth + ( context.data.$container.width() - $result.width() );
+                                                       }
+                                                       $autoEllipseMe = $autoEllipseMe.add( $result );
                                                }
                                                // Apply new width for results box, if any
                                                if ( expWidth > context.data.$container.width() ) {
@@ -305,30 +309,40 @@ $.suggestions = {
                var selected = context.data.$container.find( '.suggestions-result-current' );
                if ( !result.get || selected.get( 0 ) !== result.get( 0 ) ) {
                        if ( result === 'prev' ) {
-                               if( selected.is( '.suggestions-special' ) ) {
+                               if( selected.hasClass( 'suggestions-special' ) ) {
                                        result = context.data.$container.find( '.suggestions-result:last' );
                                } else {
                                        result = selected.prev();
+                                       if ( !( result.length && result.hasClass( 'suggestions-result' ) ) ) {
+                                               // there is something in the DOM between selected element and the wrapper, bypass it
+                                               result = selected.parents( '.suggestions-results > *' ).prev().find( '.suggestions-result' ).eq(0);
+                                       }
+
                                        if ( selected.length === 0 ) {
                                                // we are at the beginning, so lets jump to the last item
                                                if ( context.data.$container.find( '.suggestions-special' ).html() !== '' ) {
                                                        result = context.data.$container.find( '.suggestions-special' );
                                                } else {
-                                                       result = context.data.$container.find( '.suggestions-results div:last' );
+                                                       result = context.data.$container.find( '.suggestions-results .suggestions-result:last' );
                                                }
                                        }
                                }
                        } else if ( result === 'next' ) {
                                if ( selected.length === 0 ) {
                                        // No item selected, go to the first one
-                                       result = context.data.$container.find( '.suggestions-results div:first' );
+                                       result = context.data.$container.find( '.suggestions-results .suggestions-result:first' );
                                        if ( result.length === 0 && context.data.$container.find( '.suggestions-special' ).html() !== '' ) {
                                                // No suggestion exists, go to the special one directly
                                                result = context.data.$container.find( '.suggestions-special' );
                                        }
                                } else {
                                        result = selected.next();
-                                       if ( selected.is( '.suggestions-special' ) ) {
+                                       if ( !( result.length && result.hasClass( 'suggestions-result' ) ) ) {
+                                               // there is something in the DOM between selected element and the wrapper, bypass it
+                                               result = selected.parents( '.suggestions-results > *' ).next().find( '.suggestions-result' ).eq(0);
+                                       }
+
+                                       if ( selected.hasClass( 'suggestions-special' ) ) {
                                                result = $( [] );
                                        } else if (
                                                result.length === 0 &&
@@ -503,21 +517,25 @@ $.fn.suggestions = function () {
                                                // textbox loses focus. Instead, listen for a mousedown followed
                                                // by a mouseup on the same div.
                                                .mousedown( function ( e ) {
-                                                       context.data.mouseDownOn = $( e.target ).closest( '.suggestions-results div' );
+                                                       context.data.mouseDownOn = $( e.target ).closest( '.suggestions-results .suggestions-result' );
                                                } )
                                                .mouseup( function ( e ) {
-                                                       var $result = $( e.target ).closest( '.suggestions-results div' ),
+                                                       var $result = $( e.target ).closest( '.suggestions-results .suggestions-result' ),
                                                                $other = context.data.mouseDownOn;
 
                                                        context.data.mouseDownOn = $( [] );
                                                        if ( $result.get( 0 ) !== $other.get( 0 ) ) {
                                                                return;
                                                        }
-                                                       $.suggestions.highlight( context, $result, true );
-                                                       context.data.$container.hide();
-                                                       if ( typeof context.config.result.select === 'function' ) {
-                                                               context.config.result.select.call( $result, context.data.$textbox );
+                                                       // do not interfere with non-left clicks or if modifier keys are pressed (e.g. ctrl-click)
+                                                       if ( !( e.which !== 1 || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey ) ) {
+                                                               $.suggestions.highlight( context, $result, true );
+                                                               context.data.$container.hide();
+                                                               if ( typeof context.config.result.select === 'function' ) {
+                                                                       context.config.result.select.call( $result, context.data.$textbox );
+                                                               }
                                                        }
+                                                       // but still restore focus to the textbox, so that the suggestions will be hidden properly
                                                        context.data.$textbox.focus();
                                                } )
                                )
@@ -537,10 +555,14 @@ $.fn.suggestions = function () {
                                                        if ( $special.get( 0 ) !== $other.get( 0 ) ) {
                                                                return;
                                                        }
-                                                       context.data.$container.hide();
-                                                       if ( typeof context.config.special.select === 'function' ) {
-                                                               context.config.special.select.call( $special, context.data.$textbox );
+                                                       // do not interfere with non-left clicks or if modifier keys are pressed (e.g. ctrl-click)
+                                                       if ( !( e.which !== 1 || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey ) ) {
+                                                               context.data.$container.hide();
+                                                               if ( typeof context.config.special.select === 'function' ) {
+                                                                       context.config.special.select.call( $special, context.data.$textbox );
+                                                               }
                                                        }
+                                                       // but still restore focus to the textbox, so that the suggestions will be hidden properly
                                                        context.data.$textbox.focus();
                                                } )
                                                .mousemove( function ( e ) {
index 6297f9a..8320304 100644 (file)
@@ -86,7 +86,7 @@
                return false;
        }
 
-       function getElementText( node ) {
+       function getElementSortKey( node ) {
                var $node = $( node ),
                        // Use data-sort-value attribute.
                        // Use data() instead of attr() so that live value changes
                        // like charAt, toLowerCase and split are expected.
                        return String( data );
                } else {
-                       return $node.text();
+                       if ( node.tagName.toLowerCase() === 'img' ) {
+                               return $node.attr( 'alt' ) || ''; // handle undefined alt
+                       } else {
+                               return $.map( $.makeArray( node.childNodes ), function( elem ) {
+                                       // 1 is for document.ELEMENT_NODE (the constant is undefined on old browsers)
+                                       if ( elem.nodeType === 1 ) {
+                                               return getElementSortKey( elem );
+                                       } else {
+                                               return $.text( elem );
+                                       }
+                               } ).join( '' );
+                       }
                }
        }
 
        function getTextFromRowAndCellIndex( rows, rowIndex, cellIndex ) {
                if ( rows[rowIndex] && rows[rowIndex].cells[cellIndex] ) {
-                       return $.trim( getElementText( rows[rowIndex].cells[cellIndex] ) );
+                       return $.trim( getElementSortKey( rows[rowIndex].cells[cellIndex] ) );
                } else {
                        return '';
                }
                        cache.row.push( $row );
 
                        for ( var j = 0; j < totalCells; ++j ) {
-                               cols.push( parsers[j].format( getElementText( $row[0].cells[j] ), table, $row[0].cells[j] ) );
+                               cols.push( parsers[j].format( getElementSortKey( $row[0].cells[j] ), table, $row[0].cells[j] ) );
                        }
 
                        cols.push( cache.normalized.length ); // add position for rowCache
index c15fa0d..727a525 100644 (file)
@@ -1,10 +1,12 @@
 /**
- * This module enables double-click-to-edit functionality
+ * This module enables double-click-to-edit functionality.
  */
 ( function ( mw, $ ) {
-       mw.util.$content.dblclick( function ( e ) {
-               e.preventDefault();
-               // Trigger native HTMLElement click instead of opening URL (bug 43052)
-               $( '#ca-edit a' ).get( 0 ).click();
+       $( function () {
+               mw.util.$content.dblclick( function ( e ) {
+                       e.preventDefault();
+                       // Trigger native HTMLElement click instead of opening URL (bug 43052)
+                       $( '#ca-edit a' ).get( 0 ).click();
+               } );
        } );
 }( mediaWiki, jQuery ) );
index cc6f704..4de5291 100644 (file)
 /**
- * Additional mw.Api methods to assist with API calls related to categories.
+ * @class mw.Api.plugin.category
  */
 ( function ( mw, $ ) {
 
        $.extend( mw.Api.prototype, {
                /**
                 * Determine if a category exists.
-                * @param title {mw.Title}
-                * @param success {Function} callback to pass boolean of category's existence
-                * @param err {Function} optional callback to run if api error
-                * @return ajax call object
+                * @param {mw.Title} title
+                * @param {Function} [ok] Success callback (deprecated)
+                * @param {Function} [err] Error callback (deprecated)
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {boolean} return.done.isCategory Whether the category exists.
                 */
-               isCategory: function ( title, success, err ) {
-                       var params, ok;
-                       params = {
-                               prop: 'categoryinfo',
-                               titles: title.toString()
-                       };
-                       ok = function ( data ) {
-                               var exists = false;
-                               if ( data.query && data.query.pages ) {
-                                       $.each( data.query.pages, function ( id, page ) {
-                                               if ( page.categoryinfo ) {
-                                                       exists = true;
-                                               }
-                                       } );
-                               }
-                               success( exists );
-                       };
+               isCategory: function ( title, ok, err ) {
+                       var d = $.Deferred();
+                       // Backwards compatibility (< MW 1.20)
+                       d.done( ok );
+                       d.fail( err );
 
-                       return this.get( params, { ok: ok, err: err } );
+                       this.get( {
+                                       prop: 'categoryinfo',
+                                       titles: title.toString()
+                               } )
+                               .done( function ( data ) {
+                                       var exists = false;
+                                       if ( data.query && data.query.pages ) {
+                                               $.each( data.query.pages, function ( id, page ) {
+                                                       if ( page.categoryinfo ) {
+                                                               exists = true;
+                                                       }
+                                               } );
+                                       }
+                                       d.resolve( exists );
+                               })
+                               .fail( d.reject );
+
+                       return d.promise();
                },
 
                /**
                 * Get a list of categories that match a certain prefix.
                 *   e.g. given "Foo", return "Food", "Foolish people", "Foosball tables" ...
-                * @param prefix {String} prefix to match
-                * @param success {Function} callback to pass matched categories to
-                * @param err {Function} optional callback to run if api error
-                * @return {jqXHR}
+                * @param {string} prefix Prefix to match.
+                * @param {Function} [ok] Success callback (deprecated)
+                * @param {Function} [err] Error callback (deprecated)
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {String[]} return.done.categories Matched categories
                 */
-               getCategoriesByPrefix: function ( prefix, success, err ) {
+               getCategoriesByPrefix: function ( prefix, ok, err ) {
+                       var d = $.Deferred();
+                       // Backwards compatibility (< MW 1.20)
+                       d.done( ok );
+                       d.fail( err );
+
                        // Fetch with allpages to only get categories that have a corresponding description page.
-                       var params, ok;
-                       params = {
-                               'list': 'allpages',
-                               'apprefix': prefix,
-                               'apnamespace': mw.config.get('wgNamespaceIds').category
-                       };
-                       ok = function ( data ) {
-                               var texts = [];
-                               if ( data.query && data.query.allpages ) {
-                                       $.each( data.query.allpages, function ( i, category ) {
-                                               texts.push( new mw.Title( category.title ).getNameText() );
-                                       } );
-                               }
-                               success( texts );
-                       };
+                       this.get( {
+                                       list: 'allpages',
+                                       apprefix: prefix,
+                                       apnamespace: mw.config.get('wgNamespaceIds').category
+                               } )
+                               .done( function ( data ) {
+                                       var texts = [];
+                                       if ( data.query && data.query.allpages ) {
+                                               $.each( data.query.allpages, function ( i, category ) {
+                                                       texts.push( new mw.Title( category.title ).getNameText() );
+                                               } );
+                                       }
+                                       d.resolve( texts );
+                               })
+                               .fail( d.reject );
 
-                       return this.get( params, { ok: ok, err: err } );
+                       return d.promise();
                },
 
 
                /**
                 * Get the categories that a particular page on the wiki belongs to
-                * @param title {mw.Title}
-                * @param success {Function} callback to pass categories to (or false, if title not found)
-                * @param err {Function} optional callback to run if api error
-                * @param async {Boolean} optional asynchronousness (default = true = async)
-                * @return {jqXHR}
+                * @param {mw.Title} title
+                * @param {Function} [ok] Success callback (deprecated)
+                * @param {Function} [err] Error callback (deprecated)
+                * @param {boolean} [async=true] Asynchronousness
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {boolean|mw.Title[]} return.done.categories List of category titles or false
+                *  if title was not found.
                 */
-               getCategories: function ( title, success, err, async ) {
-                       var params, ok;
-                       params = {
-                               prop: 'categories',
-                               titles: title.toString()
-                       };
-                       if ( async === undefined ) {
-                               async = true;
-                       }
-                       ok = function ( data ) {
-                               var ret = false;
-                               if ( data.query && data.query.pages ) {
-                                       $.each( data.query.pages, function ( id, page ) {
-                                               if ( page.categories ) {
-                                                       if ( typeof ret !== 'object' ) {
-                                                               ret = [];
+               getCategories: function ( title, ok, err, async ) {
+                       var d = $.Deferred();
+                       // Backwards compatibility (< MW 1.20)
+                       d.done( ok );
+                       d.fail( err );
+
+                       this.get( {
+                                       prop: 'categories',
+                                       titles: title.toString()
+                               }, {
+                                       async: async === undefined ? true : async
+                               } )
+                               .done( function ( data ) {
+                                       var ret = false;
+                                       if ( data.query && data.query.pages ) {
+                                               $.each( data.query.pages, function ( id, page ) {
+                                                       if ( page.categories ) {
+                                                               if ( typeof ret !== 'object' ) {
+                                                                       ret = [];
+                                                               }
+                                                               $.each( page.categories, function ( i, cat ) {
+                                                                       ret.push( new mw.Title( cat.title ) );
+                                                               } );
                                                        }
-                                                       $.each( page.categories, function ( i, cat ) {
-                                                               ret.push( new mw.Title( cat.title ) );
-                                                       } );
-                                               }
-                                       } );
-                               }
-                               success( ret );
-                       };
+                                               } );
+                                       }
+                                       d.resolve( ret );
+                               })
+                               .fail( d.reject );
 
-                       return this.get( params, { ok: ok, err: err, async: async } );
+                       return d.promise();
                }
 
        } );
 
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.category
+        */
+
 }( mediaWiki, jQuery ) );
index 49af937..3c775ad 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Additional mw.Api methods to assist with API calls related to editing wiki pages.
+ * @class mw.Api.plugin.edit
  */
 ( function ( mw, $ ) {
 
                 * If we have a cached token try using that, and if it fails, blank out the
                 * cached token and start over.
                 *
-                * @param params {Object} API parameters
-                * @param ok {Function} callback for success
-                * @param err {Function} [optional] error callback
-                * @return {jqXHR}
+                * @param {Object} params API parameters
+                * @param {Function} [ok] Success callback (deprecated)
+                * @param {Function} [err] Error callback (deprecated)
+                * @return {jQuery.Promise} See #post
                 */
                postWithEditToken: function ( params, ok, err ) {
                        var useTokenToPost, getTokenIfBad,
                },
 
                /**
-                * Api helper to grab an edit token
+                * Api helper to grab an edit token.
                 *
-                * token callback has signature ( String token )
-                * error callback has signature ( String code, Object results, XmlHttpRequest xhr, Exception exception )
-                * Note that xhr and exception are only available for 'http_*' errors
-                *  code may be any http_* error code (see mw.Api), or 'token_missing'
-                *
-                * @param tokenCallback {Function} received token callback
-                * @param err {Function} error callback
-                * @return {jqXHR}
+                * @param {Function} [ok] Success callback
+                * @param {Function} [err] Error callback
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {string} return.done.token Received token.
                 */
-               getEditToken: function ( tokenCallback, err ) {
-                       var parameters = {
+               getEditToken: function ( ok, err ) {
+                       var d = $.Deferred();
+                       // Backwards compatibility (< MW 1.20)
+                       d.done( ok );
+                       d.fail( err );
+
+                       this.get( {
                                        action: 'tokens',
                                        type: 'edit'
-                               },
-                               ok = function ( data ) {
+                               }, {
+                                       // Due to the API assuming we're logged out if we pass the callback-parameter,
+                                       // we have to disable jQuery's callback system, and instead parse JSON string,
+                                       // by setting 'jsonp' to false.
+                                       // TODO: This concern seems genuine but no other module has it. Is it still
+                                       // needed and/or should we pass this by default?
+                                       jsonp: false
+                               } )
+                               .done( function ( data ) {
                                        var token;
                                        // If token type is not available for this user,
                                        // key 'edittoken' is missing or can contain Boolean false
                                        if ( data.tokens && data.tokens.edittoken ) {
                                                token = data.tokens.edittoken;
                                                cachedToken = token;
-                                               tokenCallback( token );
+                                               d.resolve( token );
                                        } else {
-                                               err( 'token-missing', data );
+                                               d.reject( 'token-missing', data );
                                        }
-                               },
-                               ajaxOptions = {
-                                       ok: ok,
-                                       err: err,
-                                       // Due to the API assuming we're logged out if we pass the callback-parameter,
-                                       // we have to disable jQuery's callback system, and instead parse JSON string,
-                                       // by setting 'jsonp' to false.
-                                       jsonp: false
-                               };
+                               })
+                               .fail( d.reject );
 
-                       return this.get( parameters, ajaxOptions );
+                       return d.promise();
                },
 
                /**
                 * Create a new section of the page.
-                * @param title {mw.Title|String} target page
-                * @param header {String}
-                * @param message {String} wikitext message
-                * @param ok {Function} success handler
-                * @param err {Function} error handler
-                * @return {jqXHR}
+                * @see #postWithEditToken
+                * @param {mw.Title|String} title Target page
+                * @param {string} header
+                * @param {string} message wikitext message
+                * @param {Function} [ok] Success handler
+                * @param {Function} [err] Error handler
+                * @return {jQuery.Promise}
                 */
                newSection: function ( title, header, message, ok, err ) {
-                       var params = {
+                       return this.postWithEditToken( {
                                action: 'edit',
                                section: 'new',
                                format: 'json',
                                title: title.toString(),
                                summary: header,
                                text: message
-                       };
-                       return this.postWithEditToken( params, ok, err );
+                       }, ok, err );
                }
 
         } );
 
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.edit
+        */
+
 }( mediaWiki, jQuery ) );
index a184e3c..cf7443f 100644 (file)
@@ -1,15 +1,9 @@
-/**
- * mw.Api objects represent the API of a particular MediaWiki server.
- */
 ( function ( mw, $ ) {
 
-       /**
-        * @var defaultOptions {Object}
-        * We allow people to omit these default parameters from API requests
-        * there is very customizable error handling here, on a per-call basis
-        * wondering, would it be simpler to make it easy to clone the api object,
-        * change error handling, and use that instead?
-        */
+       // We allow people to omit these default parameters from API requests
+       // there is very customizable error handling here, on a per-call basis
+       // wondering, would it be simpler to make it easy to clone the api object,
+       // change error handling, and use that instead?
        var defaultOptions = {
 
                        // Query parameters for API requests
 
        /**
         * Constructor to create an object to interact with the API of a particular MediaWiki server.
+        * mw.Api objects represent the API of a particular MediaWiki server.
+        *
+        * TODO: Share API objects with exact same config.
         *
-        * @todo Share API objects with exact same config.
-        * @example
-        * <code>
-        * var api = new mw.Api();
-        * api.get( {
-        *     action: 'query',
-        *     meta: 'userinfo'
-        * }, {
-        *     ok: function () { console.log( arguments ); }
-        * } );
-        * </code>
+        *     var api = new mw.Api();
+        *     api.get( {
+        *         action: 'query',
+        *         meta: 'userinfo'
+        *     } ).done ( function ( data ) {
+        *         console.log( data );
+        *     } );
+        *
+        * @class
         *
         * @constructor
-        * @param options {Object} See defaultOptions documentation above. Ajax options can also be
-        * overridden for each individual request to jQuery.ajax() later on.
+        * @param {Object} options See defaultOptions documentation above. Ajax options can also be
+        *  overridden for each individual request to {@link jQuery#ajax} later on.
         */
        mw.Api = function ( options ) {
 
                /**
                 * Normalize the ajax options for compatibility and/or convenience methods.
                 *
-                * @param {undefined|Object|Function} An object contaning one or more of options.ajax,
-                * or just a success function (options.ajax.ok).
+                * @param {Object} [arg] An object contaning one or more of options.ajax.
                 * @return {Object} Normalized ajax options.
                 */
                normalizeAjaxOptions: function ( arg ) {
                        // Arg argument is usually empty
-                       // (before MW 1.20 it was often used to pass ok/err callbacks)
+                       // (before MW 1.20 it was used to pass ok callbacks)
                        var opts = arg || {};
                        // Options can also be a success callback handler
                        if ( typeof arg === 'function' ) {
@@ -87,8 +81,8 @@
                /**
                 * Perform API get request
                 *
-                * @param {Object} request parameters
-                * @param {Object|Function} [optional] ajax options
+                * @param {Object} parameters
+                * @param {Object|Function} [ajaxOptions]
                 * @return {jQuery.Promise}
                 */
                get: function ( parameters, ajaxOptions ) {
 
                /**
                 * Perform API post request
-                * @todo Post actions for nonlocal will need proxy
                 *
-                * @param {Object} request parameters
-                * @param {Object|Function} [optional] ajax options
+                * TODO: Post actions for non-local hostnames will need proxy.
+                *
+                * @param {Object} parameters
+                * @param {Object|Function} [ajaxOptions]
                 * @return {jQuery.Promise}
                 */
                post: function ( parameters, ajaxOptions ) {
                /**
                 * Perform the API call.
                 *
-                * @param {Object} request parameters
-                * @param {Object} ajax options
-                * @return {jQuery.Promise}
-                * - done: API response data as first argument
-                * - fail: errorcode as first arg, details (string or object) as second arg.
+                * @param {Object} parameters
+                * @param {Object} [ajaxOptions]
+                * @return {jQuery.Promise} Done: API response data. Fail: Error code
                 */
                ajax: function ( parameters, ajaxOptions ) {
                        var token,
        };
 
        /**
-        * @var {Array} List of errors we might receive from the API.
+        * @static
+        * @property {Array}
+        * List of errors we might receive from the API.
         * For now, this just documents our expectation that there should be similar messages
         * available.
         */
        ];
 
        /**
-        * @var {Array} List of warnings we might receive from the API.
+        * @static
+        * @property {Array}
+        * List of warnings we might receive from the API.
         * For now, this just documents our expectation that there should be similar messages
         * available.
         */
index e8d1b3e..ea0388c 100644 (file)
@@ -1,42 +1,43 @@
 /**
- * mw.Api methods for parsing wikitext.
+ * @class mw.Api.plugin.parse
  */
 ( function ( mw, $ ) {
 
        $.extend( mw.Api.prototype, {
                /**
-                * Convinience method for 'action=parse'. Parses wikitext into HTML.
+                * Convinience method for 'action=parse'.
                 *
-                * @param wikiText {String}
-                * @param ok {Function} [optional] deprecated (success callback)
-                * @param err {Function} [optional] deprecated (error callback)
+                * @param {string} wikitext
+                * @param {Function} [ok] Success callback (deprecated)
+                * @param {Function} [err] Error callback (deprecated)
                 * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {string} return.done.data Parsed HTML of `wikitext`.
                 */
-               parse: function ( wikiText, ok, err ) {
-                       var apiDeferred = $.Deferred();
-
+               parse: function ( wikitext, ok, err ) {
+                       var d = $.Deferred();
                        // Backwards compatibility (< MW 1.20)
-                       if ( ok ) {
-                               apiDeferred.done( ok );
-                       }
-                       if ( err ) {
-                               apiDeferred.fail( err );
-                       }
+                       d.done( ok );
+                       d.fail( err );
 
                        this.get( {
                                        action: 'parse',
-                                       text: wikiText
+                                       text: wikitext
                                } )
                                .done( function ( data ) {
                                        if ( data.parse && data.parse.text && data.parse.text['*'] ) {
-                                               apiDeferred.resolve( data.parse.text['*'] );
+                                               d.resolve( data.parse.text['*'] );
                                        }
                                } )
-                               .fail( apiDeferred.reject );
+                               .fail( d.reject );
 
-                       // Return the promise
-                       return apiDeferred.promise();
+                       return d.promise();
                }
        } );
 
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.parse
+        */
+
 }( mediaWiki, jQuery ) );
index 1f7e275..8c46717 100644 (file)
@@ -1,33 +1,39 @@
 /**
- * Additional mw.Api methods to assist with API calls to the API module of the TitleBlacklist extension.
+ * @class mw.Api.plugin.titleblacklist
  */
-
 ( function ( mw, $ ) {
 
        $.extend( mw.Api.prototype, {
                /**
-                * Convinience method for 'action=titleblacklist'.
+                * Convinience method for `action=titleblacklist`.
                 * Note: This action is not provided by MediaWiki core, but as part of the TitleBlacklist extension.
                 *
-                * @param title {mw.Title}
-                * @param success {Function} Called on successfull request. First argument is false if title wasn't blacklisted,
-                *  object with 'reason', 'line' and 'message' properties if title was blacklisted.
-                * @param err {Function} optional callback to run if api error
-                * @return {jqXHR}
+                * @param {mw.Title|string} title
+                * @param {Function} [ok] Success callback (deprecated)
+                * @param {Function} [err] Error callback (deprecated)
+                * @return {jQuery.Promise}
+                * @return {Function} return.done
+                * @return {Object|boolean} return.done.result False if title wasn't blacklisted, an object with 'reason', 'line'
+                *  and 'message' properties if title was blacklisted.
                 */
-               isBlacklisted: function ( title, success, err ) {
-                       var     params = {
+               isBlacklisted: function ( title, ok, err ) {
+                       var d = $.Deferred();
+                       // Backwards compatibility (< MW 1.20)
+                       d.done( ok );
+                       d.fail( err );
+
+                       this.get( {
                                        action: 'titleblacklist',
                                        tbaction: 'create',
                                        tbtitle: title.toString()
-                               },
-                               ok = function ( data ) {
+                               } )
+                               .done( function ( data ) {
                                        var result;
 
                                        // this fails open (if nothing valid is returned by the api, allows the title)
                                        // also fails open when the API is not present, which will be most of the time
                                        // as this API module is part of the TitleBlacklist extension.
-                                       if ( data.titleblacklist && data.titleblacklist.result && data.titleblacklist.result === 'blacklisted') {
+                                       if ( data.titleblacklist && data.titleblacklist.result && data.titleblacklist.result === 'blacklisted' ) {
                                                if ( data.titleblacklist.reason ) {
                                                        result = {
                                                                reason: data.titleblacklist.reason,
                                                                message: data.titleblacklist.message
                                                        };
                                                } else {
-                                                       mw.log('mw.Api.titleblacklist::isBlacklisted> no reason data for blacklisted title', 'debug');
-                                                       result = { reason: 'Blacklisted, but no reason supplied', line: 'Unknown', message: null };
+                                                       mw.log( 'mw.Api.titleblacklist::isBlacklisted> no reason data for blacklisted title', 'debug' );
+                                                       result = {
+                                                               reason: 'Blacklisted, but no reason supplied',
+                                                               line: 'Unknown',
+                                                               message: null
+                                                       };
                                                }
-                                               success( result );
+                                               d.resolve( result );
                                        } else {
-                                               success ( false );
+                                               d.resolve( false );
                                        }
-                               };
+                               } )
+                               .fail( d.reject );
 
-                       return this.get( params, { ok: ok, err: err } );
+                       return d.promise();
                }
 
        } );
 
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.titleblacklist
+        */
+
 }( mediaWiki, jQuery ) );
index 6cbccbf..c86a90a 100644 (file)
@@ -1,56 +1,72 @@
 /**
- * Additional mw.Api methods to assist with (un)watching wiki pages.
+ * @class mw.Api.plugin.watch
  * @since 1.19
  */
 ( function ( mw, $ ) {
 
        /**
-        * @context {mw.Api}
+        * @private
+        * @context mw.Api
+        *
+        * @param {String|mw.Title} page Full page name or instance of mw.Title
+        * @param {Function} [ok] Success callback (deprecated)
+        * @param {Function} [err] Error callback (deprecated)
+        * @return {jQuery.Promise}
+        * @return {Function} return.done
+        * @return {Object} return.done.watch
+        * @return {string} return.done.watch.title Full pagename
+        * @return {boolean} return.done.watch.watched
+        * @return {string} return.done.watch.message Parsed HTML of the confirmational interface message
         */
-       function doWatchInternal( page, success, err, addParams ) {
-               var params = {
+       function doWatchInternal( page, ok, err, addParams ) {
+               var params, d = $.Deferred();
+               // Backwards compatibility (< MW 1.20)
+               d.done( ok );
+               d.fail( err );
+
+               params = {
                        action: 'watch',
                        title: String( page ),
                        token: mw.user.tokens.get( 'watchToken' ),
                        uselang: mw.config.get( 'wgUserLanguage' )
                };
-               function ok( data ) {
-                       success( data.watch );
-               }
+
                if ( addParams ) {
                        $.extend( params, addParams );
                }
-               return this.post( params, { ok: ok, err: err } );
+
+               this.post( params )
+                       .done( function ( data ) {
+                               d.resolve( data.watch );
+                       } )
+                       .fail( d.reject );
+
+               return d.promise();
        }
 
        $.extend( mw.Api.prototype, {
                /**
-                * Convenience method for 'action=watch'.
+                * Convenience method for `action=watch`.
                 *
-                * @param page {String|mw.Title} Full page name or instance of mw.Title
-                * @param success {Function} Callback to which the watch object will be passed.
-                * Watch object contains properties 'title' (full pagename), 'watched' (boolean) and
-                * 'message' (parsed HTML of the 'addedwatchtext' message).
-                * @param err {Function} Error callback (optional)
-                * @return {jqXHR}
+                * @inheritdoc #doWatchInternal
                 */
-               watch: function ( page, success, err ) {
-                       return doWatchInternal.call( this, page, success, err );
+               watch: function ( page, ok, err ) {
+                       return doWatchInternal.call( this, page, ok, err );
                },
                /**
-                * Convenience method for 'action=watch&unwatch=1'.
+                * Convenience method for `action=watch&unwatch=1`.
                 *
-                * @param page {String|mw.Title} Full page name or instance of mw.Title
-                * @param success {Function} Callback to which the watch object will be passed.
-                * Watch object contains properties 'title' (full pagename), 'watched' (boolean) and
-                * 'message' (parsed HTML of the 'removedwatchtext' message).
-                * @param err {Function} Error callback (optional)
-                * @return {jqXHR}
+                * @inheritdoc #doWatchInternal
                 */
-               unwatch: function ( page, success, err ) {
-                       return doWatchInternal.call( this, page, success, err, { unwatch: 1 } );
+               unwatch: function ( page, ok, err ) {
+                       return doWatchInternal.call( this, page, ok, err, { unwatch: 1 } );
                }
 
        } );
 
+       /**
+        * @class mw.Api
+        * @mixins mw.Api.plugin.watch
+        */
+
 }( mediaWiki, jQuery ) );
index b27dea4..1bc0632 100644 (file)
@@ -2,16 +2,20 @@
  * 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 ) {
-       /*jshint noempty:false, onecase:true */
+       'use strict';
+
        var grammarForms = mediaWiki.language.getData( 'ru', 'grammarForms' );
        if ( grammarForms && grammarForms[form] ) {
                return grammarForms[form][word];
        }
        switch ( form ) {
                case 'genitive': // родительный падеж
-                       if ( (  word.substr( word.length - 4 ) === 'вики' ) || (  word.substr( word.length - 4 ) === 'Вики' ) ) {
-                       } else if ( word.substr( word.length - 1 ) === 'ь' ) {
+                       if ( word.substr( word.length - 1 ) === 'ь' ) {
                                word = word.substr(0, word.length - 1 ) + 'я';
                        } else if ( word.substr( word.length - 2 ) === 'ия' ) {
                                word = word.substr(0, word.length - 2 ) + 'ии';
@@ -21,10 +25,29 @@ mediaWiki.language.convertGrammar = function ( word, form ) {
                                word = word.substr(0, word.length - 2 ) + 'тей';
                        } else if ( word.substr( word.length - 2 ) === 'ды' ) {
                                word = word.substr(0, word.length - 2 ) + 'дов';
+                       } else if ( word.substr( word.length - 3 ) === 'ные' ) {
+                               word = word.substr(0, word.length - 3 ) + 'ных';
                        } else if ( word.substr( word.length - 3 ) === 'ник' ) {
                                word = word.substr(0, word.length - 3 ) + 'ника';
                        }
                        break;
+               case 'prepositional': // предложный падеж
+                       if ( word.substr( word.length - 1 ) === 'ь' ) {
+                               word = word.substr(0, word.length - 1 ) + 'е';
+                       } else if ( word.substr( word.length - 2 ) === 'ия' ) {
+                               word = word.substr(0, word.length - 2 ) + 'ии';
+                       } else if ( word.substr( word.length - 2 ) === 'ка' ) {
+                               word = word.substr(0, word.length - 2 ) + 'ке';
+                       } else if ( word.substr( word.length - 2 )  === 'ти' ) {
+                               word = word.substr(0, word.length - 2 ) + 'тях';
+                       } else if ( word.substr( word.length - 2 ) === 'ды' ) {
+                               word = word.substr(0, word.length - 2 ) + 'дах';
+                       } else if ( word.substr( word.length - 3 ) === 'ные' ) {
+                               word = word.substr(0, word.length - 3 ) + 'ных';
+                       } else if ( word.substr( word.length - 3 ) === 'ник' ) {
+                               word = word.substr(0, word.length - 3 ) + 'нике';
+                       }
+                       break;
        }
        return word;
 };
index 46384a8..6eaec6a 100644 (file)
@@ -180,4 +180,20 @@ jQuery( document ).ready( function ( $ ) {
                $tzTextbox.blur( updateTimezoneSelection );
                updateTimezoneSelection();
        }
+
+       // Preserve the tab after saving the preferences
+       // Not using cookies, because their deletion results are inconsistent.
+       // Not using jStorage due to its enormous size (for this feature)
+       if ( window.sessionStorage ) {
+               if ( sessionStorage.getItem( 'mediawikiPreferencesTab' ) !== null ) {
+                       switchPrefTab( sessionStorage.getItem( 'mediawikiPreferencesTab' ), 'noHash' );
+               }
+               // Deleting the key, the tab states should be reset until we press Save
+               sessionStorage.removeItem( 'mediawikiPreferencesTab' );
+
+               $( '#mw-prefs-form' ).submit( function () {
+                       var storageData = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
+                       sessionStorage.setItem( 'mediawikiPreferencesTab', storageData );
+               } );
+       }
 } );
diff --git a/resources/mediawiki.special/mediawiki.special.userLogin.signup.js b/resources/mediawiki.special/mediawiki.special.userLogin.signup.js
new file mode 100644 (file)
index 0000000..bba4260
--- /dev/null
@@ -0,0 +1,10 @@
+/**
+ * JavaScript for Special:UserLogin/signup
+ */
+jQuery( document ).ready( function ( $ ) {
+       $( '#wpCreateaccountMail' )
+               .on( 'change', function() {
+                       $( '.mw-row-password' ).toggle( !$( this ).attr( 'checked' ) );
+               } )
+               .trigger( 'change' );
+} );
index dad6021..b86a14b 100644 (file)
@@ -1,6 +1,4 @@
-/**
- * mediaWiki.Title
- *
+/*!
  * @author Neil Kandalgaonkar, 2010
  * @author Timo Tijhof, 2011
  * @since 1.18
        /* Local space */
 
        /**
-        * Title
-        * @constructor
+        * @class mw.Title
         *
-        * @param title {String} Title of the page. If no second argument given,
+        * @constructor
+        * @param {string} title Title of the page. If no second argument given,
         * this will be searched for a namespace.
-        * @param namespace {Number} (optional) Namespace id. If given, title will be taken as-is.
-        * @return {Title} this
+        * @param {number} [namespace] Namespace id. If given, title will be taken as-is.
         */
        function Title( title, namespace ) {
                this.ns = 0; // integer namespace id
        }
 
 var
-       /**
-        * Public methods (defined later)
-        */
+       /* Public methods (defined later) */
        fn,
 
        /**
         * Strip some illegal chars: control chars, colon, less than, greater than,
         * brackets, braces, pipe, whitespace and normal spaces. This still leaves some insanity
         * intact, like unicode bidi chars, but it's a good start..
-        * @param s {String}
-        * @return {String}
+        * @ignore
+        * @param {string} s
+        * @return {string}
         */
        clean = function ( s ) {
                if ( s !== undefined ) {
@@ -55,8 +51,9 @@ var
 
        /**
         * Convert db-key to readable text.
-        * @param s {String}
-        * @return {String}
+        * @ignore
+        * @param {string} s
+        * @return {string}
         */
        text = function ( s ) {
                if ( s !== null && s !== undefined ) {
@@ -68,13 +65,15 @@ var
 
        /**
         * Sanitize name.
+        * @ignore
         */
        fixName = function ( s ) {
                return clean( $.trim( s ) );
        },
 
        /**
-        * Sanitize name.
+        * Sanitize extension.
+        * @ignore
         */
        fixExt = function ( s ) {
                return clean( s );
@@ -82,6 +81,7 @@ var
 
        /**
         * Sanitize namespace id.
+        * @ignore
         * @param id {Number} Namespace id.
         * @return {Number|Boolean} The id as-is or boolean false if invalid.
         */
@@ -99,8 +99,8 @@ var
 
        /**
         * Get namespace id from namespace name by any known namespace/id pair (localized, canonical or alias).
-        *
-        * @example On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or even 'Bild'.
+        * Example: On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or even 'Bild'.
+        * @ignore
         * @param ns {String} Namespace name (case insensitive, leading/trailing space ignored).
         * @return {Number|Boolean} Namespace id or boolean false if unrecognized.
         */
@@ -125,8 +125,9 @@ var
        /**
         * Helper to extract namespace, name and extension from a string.
         *
-        * @param title {mw.Title}
-        * @param raw {String}
+        * @ignore
+        * @param {mw.Title} title
+        * @param {string} raw
         * @return {mw.Title}
         */
        setAll = function ( title, s ) {
@@ -153,8 +154,9 @@ var
        /**
         * Helper to extract name and extension from a string.
         *
-        * @param title {mw.Title}
-        * @param raw {String}
+        * @ignore
+        * @param {mw.Title} title
+        * @param {string} raw
         * @return {mw.Title}
         */
        setNameAndExtension = function ( title, raw ) {
@@ -179,8 +181,9 @@ var
 
        /**
         * Whether this title exists on the wiki.
-        * @param title {mixed} prefixed db-key name (string) or instance of Title
-        * @return {mixed} Boolean true/false if the information is available. Otherwise null.
+        * @static
+        * @param {Mixed} title prefixed db-key name (string) or instance of Title
+        * @return {Mixed} Boolean true/false if the information is available. Otherwise null.
         */
        Title.exists = function ( title ) {
                var type = $.type( title ), obj = Title.exist.pages, match;
@@ -198,20 +201,27 @@ var
        };
 
        /**
-        * @var Title.exist {Object}
+        * @static
+        * @property
         */
        Title.exist = {
                /**
-                * @var Title.exist.pages {Object} Keyed by PrefixedDb title.
+                * @static
+                * @property {Object} exist.pages Keyed by PrefixedDb title.
                 * Boolean true value indicates page does exist.
                 */
                pages: {},
                /**
-                * @example Declare existing titles: Title.exist.set(['User:John_Doe', ...]);
-                * @example Declare titles nonexistent: Title.exist.set(['File:Foo_bar.jpg', ...], false);
-                * @param titles {String|Array} Title(s) in strict prefixedDb title form.
-                * @param state {Boolean} (optional) State of the given titles. Defaults to true.
-                * @return {Boolean}
+                * Example to declare existing titles:
+                *     Title.exist.set(['User:John_Doe', ...]);
+                * Eample to declare titles nonexistent:
+                *     Title.exist.set(['File:Foo_bar.jpg', ...], false);
+                *
+                * @static
+                * @property exist.set
+                * @param {string|Array} titles Title(s) in strict prefixedDb title form.
+                * @param {boolean} [state] State of the given titles. Defaults to true.
+                * @return {boolean}
                 */
                set: function ( titles, state ) {
                        titles = $.isArray( titles ) ? titles : [titles];
@@ -231,7 +241,7 @@ var
 
                /**
                 * Get the namespace number.
-                * @return {Number}
+                * @return {number}
                 */
                getNamespaceId: function (){
                        return this.ns;
@@ -240,7 +250,7 @@ var
                /**
                 * Get the namespace prefix (in the content-language).
                 * In NS_MAIN this is '', otherwise namespace name plus ':'
-                * @return {String}
+                * @return {string}
                 */
                getNamespacePrefix: function (){
                        return mw.config.get( 'wgFormattedNamespaces' )[this.ns].replace( / /g, '_' ) + (this.ns === 0 ? '' : ':');
@@ -248,7 +258,7 @@ var
 
                /**
                 * The name, like "Foo_bar"
-                * @return {String}
+                * @return {string}
                 */
                getName: function () {
                        if ( $.inArray( this.ns, mw.config.get( 'wgCaseSensitiveNamespaces' ) ) !== -1 ) {
@@ -260,7 +270,7 @@ var
 
                /**
                 * The name, like "Foo bar"
-                * @return {String}
+                * @return {string}
                 */
                getNameText: function () {
                        return text( this.getName() );
@@ -269,6 +279,7 @@ var
                /**
                 * Get full name in prefixed DB form, like File:Foo_bar.jpg,
                 * most useful for API calls, anything that must identify the "title".
+                * @return {string}
                 */
                getPrefixedDb: function () {
                        return this.getNamespacePrefix() + this.getMain();
@@ -276,7 +287,7 @@ var
 
                /**
                 * Get full name in text form, like "File:Foo bar.jpg".
-                * @return {String}
+                * @return {string}
                 */
                getPrefixedText: function () {
                        return text( this.getPrefixedDb() );
@@ -284,7 +295,7 @@ var
 
                /**
                 * The main title (without namespace), like "Foo_bar.jpg"
-                * @return {String}
+                * @return {string}
                 */
                getMain: function () {
                        return this.getName() + this.getDotExtension();
@@ -292,7 +303,7 @@ var
 
                /**
                 * The "text" form, like "Foo bar.jpg"
-                * @return {String}
+                * @return {string}
                 */
                getMainText: function () {
                        return text( this.getMain() );
@@ -300,7 +311,7 @@ var
 
                /**
                 * Get the extension (returns null if there was none)
-                * @return {String|null} extension
+                * @return {string|null}
                 */
                getExtension: function () {
                        return this.ext;
@@ -308,7 +319,7 @@ var
 
                /**
                 * Convenience method: return string like ".jpg", or "" if no extension
-                * @return {String}
+                * @return {string}
                 */
                getDotExtension: function () {
                        return this.ext === null ? '' : '.' + this.ext;
@@ -316,7 +327,8 @@ var
 
                /**
                 * Return the URL to this title
-                * @return {String}
+                * @see mw.util#wikiGetlink
+                * @return {string}
                 */
                getUrl: function () {
                        return mw.util.wikiGetlink( this.toString() );
@@ -324,7 +336,8 @@ var
 
                /**
                 * Whether this title exists on the wiki.
-                * @return {mixed} Boolean true/false if the information is available. Otherwise null.
+                * @see #static-method-exists
+                * @return {boolean|null} If the information is available. Otherwise null.
                 */
                exists: function () {
                        return Title.exists( this );
index 934e906..76f0259 100644 (file)
                                'SITENAME' : mw.config.get( 'wgSiteName' )
                        },
                        messages : mw.messages,
-                       language : mw.language
+                       language : mw.language,
+
+                       // Same meaning as in mediawiki.js.
+                       //
+                       // Only 'text', 'parse', and 'escaped' are supported, and the
+                       // actual escaping for 'escaped' is done by other code (generally
+                       // through jqueryMsg).
+                       //
+                       // However, note that this default only
+                       // applies to direct calls to jqueryMsg. The default for mediawiki.js itself
+                       // is 'text', including when it uses jqueryMsg.
+                       format: 'parse'
+
                };
 
        /**
         * @return {Function} function suitable for assigning to window.gM
         */
        mw.jqueryMsg.getMessageFunction = function ( options ) {
-               var failableParserFn = getFailableParserFn( options );
+               var failableParserFn = getFailableParserFn( options ),
+                       format;
+
+               if ( options && options.format !== undefined ) {
+                       format = options.format;
+               } else {
+                       format = parserDefaults.format;
+               }
+
                /**
                 * N.B. replacements are variadic arguments or an array in second parameter. In other words:
                 *    somefunction(a, b, c, d)
                 * @return {string} Rendered HTML.
                 */
                return function () {
-                       return failableParserFn( arguments ).html();
+                       var failableResult = failableParserFn( arguments );
+                       if ( format === 'text' || format === 'escaped' ) {
+                               return failableResult.text();
+                       } else {
+                               return failableResult.html();
+                       }
                };
        };
 
         */
        mw.jqueryMsg.parser = function ( options ) {
                this.settings = $.extend( {}, parserDefaults, options );
+               this.settings.onlyCurlyBraceTransform = ( this.settings.format === 'text' || this.settings.format === 'escaped' );
+
                this.emitter = new mw.jqueryMsg.htmlEmitter( this.settings.language, this.settings.magic );
        };
 
        mw.jqueryMsg.parser.prototype = {
-               // cache, map of mediaWiki message key to the AST of the message. In most cases, the message is a string so this is identical.
-               // (This is why we would like to move this functionality server-side).
+               /**
+                * Cache mapping MediaWiki message keys and the value onlyCurlyBraceTransform, to the AST of the message.
+                *
+                * In most cases, the message is a string so this is identical.
+                * (This is why we would like to move this functionality server-side).
+                *
+                * The two parts of the key are separated by colon.  For example:
+                *
+                * "message-key:true": ast
+                *
+                * if they key is "message-key" and onlyCurlyBraceTransform is true.
+                *
+                * This cache is shared by all instances of mw.jqueryMsg.parser.
+                *
+                * @static
+                */
                astCache: {},
 
                /**
                 * @return {String|Array} string of '[key]' if message missing, simple string if possible, array of arrays if needs parsing
                 */
                getAst: function ( key ) {
-                       if ( this.astCache[ key ] === undefined ) {
-                               var wikiText = this.settings.messages.get( key );
+                       var cacheKey = [key, this.settings.onlyCurlyBraceTransform].join( ':' ), wikiText;
+
+                       if ( this.astCache[ cacheKey ] === undefined ) {
+                               wikiText = this.settings.messages.get( key );
                                if ( typeof wikiText !== 'string' ) {
                                        wikiText = '\\[' + key + '\\]';
                                }
-                               this.astCache[ key ] = this.wikiTextToAst( wikiText );
+                               this.astCache[ cacheKey ] = this.wikiTextToAst( wikiText );
                        }
-                       return this.astCache[ key ];
+                       return this.astCache[ cacheKey ];
                },
-               /*
+
+               /**
                 * Parses the input wikiText into an abstract syntax tree, essentially an s-expression.
                 *
                 * CAVEAT: This does not parse all wikitext. It could be more efficient, but it's pretty good already.
                 */
                wikiTextToAst: function ( input ) {
                        var pos,
-                               regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, backslash, anyCharacter,
-                               escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
+                               regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, regularLiteralWithSquareBrackets,
+                               backslash, anyCharacter, escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
                                whitespace, dollar, digits,
                                openExtlink, closeExtlink, wikilinkPage, wikilinkContents, openLink, closeLink, templateName, pipe, colon,
                                templateContents, openTemplate, closeTemplate,
-                               nonWhitespaceExpression, paramExpression, expression, result;
+                               nonWhitespaceExpression, paramExpression, expression, curlyBraceTransformExpression, result;
 
                        // Indicates current position in input as we parse through it.
                        // Shared among all parsing functions below.
                        regularLiteral = makeRegexParser( /^[^{}\[\]$\\]/ );
                        regularLiteralWithoutBar = makeRegexParser(/^[^{}\[\]$\\|]/);
                        regularLiteralWithoutSpace = makeRegexParser(/^[^{}\[\]$\s]/);
+                       regularLiteralWithSquareBrackets = makeRegexParser( /^[^{}$\\]/ );
                        backslash = makeStringParser( '\\' );
                        anyCharacter = makeRegexParser( /^./ );
                        function escapedLiteral() {
                        ] );
                        // Used to define "literals" without spaces, in space-delimited situations
                        function literalWithoutSpace() {
-                                var result = nOrMore( 1, escapedOrLiteralWithoutSpace )();
-                                return result === null ? null : result.join('');
+                               var result = nOrMore( 1, escapedOrLiteralWithoutSpace )();
+                               return result === null ? null : result.join('');
                        }
                        // Used to define "literals" within template parameters. The pipe character is the parameter delimeter, so by default
                        // it is not a literal in the parameter
                        function literalWithoutBar() {
-                                var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
-                                return result === null ? null : result.join('');
+                               var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
+                               return result === null ? null : result.join('');
                        }
 
                        // Used for wikilink page names.  Like literalWithoutBar, but
                        }
 
                        function literal() {
-                                var result = nOrMore( 1, escapedOrRegularLiteral )();
-                                return result === null ? null : result.join('');
+                               var result = nOrMore( 1, escapedOrRegularLiteral )();
+                               return result === null ? null : result.join('');
                        }
+
+                       function curlyBraceTransformExpressionLiteral() {
+                               var result = nOrMore( 1, regularLiteralWithSquareBrackets )();
+                               return result === null ? null : result.join('');
+                       }
+
                        whitespace = makeRegexParser( /^\s+/ );
                        dollar = makeStringParser( '$' );
                        digits = makeRegexParser( /^\d+/ );
                                literal
                        ] );
 
-                       function start() {
-                               var result = nOrMore( 0, expression )();
+                       // Used when only {{-transformation is wanted, for 'text'
+                       // or 'escaped' formats
+                       curlyBraceTransformExpression = choice( [
+                               template,
+                               replacement,
+                               curlyBraceTransformExpressionLiteral
+                       ] );
+
+
+                       /**
+                        * Starts the parse
+                        *
+                        * @param {Function} rootExpression root parse function
+                        */
+                       function start( rootExpression ) {
+                               var result = nOrMore( 0, rootExpression )();
                                if ( result === null ) {
                                        return null;
                                }
                        // everything above this point is supposed to be stateless/static, but
                        // I am deferring the work of turning it into prototypes & objects. It's quite fast enough
                        // finally let's do some actual work...
-                       result = start();
+
+                       // If you add another possible rootExpression, you must update the astCache key scheme.
+                       result = start( this.settings.onlyCurlyBraceTransform ? curlyBraceTransformExpression : expression );
 
                        /*
                         * For success, the p must have gotten to the end of the input
                                                $span.append( childNode );
                                        } );
                                } else {
-                                       // Let jQuery append nodes, arrays of nodes and jQuery objects
-                                       // other things (strings, numbers, ..) are appended as text nodes (not as HTML strings)
-                                       $span.append( $.type( node ) === 'object' ? node : document.createTextNode( node ) );
+                                       // strings, integers, anything else
+                                       // (will soon switch to createTextNode() for non-objects)
+                                       $span.append( node );
                                }
                        } );
                        return $span;
 
                /**
                 * Tranform parsed structure into a int: (interface language) message include
-                * Invoked by putting {{MediaWiki:othermessage}} into a message
+                * Invoked by putting {{int:othermessage}} into a message
                 * @param {Array} of nodes
                 * @return {string} Other message
                 */
        // Replace the default message parser with jqueryMsg
        oldParser = mw.Message.prototype.parser;
        mw.Message.prototype.parser = function () {
+               var messageFunction;
+
                // TODO: should we cache the message function so we don't create a new one every time? Benchmark this maybe?
                // Caching is somewhat problematic, because we do need different message functions for different maps, so
                // we'd have to cache the parser as a member of this.map, which sounds a bit ugly.
                // Do not use mw.jqueryMsg unless required
-               if ( !/\{\{|\[/.test(this.map.get( this.key ) ) ) {
+               if ( this.format === 'plain' || !/\{\{|\[/.test(this.map.get( this.key ) ) ) {
                        // Fall back to mw.msg's simple parser
                        return oldParser.apply( this );
                }
-               var messageFunction = mw.jqueryMsg.getMessageFunction( { 'messages': this.map } );
+
+               messageFunction = mw.jqueryMsg.getMessageFunction( {
+                       'messages': this.map,
+                       // For format 'escaped', escaping part is handled by mediawiki.js
+                       'format': this.format
+               } );
                return messageFunction( this.key, this.parameters );
        };
 
index b0abc9e..b5b42e1 100644 (file)
@@ -13,14 +13,13 @@ var mw = ( function ( $, undefined ) {
        /* Object constructors */
 
        /**
-        * Map
-        *
         * Creates an object that can be read from or written to from prototype functions
         * that allow both single and multiple variables at once.
+        * @class mw.Map
         *
-        * @param global boolean Whether to store the values in the global window
+        * @constructor
+        * @param {boolean} global Whether to store the values in the global window
         *  object or a exclusively in the object property 'values'.
-        * @return Map
         */
        function Map( global ) {
                this.values = global === true ? window : {};
@@ -39,7 +38,7 @@ var mw = ( function ( $, undefined ) {
                 *  If selection was an array, returns an object of key/values (value is null if not found),
                 *  If selection was not passed or invalid, will return the 'values' object member (be careful as
                 *  objects are always passed by reference in JavaScript!).
-                * @return Values as a string or object, null if invalid/inexistant.
+                * @return {string|Object|null} Values as a string or object, null if invalid/inexistant.
                 */
                get: function ( selection, fallback ) {
                        var results, i;
@@ -98,7 +97,7 @@ var mw = ( function ( $, undefined ) {
                 * Checks if one or multiple keys exist.
                 *
                 * @param selection {mixed} String key or array of keys to check
-                * @return {Boolean} Existence of key(s)
+                * @return {boolean} Existence of key(s)
                 */
                exists: function ( selection ) {
                        var s;
@@ -116,18 +115,17 @@ var mw = ( function ( $, undefined ) {
        };
 
        /**
-        * Message
-        *
         * Object constructor for messages,
         * similar to the Message class in MediaWiki PHP.
+        * @class mw.Message
         *
-        * @param map Map Instance of mw.Map
-        * @param key String
-        * @param parameters Array
-        * @return Message
+        * @constructor
+        * @param {mw.Map} map Message storage
+        * @param {string} key
+        * @param {Array} [parameters]
         */
        function Message( map, key, parameters ) {
-               this.format = 'plain';
+               this.format = 'text';
                this.map = map;
                this.key = key;
                this.parameters = parameters === undefined ? [] : slice.call( parameters );
@@ -136,9 +134,13 @@ var mw = ( function ( $, undefined ) {
 
        Message.prototype = {
                /**
-                * Simple message parser, does $N replacement and nothing else.
+                * Simple message parser, does $N replacement, HTML-escaping (only for
+                * 'escaped' format), and nothing else.
+                *
                 * This may be overridden to provide a more complex message parser.
                 *
+                * The primary override is in mediawiki.jqueryMsg.
+                *
                 * This function will not be called for nonexistent messages.
                 */
                parser: function () {
@@ -152,8 +154,8 @@ var mw = ( function ( $, undefined ) {
                /**
                 * Appends (does not replace) parameters for replacement to the .parameters property.
                 *
-                * @param parameters Array
-                * @return Message
+                * @param {Array} parameters
+                * @chainable
                 */
                params: function ( parameters ) {
                        var i;
@@ -166,25 +168,21 @@ var mw = ( function ( $, undefined ) {
                /**
                 * Converts message object to it's string form based on the state of format.
                 *
-                * @return string Message as a string in the current form or <key> if key does not exist.
+                * @return {string} Message as a string in the current form or `<key>` if key does not exist.
                 */
                toString: function () {
                        var text;
 
                        if ( !this.exists() ) {
                                // Use <key> as text if key does not exist
-                               if ( this.format !== 'plain' ) {
-                                       // format 'escape' and 'parse' need to have the brackets and key html escaped
+                               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 + '>';
                        }
 
-                       if ( this.format === 'plain' ) {
-                               // @todo FIXME: Although not applicable to core Message,
-                               // Plugins like jQueryMsg should be able to distinguish
-                               // between 'plain' (only variable replacement and plural/gender)
-                               // and actually parsing wikitext to HTML.
+                       if ( this.format === 'plain' || this.format === 'text' || this.format === 'parse' ) {
                                text = this.parser();
                        }
 
@@ -193,15 +191,16 @@ var mw = ( function ( $, undefined ) {
                                text = mw.html.escape( text );
                        }
 
-                       if ( this.format === 'parse' ) {
-                               text = this.parser();
-                       }
-
                        return text;
                },
 
                /**
-                * Changes format to parse and converts message to string
+                * Changes format to 'parse' and converts message to string
+                *
+                * If jqueryMsg is loaded, this parses the message text from wikitext
+                * (where supported) to HTML
+                *
+                * Otherwise, it is equivalent to plain.
                 *
                 * @return {string} String form of parsed message
                 */
@@ -211,7 +210,10 @@ var mw = ( function ( $, undefined ) {
                },
 
                /**
-                * Changes format to plain and converts message to string
+                * Changes format to 'plain' and converts message to string
+                *
+                * This substitutes parameters, but otherwise does not change the
+                * message text.
                 *
                 * @return {string} String form of plain message
                 */
@@ -221,7 +223,23 @@ var mw = ( function ( $, undefined ) {
                },
 
                /**
-                * Changes the format to html escaped and converts message to string
+                * Changes format to 'text' and converts message to string
+                *
+                * If jqueryMsg is loaded, {{-transformation is done where supported
+                * (such as {{plural:}}, {{gender:}}, {{int:}}).
+                *
+                * Otherwise, it is equivalent to plain.
+                */
+               text: function () {
+                       this.format = 'text';
+                       return this.toString();
+               },
+
+               /**
+                * Changes the format to 'escaped' and converts message to string
+                *
+                * This is equivalent to using the 'text' format (see text method), then
+                * HTML-escaping the output.
                 *
                 * @return {string} String form of html escaped message
                 */
@@ -233,13 +251,19 @@ var mw = ( function ( $, undefined ) {
                /**
                 * Checks if message exists
                 *
-                * @return {string} String form of parsed message
+                * @see mw.Map#exists
+                * @return {boolean}
                 */
                exists: function () {
                        return this.map.exists( this.key );
                }
        };
 
+       /**
+        * @class mw
+        * @alternateClassName mediaWiki
+        * @singleton
+        */
        return {
                /* Public Members */
 
@@ -249,77 +273,72 @@ var mw = ( function ( $, undefined ) {
                 */
                log: function () { },
 
-               /**
-                * @var constructor Make the Map constructor publicly available.
-                */
+               // Make the Map constructor publicly available.
                Map: Map,
 
-               /**
-                * @var constructor Make the Message constructor publicly available.
-                */
+               // Make the Message constructor publicly available.
                Message: Message,
 
                /**
                 * List of configuration values
                 *
                 * Dummy placeholder. Initiated in startUp module as a new instance of mw.Map().
-                * If $wgLegacyJavaScriptGlobals is true, this Map will have its values
+                * If `$wgLegacyJavaScriptGlobals` is true, this Map will have its values
                 * in the global window object.
+                * @property
                 */
                config: null,
 
                /**
-                * @var object
-                *
                 * Empty object that plugins can be installed in.
+                * @property
                 */
                libs: {},
 
                /* Extension points */
 
+               /**
+                * @property
+                */
                legacy: {},
 
                /**
                 * Localization system
+                * @property {mw.Map}
                 */
                messages: new Map(),
 
                /* Public Methods */
 
                /**
-                * Gets a message object, similar to wfMessage()
+                * Gets a message object, similar to wfMessage().
                 *
-                * @param key string Key of message to get
-                * @param parameter1 mixed First argument in a list of variadic arguments,
-                *  each a parameter for $N replacement in messages.
-                * @return Message
+                * @param {string} key Key of message to get
+                * @param {Mixed...} parameters Parameters for the $N replacements in messages.
+                * @return {mw.Message}
                 */
-               message: function ( key, parameter1 ) {
-                       var parameters;
-                       // Support variadic arguments
-                       if ( parameter1 !== undefined ) {
-                               parameters = slice.call( arguments );
-                               parameters.shift();
-                       } else {
-                               parameters = [];
-                       }
+               message: function ( key ) {
+                       // Variadic arguments
+                       var parameters = slice.call( arguments, 1 );
                        return new Message( mw.messages, key, parameters );
                },
 
                /**
                 * Gets a message string, similar to wfMessage()
                 *
-                * @param key string Key of message to get
-                * @param parameters mixed First argument in a list of variadic arguments,
-                *  each a parameter for $N replacement in messages.
-                * @return String.
+                * @see mw.Message#toString
+                * @param {string} key Key of message to get
+                * @param {Mixed...} parameters Parameters for the $N replacements in messages.
+                * @return {string}
                 */
-               msg: function ( /* key, parameter_1, parameter_2, .. */ ) {
+               msg: function ( /* key, parameters... */ ) {
                        return mw.message.apply( mw.message, arguments ).toString();
                },
 
                /**
                 * Client-side module loader which integrates with the MediaWiki ResourceLoader
+                * @class mw.loader
+                * @singleton
                 */
                loader: ( function () {
 
@@ -338,29 +357,32 @@ var mw = ( function ( $, undefined ) {
                         * mw.loader.implement.
                         *
                         * Format:
-                        *      {
-                        *              'moduleName': {
-                        *                      'version': ############## (unix timestamp),
-                        *                      'dependencies': ['required.foo', 'bar.also', ...], (or) function () {}
-                        *                      'group': 'somegroup', (or) null,
-                        *                      'source': 'local', 'someforeignwiki', (or) null
-                        *                      'state': 'registered', 'loading', 'loaded', 'ready', 'error' or 'missing'
-                        *                      'script': ...,
-                        *                      'style': ...,
-                        *                      'messages': { 'key': 'value' },
-                        *              }
-                        *      }
+                        *     {
+                        *         'moduleName': {
+                        *             'version': ############## (unix timestamp),
+                        *             'dependencies': ['required.foo', 'bar.also', ...], (or) function () {}
+                        *             'group': 'somegroup', (or) null,
+                        *             'source': 'local', 'someforeignwiki', (or) null
+                        *             'state': 'registered', 'loading', 'loaded', 'ready', 'error' or 'missing'
+                        *             'script': ...,
+                        *             'style': ...,
+                        *             'messages': { 'key': 'value' },
+                        *         }
+                        *     }
+                        *
+                        * @property
+                        * @private
                         */
                        var registry = {},
-                               /**
-                                * Mapping of sources, keyed by source-id, values are objects.
-                                * Format:
-                                *      {
-                                *              'sourceId': {
-                                *                      'loadScript': 'http://foo.bar/w/load.php'
-                                *              }
-                                *      }
-                                */
+                               //
+                               // Mapping of sources, keyed by source-id, values are objects.
+                               // Format:
+                               //      {
+                               //              'sourceId': {
+                               //                      'loadScript': 'http://foo.bar/w/load.php'
+                               //              }
+                               //      }
+                               //
                                sources = {},
                                // List of modules which will be loaded as when ready
                                batch = [],
@@ -392,10 +414,11 @@ var mw = ( function ( $, undefined ) {
                        /**
                         * Create a new style tag and add it to the DOM.
                         *
-                        * @param text String: CSS text
-                        * @param nextnode mixed: [optional] An Element or jQuery object for an element where
-                        * the style tag should be inserted before. Otherwise appended to the <head>.
-                        * @return HTMLStyleElement
+                        * @private
+                        * @param {string} text CSS text
+                        * @param {Mixed} [nextnode] An Element or jQuery object for an element where
+                        * the style tag should be inserted before. Otherwise appended to the `<head>`.
+                        * @return {HTMLElement} Node reference to the created `<style>` tag.
                         */
                        function addStyleTag( text, nextnode ) {
                                var s = document.createElement( 'style' );
@@ -432,11 +455,15 @@ var mw = ( function ( $, undefined ) {
                         * Checks if certain cssText is safe to append to
                         * a stylesheet.
                         *
-                        * Right now it only makes sure that cssText containing @import
+                        * Right now it only makes sure that cssText containing `@import`
                         * rules will end up in a new stylesheet (as those only work when
                         * placed at the start of a stylesheet; bug 35562).
                         * This could later be extended to take care of other bugs, such as
                         * the IE cssRules limit - not the same as the IE styleSheets limit).
+                        * @private
+                        * @param {jQuery} $style
+                        * @param {string} cssText
+                        * @return {boolean}
                         */
                        function canExpandStylesheetWith( $style, cssText ) {
                                return cssText.indexOf( '@import' ) === -1;
@@ -445,12 +472,12 @@ var mw = ( function ( $, undefined ) {
                        function addEmbeddedCSS( cssText ) {
                                var $style, styleEl;
                                $style = getMarker().prev();
-                               // Re-use <style> tags if possible, this to try to stay
+                               // Re-use `<style>` tags if possible, this to try to stay
                                // under the IE stylesheet limit (bug 31676).
                                // Also verify that the the element before Marker actually is one
                                // that came from ResourceLoader, and not a style tag that some
                                // other script inserted before our marker, or, more importantly,
-                               // it may not be a style tag at all (could be <meta> or <script>).
+                               // it may not be a style tag at all (could be `<meta>` or `<script>`).
                                if (
                                        $style.data( 'ResourceLoaderDynamicStyleTag' ) === true &&
                                        canExpandStylesheetWith( $style, cssText )
@@ -475,6 +502,7 @@ var mw = ( function ( $, undefined ) {
 
                        /**
                         * Generates an ISO8601 "basic" string from a UNIX timestamp
+                        * @private
                         */
                        function formatVersionNumber( timestamp ) {
                                var     d = new Date();
@@ -491,15 +519,16 @@ var mw = ( function ( $, undefined ) {
                        /**
                         * Resolves dependencies and detects circular references.
                         *
-                        * @param module String Name of the top-level module whose dependencies shall be
+                        * @private
+                        * @param {string} module Name of the top-level module whose dependencies shall be
                         *   resolved and sorted.
-                        * @param resolved Array Returns a topological sort of the given module and its
+                        * @param {Array} resolved Returns a topological sort of the given module and its
                         *   dependencies, such that later modules depend on earlier modules. The array
                         *   contains the module names. If the array contains already some module names,
                         *   this function appends its result to the pre-existing array.
-                        * @param unresolved Object [optional] Hash used to track the current dependency
+                        * @param {Object} [unresolved] Hash used to track the current dependency
                         *   chain; used to report loops in the dependency graph.
-                        * @throws Error if any unregistered module or a dependency loop is encountered
+                        * @throws {Error} If any unregistered module or a dependency loop is encountered
                         */
                        function sortDependencies( module, resolved, unresolved ) {
                                var n, deps, len;
@@ -548,9 +577,10 @@ var mw = ( function ( $, undefined ) {
                         * Gets a list of module names that a module depends on in their proper dependency
                         * order.
                         *
-                        * @param module string module name or array of string module names
-                        * @return list of dependencies, including 'module'.
-                        * @throws Error if circular reference is detected
+                        * @private
+                        * @param {string} module Module name or array of string module names
+                        * @return {Array} list of dependencies, including 'module'.
+                        * @throws {Error} If circular reference is detected
                         */
                        function resolve( module ) {
                                var m, resolved;
@@ -579,10 +609,11 @@ var mw = ( function ( $, undefined ) {
                         * One can also filter for 'unregistered', which will return the
                         * modules names that don't have a registry entry.
                         *
-                        * @param states string or array of strings of module states to filter by
-                        * @param modules array list of module names to filter (optional, by default the entire
+                        * @private
+                        * @param {string|string[]} states Module states to filter by
+                        * @param {Array} modules List of module names to filter (optional, by default the entire
                         * registry is used)
-                        * @return array list of filtered module names
+                        * @return {Array} List of filtered module names
                         */
                        function filter( states, modules ) {
                                var list, module, s, m;
@@ -624,9 +655,9 @@ var mw = ( function ( $, undefined ) {
                         * Determine whether all dependencies are in state 'ready', which means we may
                         * execute the module or job now.
                         *
-                        * @param dependencies Array dependencies (module names) to be checked.
-                        *
-                        * @return Boolean true if all dependencies are in state 'ready', false otherwise
+                        * @private
+                        * @param {Array} dependencies Dependencies (module names) to be checked.
+                        * @return {boolean} True if all dependencies are in state 'ready', false otherwise
                         */
                        function allReady( dependencies ) {
                                return filter( 'ready', dependencies ).length === dependencies.length;
@@ -638,8 +669,9 @@ var mw = ( function ( $, undefined ) {
                         * Gets console references in each invocation, so that delayed debugging tools work
                         * fine. No need for optimization here, which would only result in losing logs.
                         *
-                        * @param msg String text for the log entry.
-                        * @param e Error [optional] to also log.
+                        * @private
+                        * @param {string} msg text for the log entry.
+                        * @param {Error} [e]
                         */
                        function log( msg, e ) {
                                var console = window.console;
@@ -661,7 +693,8 @@ var mw = ( function ( $, undefined ) {
                         * state up the dependency tree; otherwise, execute all jobs/modules that now have all their
                         * dependencies satisfied. On jobs depending on a failed module, run the error callback, if any.
                         *
-                        * @param module String name of module that entered one of the states 'ready', 'error', or 'missing'.
+                        * @private
+                        * @param {string} module Name of module that entered one of the states 'ready', 'error', or 'missing'.
                         */
                        function handlePending( module ) {
                                var j, job, hasErrors, m, stateChange;
@@ -729,8 +762,9 @@ var mw = ( function ( $, undefined ) {
                         * Adds a script tag to the DOM, either using document.write or low-level DOM manipulation,
                         * depending on whether document-ready has occurred yet and whether we are in async mode.
                         *
-                        * @param src String: URL to script, will be used as the src attribute in the script tag
-                        * @param callback Function: Optional callback which will be run when the script is done
+                        * @private
+                        * @param {string} src URL to script, will be used as the src attribute in the script tag
+                        * @param {Function} [callback] Callback which will be run when the script is done
                         */
                        function addScript( src, callback, async ) {
                                /*jshint evil:true */
@@ -804,7 +838,8 @@ var mw = ( function ( $, undefined ) {
                        /**
                         * Executes a loaded module, making it ready to use
                         *
-                        * @param module string module name to execute
+                        * @private
+                        * @param {string} module Module name to execute
                         */
                        function execute( module ) {
                                var key, value, media, i, urls, script, markModuleReady, nestedAddScript;
@@ -822,6 +857,7 @@ var mw = ( function ( $, undefined ) {
                                /**
                                 * Define loop-function here for efficiency
                                 * and to avoid re-using badly scoped variables.
+                                * @ignore
                                 */
                                function addLink( media, url ) {
                                        var el = document.createElement( 'link' );
@@ -932,11 +968,12 @@ var mw = ( function ( $, undefined ) {
                         * Adds a dependencies to the queue with optional callbacks to be run
                         * when the dependencies are ready or fail
                         *
-                        * @param dependencies string module name or array of string module names
-                        * @param ready function callback to execute when all dependencies are ready
-                        * @param error function callback to execute when any dependency fails
-                        * @param async (optional) If true, load modules asynchronously even if
-                        *  document ready has not yet occurred
+                        * @private
+                        * @param {string|string[]} dependencies Module name or array of string module names
+                        * @param {Function} ready Callback to execute when all dependencies are ready
+                        * @param {Function} error Callback to execute when any dependency fails
+                        * @param {boolean} [async] If true, load modules asynchronously even if
+                        *  document ready has not yet occurred.
                         */
                        function request( dependencies, ready, error, async ) {
                                var n;
@@ -991,6 +1028,7 @@ var mw = ( function ( $, undefined ) {
                        /**
                         * Converts a module map of the form { foo: [ 'bar', 'baz' ], bar: [ 'baz, 'quux' ] }
                         * to a query string of the form foo.bar,baz|bar.baz,quux
+                        * @private
                         */
                        function buildModulesString( moduleMap ) {
                                var arr = [], p, prefix;
@@ -1004,10 +1042,11 @@ var mw = ( function ( $, undefined ) {
                        /**
                         * Asynchronously append a script tag to the end of the body
                         * that invokes load.php
-                        * @param moduleMap {Object}: Module map, see buildModulesString()
-                        * @param currReqBase {Object}: Object with other parameters (other than 'modules') to use in the request
-                        * @param sourceLoadScript {String}: URL of load.php
-                        * @param async {Boolean}: If true, use an asynchrounous request even if document ready has not yet occurred
+                        * @private
+                        * @param {Object} moduleMap Module map, see #buildModulesString
+                        * @param {Object} currReqBase Object with other parameters (other than 'modules') to use in the request
+                        * @param {string} sourceLoadScript URL of load.php
+                        * @param {boolean} async If true, use an asynchrounous request even if document ready has not yet occurred
                         */
                        function doRequest( moduleMap, currReqBase, sourceLoadScript, async ) {
                                var request = $.extend(
@@ -1162,10 +1201,10 @@ var mw = ( function ( $, undefined ) {
                                /**
                                 * Register a source.
                                 *
-                                * @param id {String}: Short lowercase a-Z string representing a source, only used internally.
-                                * @param props {Object}: Object containing only the loadScript property which is a url to
-                                * the load.php location of the source.
-                                * @return {Boolean}
+                                * @param {string} id Short lowercase a-Z string representing a source, only used internally.
+                                * @param {Object} props Object containing only the loadScript property which is a url to
+                                *  the load.php location of the source.
+                                * @return {boolean}
                                 */
                                addSource: function ( id, props ) {
                                        var source;
@@ -1244,20 +1283,20 @@ var mw = ( function ( $, undefined ) {
                                 *
                                 * All arguments are required.
                                 *
-                                * @param {String} module Name of module
+                                * @param {string} module Name of module
                                 * @param {Function|Array} script Function with module code or Array of URLs to
-                                *  be used as the src attribute of a new <script> tag.
+                                *  be used as the src attribute of a new `<script>` tag.
                                 * @param {Object} style Should follow one of the following patterns:
-                                *  { "css": [css, ..] }
-                                *  { "url": { <media>: [url, ..] } }
-                                *  And for backwards compatibility (needs to be supported forever due to caching):
-                                *  { <media>: css }
-                                *  { <media>: [url, ..] }
+                                *     { "css": [css, ..] }
+                                *     { "url": { <media>: [url, ..] } }
+                                * And for backwards compatibility (needs to be supported forever due to caching):
+                                *     { <media>: css }
+                                *     { <media>: [url, ..] }
                                 *
-                                *  The reason css strings are not concatenated anymore is bug 31676. We now check
-                                *  whether it's safe to extend the stylesheet (see canExpandStylesheetWith).
+                                * The reason css strings are not concatenated anymore is bug 31676. We now check
+                                * whether it's safe to extend the stylesheet (see #canExpandStylesheetWith).
                                 *
-                                * @param {Object} msgs List of key/value pairs to be passed through mw.messages.set
+                                * @param {Object} msgs List of key/value pairs to be added to {@link mw#messages}.
                                 */
                                implement: function ( module, script, style, msgs ) {
                                        // Validate input
@@ -1491,7 +1530,11 @@ var mw = ( function ( $, undefined ) {
                        };
                }() ),
 
-               /** HTML construction helper functions */
+               /**
+                * HTML construction helper functions
+                * @class mw.html
+                * @singleton
+                */
                html: ( function () {
                        function escapeCallback( s ) {
                                switch ( s ) {
@@ -1511,7 +1554,7 @@ var mw = ( function ( $, undefined ) {
                        return {
                                /**
                                 * Escape a string for HTML. Converts special characters to HTML entities.
-                                * @param s The string to escape
+                                * @param {string} s The string to escape
                                 */
                                escape: function ( s ) {
                                        return s.replace( /['"<>&]/g, escapeCallback );
@@ -1519,7 +1562,7 @@ var mw = ( function ( $, undefined ) {
 
                                /**
                                 * Wrapper object for raw HTML passed to mw.html.element().
-                                * @constructor
+                                * @class mw.html.Raw
                                 */
                                Raw: function ( value ) {
                                        this.value = value;
@@ -1527,7 +1570,7 @@ var mw = ( function ( $, undefined ) {
 
                                /**
                                 * Wrapper object for CDATA element contents passed to mw.html.element()
-                                * @constructor
+                                * @class mw.html.Cdata
                                 */
                                Cdata: function ( value ) {
                                        this.value = value;
index 35cc6d8..fd34e7e 100644 (file)
@@ -1,25 +1,24 @@
-/**
- * Implements mediaWiki.notification library
- */
 ( function ( mw, $ ) {
        'use strict';
 
        var notification,
                isPageReady = false,
-               isInitialized = false,
                preReadyNotifQueue = [],
-               /**
-                * @var {jQuery}
-                * The #mw-notification-area div that all notifications are contained inside.
-                */
+               // The #mw-notification-area div that all notifications are contained inside.
                $area = null;
 
        /**
         * Creates a Notification object for 1 message.
-        * Does not insert anything into the document (see .start()).
+        * Does not insert anything into the document (see #start).
+        *
+        * The "_" in the name is to avoid a bug (http://github.com/senchalabs/jsduck/issues/304)
+        * It is not part of the actual class name.
+        *
+        * @class mw.Notification_
+        * @alternateClassName mw.Notification
+        * @private
         *
         * @constructor
-        * @see mw.notification.notify
         */
        function Notification( message, options ) {
                var $notification, $notificationTitle, $notificationContent;
         *
         * @param {Object} options An object containing options for the closing of the notification.
         *  These are typically only used internally.
+        *
         *  - speed: Use a close speed different than the default 'slow'.
         *  - placeholder: Set to false to disable the placeholder transition.
         */
 
        /**
         * Helper function, take a list of notification divs and call
-        * a function on the Notification instance attached to them
+        * a function on the Notification instance attached to them.
         *
         * @param {jQuery} $notifications A jQuery object containing notification divs
         * @param {string} fn The name of the function to call on the Notification instance
        }
 
        /**
-        * Initialisation
-        * (don't call before document ready)
+        * Initialisation.
+        * Must only be called once, and not before the document is ready.
+        * @ignore
         */
        function init() {
-               if ( !isInitialized ) {
-                       isInitialized = true;
-                       $area = $( '<div id="mw-notification-area"></div>' )
-                               // Pause auto-hide timers when the mouse is in the notification area.
-                               .on( {
-                                       mouseenter: notification.pause,
-                                       mouseleave: notification.resume
-                               } )
-                               // When clicking on a notification close it.
-                               .on( 'click', '.mw-notification', function () {
-                                       var notif = $( this ).data( 'mw.notification' );
-                                       if ( notif ) {
-                                               notif.close();
-                                       }
-                               } )
-                               // Stop click events from <a> tags from propogating to prevent clicking.
-                               // on links from hiding a notification.
-                               .on( 'click', 'a', function ( e ) {
-                                       e.stopPropagation();
-                               } );
-
-                       // Prepend the notification area to the content area and save it's object.
-                       mw.util.$content.prepend( $area );
-               }
+               $area = $( '<div id="mw-notification-area"></div>' )
+                       // Pause auto-hide timers when the mouse is in the notification area.
+                       .on( {
+                               mouseenter: notification.pause,
+                               mouseleave: notification.resume
+                       } )
+                       // When clicking on a notification close it.
+                       .on( 'click', '.mw-notification', function () {
+                               var notif = $( this ).data( 'mw.notification' );
+                               if ( notif ) {
+                                       notif.close();
+                               }
+                       } )
+                       // Stop click events from <a> tags from propogating to prevent clicking.
+                       // on links from hiding a notification.
+                       .on( 'click', 'a', function ( e ) {
+                               e.stopPropagation();
+                       } );
+
+               // Prepend the notification area to the content area and save it's object.
+               mw.util.$content.prepend( $area );
        }
 
+       /**
+        * @class mw.notification
+        * @singleton
+        */
        notification = {
                /**
                 * Pause auto-hide timers for all notifications.
                 * Notifications will not auto-hide until resume is called.
+                * @see mw.Notification#pause
                 */
                pause: function () {
                        callEachNotification(
 
                /**
                 * Resume any paused auto-hide timers from the beginning.
-                * Only the first {autoHideLimit} timers will be resumed.
+                * Only the first #autoHideLimit timers will be resumed.
                 */
                resume: function () {
                        callEachNotification(
-                               // Only call resume on the first {autoHideLimit} notifications.
-                               // Exclude noautohide notifications to avoid bugs where {autoHideLimit}
-                               // { autoHide: false } notifications are at the start preventing any
+                               // Only call resume on the first #autoHideLimit notifications.
+                               // Exclude noautohide notifications to avoid bugs where #autoHideLimit
+                               // `{ autoHide: false }` notifications are at the start preventing any
                                // auto-hide notifications from being autohidden.
                                $area.children( '.mw-notification-autohide' ).slice( 0, notification.autoHideLimit ),
                                'resume'
                /**
                 * Display a notification message to the user.
                 *
-                * @param {mixed} message The DOM-element, jQuery object, mw.Message instance,
-                *  or plaintext string to be used as the message.
+                * @param {HTMLElement|jQuery|mw.Message|string} message
                 * @param {Object} options The options to use for the notification.
-                *  See mw.notification.defaults for details.
+                *  See #defaults for details.
                 */
                notify: function ( message, options ) {
                        var notif;
                },
 
                /**
-                * @var {Object}
-                * The defaults for mw.notification.notify's options parameter
-                *   autoHide:
-                *     A boolean indicating whether the notifification should automatically
-                *     be hidden after shown. Or if it should persist.
+                * @property {Object}
+                * The defaults for #notify options parameter.
+                *
+                * - autoHide:
+                *   A boolean indicating whether the notifification should automatically
+                *   be hidden after shown. Or if it should persist.
                 *
-                *   tag:
-                *     An optional string. When a notification is tagged only one message
-                *     with that tag will be displayed. Trying to display a new notification
-                *     with the same tag as one already being displayed will cause the other
-                *     notification to be closed and this new notification to open up inside
-                *     the same place as the previous notification.
+                * - tag:
+                *   An optional string. When a notification is tagged only one message
+                *   with that tag will be displayed. Trying to display a new notification
+                *   with the same tag as one already being displayed will cause the other
+                *   notification to be closed and this new notification to open up inside
+                *   the same place as the previous notification.
                 *
-                *   title:
-                *     An optional title for the notification. Will be displayed above the
-                *     content. Usually in bold.
+                * - title:
+                *   An optional title for the notification. Will be displayed above the
+                *   content. Usually in bold.
                 */
                defaults: {
                        autoHide: true,
                },
 
                /**
-                * @var {number}
+                * @property {number}
                 * Number of seconds to wait before auto-hiding notifications.
                 */
                autoHideSeconds: 5,
 
                /**
-                * @var {number}
+                * @property {number}
                 * Maximum number of notifications to count down auto-hide timers for.
-                * Only the first {autoHideLimit} notifications being displayed will
+                * Only the first #autoHideLimit notifications being displayed will
                 * auto-hide. Any notifications further down in the list will only start
                 * counting down to auto-hide after the first few messages have closed.
                 *
                 * This basically represents the number of notifications the user should
-                * be able to process in {autoHideSeconds} time.
+                * be able to process in #autoHideSeconds time.
                 */
                autoHideLimit: 3
        };
index 3bf2a89..83d95b6 100644 (file)
@@ -1,11 +1,13 @@
 /**
- * Implements mediaWiki.notify function
+ * @class mw.plugin.notify
  */
 ( function ( mw ) {
        'use strict';
 
        /**
-        * @see mw.notification.notify
+        * @see mw.notification#notify
+        * @param message
+        * @param options
         */
        mw.notify = function ( message, options ) {
                // Don't bother loading the whole notification system if we never use it.
@@ -17,4 +19,9 @@
                } );
        };
 
-}( mediaWiki ) );
\ No newline at end of file
+       /**
+        * @class mw
+        * @mixins mw.plugin.notify
+        */
+
+}( mediaWiki ) );
diff --git a/resources/mediawiki/mediawiki.searchSuggest.css b/resources/mediawiki/mediawiki.searchSuggest.css
new file mode 100644 (file)
index 0000000..0fb862b
--- /dev/null
@@ -0,0 +1,16 @@
+/* Make sure the links are not underlined or colored, ever. */
+/* There is already a :focus / :hover indication on the <div>. */
+.suggestions a.mw-searchSuggest-link,
+.suggestions a.mw-searchSuggest-link:hover,
+.suggestions a.mw-searchSuggest-link:active,
+.suggestions a.mw-searchSuggest-link:focus {
+       text-decoration: none;
+       color: black;
+}
+
+.suggestions-result-current a.mw-searchSuggest-link,
+.suggestions-result-current a.mw-searchSuggest-link:hover,
+.suggestions-result-current a.mw-searchSuggest-link:active,
+.suggestions-result-current a.mw-searchSuggest-link:focus {
+       color: white;
+}
index 99a5557..2bc7cea 100644 (file)
@@ -3,7 +3,7 @@
  */
 ( function ( mw, $ ) {
        $( document ).ready( function ( $ ) {
-               var map, searchboxesSelectors,
+               var map, resultRenderCache, searchboxesSelectors,
                        // Region where the suggestions box will appear directly below
                        // (using the same width). Can be a container element or the input
                        // itself, depending on what suits best in the environment.
                        return;
                }
 
+               // Compute form data for search suggestions functionality.
+               function computeResultRenderCache( context ) {
+                       var $form, formAction, baseHref, linkParams;
+
+                       // Compute common parameters for links' hrefs
+                       $form = context.config.$region.closest( 'form' );
+
+                       formAction = $form.attr( 'action' );
+                       baseHref = formAction + ( formAction.match(/\?/) ? '&' : '?' );
+
+                       linkParams = {};
+                       $.each( $form.serializeArray(), function ( idx, obj ) {
+                               linkParams[ obj.name ] = obj.value;
+                       } );
+
+                       return {
+                               textParam: context.data.$textbox.attr( 'name' ),
+                               linkParams: linkParams,
+                               baseHref: baseHref
+                       };
+               }
+
+               // The function used to render the suggestions.
+               function renderFunction( text, context ) {
+                       if ( !resultRenderCache ) {
+                               resultRenderCache = computeResultRenderCache( context );
+                       }
+
+                       // linkParams object is modified and reused
+                       resultRenderCache.linkParams[ resultRenderCache.textParam ] = text;
+
+                       // this is the container <div>, jQueryfied
+                       this
+                               .append(
+                                       // the <span> is needed for $.autoEllipsis to work
+                                       $( '<span>' )
+                                               .css( 'whiteSpace', 'nowrap' )
+                                               .text( text )
+                               )
+                               .wrap(
+                                       $( '<a>' )
+                                               .attr( 'href', resultRenderCache.baseHref + $.param( resultRenderCache.linkParams ) )
+                                               .addClass( 'mw-searchSuggest-link' )
+                               );
+               }
+
+               function specialRenderFunction( query, context ) {
+                       var $el = this;
+
+                       if ( !resultRenderCache ) {
+                               resultRenderCache = computeResultRenderCache( context );
+                       }
+
+                       // linkParams object is modified and reused
+                       resultRenderCache.linkParams[ resultRenderCache.textParam ] = query;
+
+                       if ( $el.children().length === 0 ) {
+                               $el
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'special-label' )
+                                                       .text( mw.msg( 'searchsuggest-containing' ) ),
+                                               $( '<div>' )
+                                                       .addClass( 'special-query' )
+                                                       .text( query )
+                                                       .autoEllipsis()
+                                       )
+                                       .show();
+                       } else {
+                               $el.find( '.special-query' )
+                                       .text( query )
+                                       .autoEllipsis();
+                       }
+
+                       if ( $el.parent().hasClass( 'mw-searchSuggest-link' ) ) {
+                               $el.parent().attr( 'href', resultRenderCache.baseHref + $.param( resultRenderCache.linkParams ) + '&fulltext=1' );
+                       } else {
+                               $el.wrap(
+                                       $( '<a>' )
+                                               .attr( 'href', resultRenderCache.baseHref + $.param( resultRenderCache.linkParams ) + '&fulltext=1' )
+                                               .addClass( 'mw-searchSuggest-link' )
+                               );
+                       }
+               }
+
                // General suggestions functionality for all search boxes
                searchboxesSelectors = [
                        // Primary searchbox on every page in standard skins
                                        }
                                },
                                result: {
+                                       render: renderFunction,
                                        select: function ( $input ) {
                                                $input.closest( 'form' ).submit();
                                        }
                // Special suggestions functionality for skin-provided search box
                $searchInput.suggestions( {
                        result: {
+                               render: renderFunction,
                                select: function ( $input ) {
                                        $input.closest( 'form' ).submit();
                                }
                        },
                        special: {
-                               render: function ( query ) {
-                                       var $el = this;
-                                       if ( $el.children().length === 0 ) {
-                                               $el
-                                                       .append(
-                                                               $( '<div>' )
-                                                                       .addClass( 'special-label' )
-                                                                       .text( mw.msg( 'searchsuggest-containing' ) ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'special-query' )
-                                                                       .text( query )
-                                                                       .autoEllipsis()
-                                                       )
-                                                       .show();
-                                       } else {
-                                               $el.find( '.special-query' )
-                                                       .text( query )
-                                                       .autoEllipsis();
-                                       }
-                               },
+                               render: specialRenderFunction,
                                select: function ( $input ) {
                                        $input.closest( 'form' ).append(
                                                $( '<input type="hidden" name="fulltext" value="1"/>' )
index 5c5c87e..3b2a59c 100644 (file)
@@ -61,7 +61,7 @@
                 *
                 * @return String: Random set of 32 alpha-numeric characters
                 */
-               function generateId() {
+               this.generateRandomSessionId = function () {
                        var i, r,
                                id = '',
                                seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
@@ -70,7 +70,7 @@
                                id += seed.substring( r, r + 1 );
                        }
                        return id;
-               }
+               };
 
                /**
                 * Gets the current user's name.
                this.sessionId = function () {
                        var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
                        if ( typeof sessionId === 'undefined' || sessionId === null ) {
-                               sessionId = generateId();
+                               sessionId = user.generateRandomSessionId();
                                $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
                        }
                        return sessionId;
                        }
                        id = $.cookie( 'mediaWiki.user.id' );
                        if ( typeof id === 'undefined' || id === null ) {
-                               id = generateId();
+                               id = user.generateRandomSessionId();
                        }
                        // Set cookie if not set, or renew it if already set
                        $.cookie( 'mediaWiki.user.id', id, {
index 9b2faa8..cb7dd63 100644 (file)
@@ -1,10 +1,11 @@
-/**
- * Implements mediaWiki.util library
- */
 ( function ( mw, $ ) {
        'use strict';
 
-       // Local cache and alias
+       /**
+        * Utility library
+        * @class mw.util
+        * @singleton
+        */
        var util = {
 
                /**
                /**
                 * Encode the string like PHP's rawurlencode
                 *
-                * @param str string String to be encoded
+                * @param {string} str String to be encoded.
                 */
                rawurlencode: function ( str ) {
                        str = String( str );
                 * We want / and : to be included as literal characters in our title URLs
                 * as they otherwise fatally break the title
                 *
-                * @param str string String to be encoded
+                * @param {string} str String to be encoded.
                 */
                wikiUrlencode: function ( str ) {
                        return util.rawurlencode( str )
                },
 
                /**
-                * Get the link to a page name (relative to wgServer)
+                * Get the link to a page name (relative to `wgServer`),
                 *
-                * @param str String: Page name to get the link for.
-                * @return String: Location for a page with name of 'str' or boolean false on error.
+                * @param {string} str Page name to get the link for.
+                * @return {string} Location for a page with name of `str` or boolean false on error.
                 */
                wikiGetlink: function ( str ) {
                        return mw.config.get( 'wgArticlePath' ).replace( '$1',
 
                /**
                 * Get address to a script in the wiki root.
-                * For index.php use mw.config.get( 'wgScript' )
+                * For index.php use `mw.config.get( 'wgScript' )`.
                 *
                 * @since 1.18
                 * @param str string Name of script (eg. 'api'), defaults to 'index'
 
                /**
                 * Append a new style block to the head and return the CSSStyleSheet object.
-                * Use .ownerNode to access the <style> element, or use mw.loader.addStyleTag.
+                * Use .ownerNode to access the `<style>` element, or use mw.loader#addStyleTag.
                 * This function returns the styleSheet object for convience (due to cross-browsers
                 * difference as to where it is located).
-                * @example
-                * <code>
-                * var sheet = mw.util.addCSS('.foobar { display: none; }');
-                * $(foo).click(function () {
-                *     // Toggle the sheet on and off
-                *     sheet.disabled = !sheet.disabled;
-                * });
-                * </code>
                 *
-                * @param text string CSS to be appended
-                * @return CSSStyleSheet (use .ownerNode to get to the <style> element)
+                *     var sheet = mw.util.addCSS('.foobar { display: none; }');
+                *     $(foo).click(function () {
+                *         // Toggle the sheet on and off
+                *         sheet.disabled = !sheet.disabled;
+                *     });
+                *
+                * @param {string} text CSS to be appended
+                * @return {CSSStyleSheet} Use .ownerNode to get to the `<style>` element.
                 */
                addCSS: function ( text ) {
                        var s = mw.loader.addStyleTag( text );
                /**
                 * Hide/show the table of contents element
                 *
-                * @param $toggleLink jQuery A jQuery object of the toggle link.
-                * @param callback function Function to be called after the toggle is
-                * completed (including the animation) (optional)
-                * @return mixed Boolean visibility of the toc (true if it's visible)
+                * @param {jQuery} $toggleLink A jQuery object of the toggle link.
+                * @param {Function} [callback] Function to be called after the toggle is
+                *  completed (including the animation).
+                * @return {Mixed} Boolean visibility of the toc (true if it's visible)
                 * or Null if there was no table of contents.
                 */
                toggleToc: function ( $toggleLink, callback ) {
                 * Grab the URL parameter value for the given parameter.
                 * Returns null if not found.
                 *
-                * @param param string The parameter name.
-                * @param url string URL to search through (optional)
-                * @return mixed Parameter value or null.
+                * @param {string} param The parameter name.
+                * @param {string} [url] URL to search through.
+                * @return {Mixed} Parameter value or null.
                 */
                getParamValue: function ( param, url ) {
                        if ( url === undefined ) {
                },
 
                /**
-                * @var string
+                * @property {string}
                 * Access key prefix. Will be re-defined based on browser/operating system
-                * detection in mw.util.init().
+                * detection in mw.util#init.
                 */
                tooltipAccessKeyPrefix: 'alt-',
 
                /**
-                * @var RegExp
+                * @property {RegExp}
                 * Regex to match accesskey tooltips.
                 */
                tooltipAccessKeyRegexp: /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/,
                 * otherwise, all the nodes that will probably have accesskeys by
                 * default are updated.
                 *
-                * @param $nodes {Array|jQuery} [optional] A jQuery object, or array
-                * of elements to update.
+                * @param {Array|jQuery} [$nodes] A jQuery object, or array of nodes to update.
                 */
                updateTooltipAccessKeys: function ( $nodes ) {
                        if ( !$nodes ) {
                },
 
                /*
-                * @var jQuery
-                * A jQuery object that refers to the content area element
-                * Populated by init().
+                * @property {jQuery}
+                * A jQuery object that refers to the content area element.
+                * Populated by #init.
                 */
                $content: null,
 
                 *
                 * By default the new link will be added to the end of the list. To
                 * add the link before a given existing item, pass the DOM node
-                * (document.getElementById( 'foobar' )) or the jQuery-selector
-                * ( '#foobar' ) of that item.
+                * (e.g. `document.getElementById( 'foobar' )`) or a jQuery-selector
+                * (e.g. `'#foobar'`) for that item.
                 *
-                * @example mw.util.addPortletLink(
-                *       'p-tb', 'http://mediawiki.org/',
-                *       'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', '#t-print'
-                * )
+                *     mw.util.addPortletLink(
+                *         'p-tb', 'http://mediawiki.org/',
+                *         'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', '#t-print'
+                *     );
                 *
-                * @param portlet string ID of the target portlet ( 'p-cactions' or 'p-personal' etc.)
-                * @param href string Link URL
-                * @param text string Link text
-                * @param id string ID of the new item, should be unique and preferably have
-                * the appropriate prefix ( 'ca-', 'pt-', 'n-' or 't-' )
-                * @param tooltip string Text to show when hovering over the link, without accesskey suffix
-                * @param accesskey string Access key to activate this link (one character, try
-                * to avoid conflicts. Use $( '[accesskey=x]' ).get() in the console to
-                * see if 'x' is already used.
-                * @param nextnode mixed DOM Node or jQuery-selector string of the item that the new
-                * item should be added before, should be another item in the same
-                * list, it will be ignored otherwise
+                * @param {string} portlet ID of the target portlet ( 'p-cactions' or 'p-personal' etc.)
+                * @param {string} href Link URL
+                * @param {string} text Link text
+                * @param {string} [id] ID of the new item, should be unique and preferably have
+                *  the appropriate prefix ( 'ca-', 'pt-', 'n-' or 't-' )
+                * @param {string} [tooltip] Text to show when hovering over the link, without accesskey suffix
+                * @param {string} [accesskey] Access key to activate this link (one character, try
+                *  to avoid conflicts. Use `$( '[accesskey=x]' ).get()` in the console to
+                *  see if 'x' is already used.
+                * @param {HTMLElement|jQuery|string} [nextnode] Element or jQuery-selector string to the item that
+                *  the new item should be added before, should be another item in the same
+                *  list, it will be ignored otherwise
                 *
-                * @return mixed The DOM Node of the added item (a ListItem or Anchor element,
+                * @return {HTMLElement|null} The added element (a ListItem or Anchor element,
                 * depending on the skin) or null if no element was added to the document.
                 */
                addPortletLink: function ( portlet, href, text, id, tooltip, accesskey, nextnode ) {
                 * something, replacing any previous message.
                 * Calling with no arguments, with an empty string or null will hide the message
                 *
-                * @param message {mixed} The DOM-element, jQuery object or HTML-string to be put inside the message box.
+                * @param {Mixed} message The DOM-element, jQuery object or HTML-string to be put inside the message box.
                 * to allow CSS/JS to hide different boxes. null = no class used.
-                * @depreceated Use mw.notify
+                * @deprecated Use mw#notify
                 */
                jsMessage: function ( message ) {
                        if ( !arguments.length || message === '' || message === null ) {
                 * according to HTML5 specification. Please note the specification
                 * does not validate a domain with one character.
                 *
-                * @todo FIXME: should be moved to or replaced by a JavaScript validation module.
+                * FIXME: should be moved to or replaced by a validation module.
                 *
-                * @param mailtxt string E-mail address to be validated.
-                * @return mixed Null if mailtxt was an empty string, otherwise true/false
-                * is determined by validation.
+                * @param {string} mailtxt E-mail address to be validated.
+                * @return {boolean|null} Null if `mailtxt` was an empty string, otherwise true/false
+                * as determined by validation.
                 */
                validateEmail: function ( mailtxt ) {
                        var rfc5322Atext, rfc1034LdhStr, html5EmailRegexp;
                                return null;
                        }
 
-                       /**
-                        * HTML5 defines a string as valid e-mail address if it matches
-                        * the ABNF:
-                        *      1 * ( atext / "." ) "@" ldh-str 1*( "." ldh-str )
-                        * With:
-                        * - 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):
-                        */
-
-                       /**
-                        * First, define the RFC 5322 'atext' which is pretty easy:
-                        * atext = ALPHA / DIGIT / ; Printable US-ASCII
-                                                "!" / "#" /     ; characters not including
-                                                "$" / "%" /     ; specials. Used for atoms.
-                                                "&" / "'" /
-                                                "*" / "+" /
-                                                "-" / "/" /
-                                                "=" / "?" /
-                                                "^" / "_" /
-                                                "`" / "{" /
-                                                "|" / "}" /
-                                                "~"
-                       */
+                       // HTML5 defines a string as valid e-mail address if it matches
+                       // the ABNF:
+                       //      1 * ( atext / "." ) "@" ldh-str 1*( "." ldh-str )
+                       // With:
+                       // - 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)
+                       // First, define the RFC 5322 'atext' which is pretty easy:
+                       // atext = ALPHA / DIGIT / ; Printable US-ASCII
+                       //     "!" / "#" /    ; characters not including
+                       //     "$" / "%" /    ; specials. Used for atoms.
+                       //     "&" / "'" /
+                       //     "*" / "+" /
+                       //     "-" / "/" /
+                       //     "=" / "?" /
+                       //     "^" / "_" /
+                       //     "`" / "{" /
+                       //     "|" / "}" /
+                       //     "~"
                        rfc5322Atext = 'a-z0-9!#$%&\'*+\\-/=?^_`{|}~';
 
-                       /**
-                        * Next define the RFC 1034 'ldh-str'
-                        *      <domain> ::= <subdomain> | " "
-                        *      <subdomain> ::= <label> | <subdomain> "." <label>
-                        *      <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
-                        *      <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
-                        *      <let-dig-hyp> ::= <let-dig> | "-"
-                        *      <let-dig> ::= <letter> | <digit>
-                        */
+                       // Next define the RFC 1034 'ldh-str'
+                       //      <domain> ::= <subdomain> | " "
+                       //      <subdomain> ::= <label> | <subdomain> "." <label>
+                       //      <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+                       //      <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+                       //      <let-dig-hyp> ::= <let-dig> | "-"
+                       //      <let-dig> ::= <letter> | <digit>
                        rfc1034LdhStr = 'a-z0-9\\-';
 
                        html5EmailRegexp = new RegExp(
                /**
                 * Note: borrows from IP::isIPv4
                 *
-                * @param address string
-                * @param allowBlock boolean
-                * @return boolean
+                * @param {string} address
+                * @param {boolean} allowBlock
+                * @return {boolean}
                 */
                isIPv4Address: function ( address, allowBlock ) {
                        if ( typeof address !== 'string' ) {
                /**
                 * Note: borrows from IP::isIPv6
                 *
-                * @param address string
-                * @param allowBlock boolean
-                * @return boolean
+                * @param {string} address
+                * @param {boolean} allowBlock
+                * @return {boolean}
                 */
                isIPv6Address: function ( address, allowBlock ) {
                        if ( typeof address !== 'string' ) {
index 0be614a..09aec79 100644 (file)
@@ -93,4 +93,3 @@ function unixLineEndings( $var ) {
        }
        return $var;
 }
-
index c4349c6..ee68abb 100644 (file)
@@ -230,7 +230,7 @@ class VectorTemplate extends BaseTemplate {
                <div id="mw-navigation">
                        <h2><?php $this->msg( 'navigation-heading' ) ?></h2>
                        <!-- header -->
-                       <div id="mw-head" class="noprint">
+                       <div id="mw-head">
                                <?php $this->renderNavigation( 'PERSONAL' ); ?>
                                <div id="left-navigation">
                                        <?php $this->renderNavigation( array( 'NAMESPACES', 'VARIANTS' ) ); ?>
@@ -241,7 +241,7 @@ class VectorTemplate extends BaseTemplate {
                        </div>
                        <!-- /header -->
                        <!-- panel -->
-                       <div id="mw-panel" class="noprint">
+                       <div id="mw-panel">
                                <!-- logo -->
                                        <div id="p-logo" role="banner"><a style="background-image: url(<?php $this->text( 'logopath' ) ?>);" href="<?php echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] ) ?>" <?php echo Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ) ?>></a></div>
                                <!-- /logo -->
index 34d3357..1fe750e 100644 (file)
@@ -313,6 +313,11 @@ input#wpSummary {
        padding-left: 0.25em;
        border-left: none;
 }
+
+/* (bug 5346) make category redirects italic */
+.catlinks li a.mw-redirect {
+       font-style: italic;
+}
 /**
  * Hidden categories
  */
@@ -826,6 +831,7 @@ div.gallerytext {
 
 /* Language specific height correction for titles. Ref Bug 29405 and Bug 30809 */
 /* Languages like hi or ml require slightly more vertical space to show diacritics properly */
+h1:lang(anp),
 h1:lang(as),
 h1:lang(bh), /* Macrolanguage, used on bh.wikipedia.org, should be removed one day */
 h1:lang(bho),
@@ -833,16 +839,22 @@ h1:lang(bn),
 h1:lang(gu),
 h1:lang(hi),
 h1:lang(kn),
+h1:lang(ks),
 h1:lang(ml),
 h1:lang(mr),
 h1:lang(my),
+h1:lang(mai),
+h1:lang(ne),
+h1:lang(new),
 h1:lang(or),
 h1:lang(pa),
+h1:lang(pi),
 h1:lang(sa),
 h1:lang(ta),
 h1:lang(te) {
        line-height: 1.6em !important;
 }
+h2:lang(anp), h3:lang(anp), h4:lang(anp), h5:lang(anp), h6:lang(anp),
 h2:lang(as), h3:lang(as), h4:lang(as), h5:lang(as), h6:lang(as),
 h2:lang(bho), h3:lang(bho), h4:lang(bho), h5:lang(bho), h6:lang(bho),
 h2:lang(bh), h3:lang(bh), h4:lang(bh), h5:lang(bh), h6:lang(bh),
@@ -850,11 +862,16 @@ h2:lang(bn), h3:lang(bn), h4:lang(bn), h5:lang(bn), h6:lang(bn),
 h2:lang(gu), h3:lang(gu), h4:lang(gu), h5:lang(gu), h6:lang(gu),
 h2:lang(hi), h3:lang(hi), h4:lang(hi), h5:lang(hi), h6:lang(hi),
 h2:lang(kn), h3:lang(kn), h4:lang(kn), h5:lang(kn), h6:lang(kn),
+h2:lang(ks), h3:lang(ks), h4:lang(ks), h5:lang(ks), h6:lang(ks),
 h2:lang(ml), h3:lang(ml), h4:lang(ml), h5:lang(ml), h6:lang(ml),
 h2:lang(mr), h3:lang(mr), h4:lang(mr), h5:lang(mr), h6:lang(mr),
 h2:lang(my), h3:lang(my), h4:lang(my), h5:lang(my), h6:lang(my),
+h2:lang(mai), h3:lang(mai), h4:lang(mai), h5:lang(mai), h6:lang(mai),
+h2:lang(ne), h3:lang(ne), h4:lang(ne), h5:lang(ne), h6:lang(ne),
+h2:lang(new), h3:lang(new), h4:lang(new), h5:lang(new), h6:lang(new),
 h2:lang(or), h3:lang(or), h4:lang(or), h5:lang(or), h6:lang(or),
 h2:lang(pa), h3:lang(pa), h4:lang(pa), h5:lang(pa), h6:lang(pa),
+h2:lang(pi), h3:lang(pi), h4:lang(pi), h5:lang(pi), h6:lang(pi),
 h2:lang(sa), h3:lang(sa), h4:lang(sa), h5:lang(sa), h6:lang(sa),
 h2:lang(ta), h3:lang(ta), h4:lang(ta), h5:lang(ta), h6:lang(ta),
 h2:lang(te), h3:lang(te), h4:lang(te), h5:lang(te), h6:lang(te) {
@@ -1068,8 +1085,8 @@ table.floatleft {
 }
 
 .editsection, .toctoggle {
-    -moz-user-select: none;
-    -webkit-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
+       -moz-user-select: none;
+       -webkit-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
 }
diff --git a/skins/vector/images/border.png b/skins/vector/images/border.png
deleted file mode 100644 (file)
index f9ca8cc..0000000
Binary files a/skins/vector/images/border.png and /dev/null differ
diff --git a/skins/vector/images/page-base.png b/skins/vector/images/page-base.png
deleted file mode 100644 (file)
index b3ecd30..0000000
Binary files a/skins/vector/images/page-base.png and /dev/null differ
diff --git a/skins/vector/images/preferences-base.png b/skins/vector/images/preferences-base.png
deleted file mode 100644 (file)
index 8e0082b..0000000
Binary files a/skins/vector/images/preferences-base.png and /dev/null differ
diff --git a/skins/vector/images/preferences-edge.png b/skins/vector/images/preferences-edge.png
deleted file mode 100644 (file)
index 411a1aa..0000000
Binary files a/skins/vector/images/preferences-edge.png and /dev/null differ
index 26967a5..2e09ee1 100644 (file)
@@ -21,18 +21,17 @@ body {
        font-size: 1em;
 }
 body {
-       background-color: #f3f3f3;
-       /* @embed */
-       background-image: url(images/page-base.png);
+       background-color: #f6f6f6;
 }
 /* Content */
 div#content {
        margin-left: 10em;
        padding: 1em;
-       /* @embed */
-       background-image: url(images/border.png);
-       background-position: top left;
-       background-repeat: repeat-y;
+       /* Border on top, left, and bottom side */
+       border: 1px solid #a7d7f9;
+       border-right-width: 0;
+       /* Merge the border with tabs' one (in their background image) */
+       margin-top: -1px;
        background-color: white;
        color: black;
        direction: ltr;
@@ -55,10 +54,6 @@ div#content {
        margin-top: -5em;
        margin-left: 10em;
        height: 5em;
-       /* @embed */
-       background-image: url(images/border.png);
-       background-position: bottom left;
-       background-repeat: repeat-x;
 }
 div#mw-head {
        position: absolute;
@@ -528,10 +523,6 @@ div#footer {
        margin-left: 10em;
        margin-top: 0;
        padding: 0.75em;
-       /* @embed */
-       background-image: url(images/border.png);
-       background-position: top left;
-       background-repeat: repeat-x;
        direction: ltr;
 }
 div#footer ul {
@@ -654,9 +645,7 @@ div#footer #footer-places li {
        margin-top: -2px;
        clear: both;
        border: solid 1px #ccc;
-       background-color: #f9f9f9;
-       /* @embed */
-       background-image: url(images/preferences-base.png);
+       background-color: #fafafa;
 }
 #preferences fieldset {
        border: none;
index 28501ea..716a8db 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * @file
  * @ingroup Maintenance
- * @copyright Copyright Â© Wikimedia Deuschland, 2009
+ * @copyright Copyright © Wikimedia Deuschland, 2009
  * @author Hallo Welt! Medienwerkstatt GmbH
  * @author Markus Glaser, Dan Nessett, Priyanka Dhanda
  * initial idea by Daniel Kinzler
@@ -32,7 +32,7 @@ define( 'SELENIUMTEST', true );
 require( __DIR__ . '/../maintenance/Maintenance.php' );
 
 require_once( 'PHPUnit/Runner/Version.php' );
-if( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) {
+if ( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) {
        # PHPUnit 3.5.0 introduced a nice autoloader based on class name
        require_once( 'PHPUnit/Autoload.php' );
 } else {
@@ -75,7 +75,7 @@ class SeleniumTester extends Maintenance {
        public function listBrowsers() {
                $desc = "Available browsers:\n";
 
-               foreach ($this->selenium->getAvailableBrowsers() as $k => $v) {
+               foreach ( $this->selenium->getAvailableBrowsers() as $k => $v ) {
                        $desc .= "  $k => $v\n";
                }
 
@@ -85,8 +85,8 @@ class SeleniumTester extends Maintenance {
        protected function startServer() {
                if ( $this->seleniumServerExecPath == '' ) {
                        die ( "The selenium server exec path is not set in " .
-                                 "selenium_settings.ini. Cannot start server \n" .
-                                 "as requested - terminating RunSeleniumTests\n" );
+                               "selenium_settings.ini. Cannot start server \n" .
+                               "as requested - terminating RunSeleniumTests\n" );
                }
                $this->serverManager = new SeleniumServerManager( 'true',
                        $this->selenium->getPort(),
@@ -159,20 +159,20 @@ class SeleniumTester extends Maintenance {
 
                $configFile = $this->getOption( 'seleniumConfig', '' );
                if ( strlen( $configFile ) > 0 ) {
-                       $this->output("Using Selenium Configuration file: " . $configFile . "\n");
+                       $this->output( "Using Selenium Configuration file: " . $configFile . "\n" );
                        SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                                $seleniumBrowsers,
                                $seleniumTestSuites,
                                $configFile );
                } elseif ( !isset( $wgHooks['SeleniumSettings'] ) ) {
-                       $this->output("No command line, configuration file or configuration hook found.\n");
+                       $this->output( "No command line, configuration file or configuration hook found.\n" );
                        SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                                $seleniumBrowsers,
                                $seleniumTestSuites
-                                                                                                       );
+                       );
                } else {
-                       $this->output("Using 'SeleniumSettings' hook for configuration.\n");
-                       wfRunHooks('SeleniumSettings', array( $seleniumSettings,
+                       $this->output( "Using 'SeleniumSettings' hook for configuration.\n" );
+                       wfRunHooks( 'SeleniumSettings', array( $seleniumSettings,
                                $seleniumBrowsers,
                                $seleniumTestSuites ) );
                }
@@ -180,24 +180,48 @@ class SeleniumTester extends Maintenance {
                // State for starting/stopping the Selenium server has nothing to do with the Selenium
                // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but
                // the Maintenance class does not have a setOption()
-               if ( ! isset( $seleniumSettings['startserver'] ) ) $this->getOption( 'startserver', true );
-               if ( ! isset( $seleniumSettings['stopserver'] ) ) $this->getOption( 'stopserver', true );
-               if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) $seleniumSettings['seleniumserverexecpath'] = '';
+               if ( !isset( $seleniumSettings['startserver'] ) ) {
+                       $this->getOption( 'startserver', true );
+               }
+               if ( !isset( $seleniumSettings['stopserver'] ) ) {
+                       $this->getOption( 'stopserver', true );
+               }
+               if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) {
+                       $seleniumSettings['seleniumserverexecpath'] = '';
+               }
                $this->seleniumServerExecPath = $seleniumSettings['seleniumserverexecpath'];
 
                //set reasonable defaults if we did not find the settings
-               if ( !isset( $seleniumBrowsers ) ) $seleniumBrowsers = array ('firefox' => '*firefox');
-               if ( !isset( $seleniumSettings['host'] ) ) $seleniumSettings['host'] = $wgServer . $wgScriptPath;
-               if ( !isset( $seleniumSettings['port'] ) ) $seleniumSettings['port'] = '4444';
-               if ( !isset( $seleniumSettings['wikiUrl'] ) ) $seleniumSettings['wikiUrl'] = 'http://localhost';
-               if ( !isset( $seleniumSettings['username'] ) ) $seleniumSettings['username'] = '';
-               if ( !isset( $seleniumSettings['userPassword'] ) ) $seleniumSettings['userPassword'] = '';
-               if ( !isset( $seleniumSettings['testBrowser'] ) ) $seleniumSettings['testBrowser'] = 'firefox';
-               if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) $seleniumSettings['jUnitLogFile'] = false;
-               if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) $seleniumSettings['runAgainstGrid'] = false;
+               if ( !isset( $seleniumBrowsers ) ) {
+                       $seleniumBrowsers = array( 'firefox' => '*firefox' );
+               }
+               if ( !isset( $seleniumSettings['host'] ) ) {
+                       $seleniumSettings['host'] = $wgServer . $wgScriptPath;
+               }
+               if ( !isset( $seleniumSettings['port'] ) ) {
+                       $seleniumSettings['port'] = '4444';
+               }
+               if ( !isset( $seleniumSettings['wikiUrl'] ) ) {
+                       $seleniumSettings['wikiUrl'] = 'http://localhost';
+               }
+               if ( !isset( $seleniumSettings['username'] ) ) {
+                       $seleniumSettings['username'] = '';
+               }
+               if ( !isset( $seleniumSettings['userPassword'] ) ) {
+                       $seleniumSettings['userPassword'] = '';
+               }
+               if ( !isset( $seleniumSettings['testBrowser'] ) ) {
+                       $seleniumSettings['testBrowser'] = 'firefox';
+               }
+               if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) {
+                       $seleniumSettings['jUnitLogFile'] = false;
+               }
+               if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) {
+                       $seleniumSettings['runAgainstGrid'] = false;
+               }
 
                // Setup Selenium class
-               $this->selenium = new Selenium( );
+               $this->selenium = new Selenium();
                $this->selenium->setAvailableBrowsers( $seleniumBrowsers );
                $this->selenium->setRunAgainstGrid( $this->getOption( 'runAgainstGrid', $seleniumSettings['runAgainstGrid'] ) );
                $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) );
@@ -209,9 +233,9 @@ class SeleniumTester extends Maintenance {
                $this->selenium->setVerbose( $this->hasOption( 'verbose' ) );
                $this->selenium->setJUnitLogFile( $this->getOption( 'jUnitLogFile', $seleniumSettings['jUnitLogFile'] ) );
 
-               if( $this->hasOption( 'list-browsers' ) ) {
+               if ( $this->hasOption( 'list-browsers' ) ) {
                        $this->listBrowsers();
-                       exit(0);
+                       exit( 0 );
                }
                if ( $this->hasOption( 'startserver' ) ) {
                        $this->startServer();
@@ -222,7 +246,7 @@ class SeleniumTester extends Maintenance {
 
                $this->runTests( $seleniumTestSuites );
 
-               if ( $this->hasOption( 'stopserver' )  ) {
+               if ( $this->hasOption( 'stopserver' ) ) {
                        $this->stopServer();
                }
        }
index 8373b51..264ba69 100644 (file)
@@ -77,7 +77,7 @@ $wgAutoloadClasses += array(
        'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php",
 
        # tests/phpunit/includes/site
-       'SiteObjectTest' => "$testDir/phpunit/includes/site/SiteObjectTest.php",
+       'SiteTest' => "$testDir/phpunit/includes/site/SiteTest.php",
        'TestSites' => "$testDir/phpunit/includes/site/TestSites.php",
 
        # tests/phpunit/languages
@@ -101,4 +101,3 @@ $wgAutoloadClasses += array(
        'SeleniumTestSuite' => "$testDir/selenium/SeleniumTestSuite.php",
        'SeleniumConfig' => "$testDir/selenium/SeleniumConfig.php",
 );
-
index ea1b290..aa56e6e 100644 (file)
@@ -74,6 +74,7 @@ class ParserTest {
 
        public $regex = "";
        private $savedGlobals = array();
+
        /**
         * Sets terminal colorization and diff/quick modes depending on OS and
         * command-line options (--color and --quick).
@@ -83,14 +84,14 @@ class ParserTest {
                $this->color = !wfIsWindows() && Maintenance::posix_isatty( 1 );
 
                if ( isset( $options['color'] ) ) {
-                       switch( $options['color'] ) {
-                       case 'no':
-                               $this->color = false;
-                               break;
-                       case 'yes':
-                       default:
-                               $this->color = true;
-                               break;
+                       switch ( $options['color'] ) {
+                               case 'no':
+                                       $this->color = false;
+                                       break;
+                               case 'yes':
+                               default:
+                                       $this->color = true;
+                                       break;
                        }
                }
 
@@ -102,7 +103,7 @@ class ParserTest {
                $this->showProgress = !isset( $options['quiet'] );
                $this->showFailure = !(
                        isset( $options['quiet'] )
-                       && ( isset( $options['record'] )
+                               && ( isset( $options['record'] )
                                || isset( $options['compare'] ) ) ); // redundant output
 
                $this->showOutput = isset( $options['show-output'] );
@@ -152,23 +153,26 @@ class ParserTest {
                $wgExtensionAssetsPath = '/extensions';
                $wgThumbnailScriptPath = false;
                $wgLockManagers = array( array(
-                       'name'          => 'fsLockManager',
-                       'class'         => 'FSLockManager',
+                       'name' => 'fsLockManager',
+                       'class' => 'FSLockManager',
                        'lockDirectory' => wfTempDir() . '/test-repo/lockdir',
+               ), array(
+                       'name' => 'nullLockManager',
+                       'class' => 'NullLockManager',
                ) );
                $wgLocalFileRepo = array(
-                       'class'           => 'LocalRepo',
-                       'name'            => 'local',
-                       'url'             => 'http://example.com/images',
-                       'hashLevels'      => 2,
+                       'class' => 'LocalRepo',
+                       'name' => 'local',
+                       'url' => 'http://example.com/images',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'local-backend',
                                'lockManager' => 'fsLockManager',
                                'containerPaths' => array(
-                                       'local-public'  => wfTempDir() . '/test-repo/public',
-                                       'local-thumb'   => wfTempDir() . '/test-repo/thumb',
-                                       'local-temp'    => wfTempDir() . '/test-repo/temp',
+                                       'local-public' => wfTempDir() . '/test-repo/public',
+                                       'local-thumb' => wfTempDir() . '/test-repo/thumb',
+                                       'local-temp' => wfTempDir() . '/test-repo/temp',
                                        'local-deleted' => wfTempDir() . '/test-repo/deleted',
                                )
                        ) )
@@ -203,16 +207,16 @@ class ParserTest {
                $wgRequest = $context->getRequest();
 
                if ( $wgStyleDirectory === false ) {
-                       $wgStyleDirectory   = "$IP/skins";
+                       $wgStyleDirectory = "$IP/skins";
                }
 
        }
 
-       public function setupRecorder ( $options ) {
+       public function setupRecorder( $options ) {
                if ( isset( $options['record'] ) ) {
                        $this->recorder = new DbTestRecorder( $this );
                        $this->recorder->version = isset( $options['setversion'] ) ?
-                                       $options['setversion'] : SpecialVersion::getVersion();
+                               $options['setversion'] : SpecialVersion::getVersion();
                } elseif ( isset( $options['compare'] ) ) {
                        $this->recorder = new DbTestPreviewer( $this );
                } else {
@@ -224,11 +228,10 @@ class ParserTest {
         * Remove last character if it is a newline
         * @group utility
         */
-       static public function chomp( $s ) {
+       public static function chomp( $s ) {
                if ( substr( $s, -1 ) === "\n" ) {
                        return substr( $s, 0, -1 );
-               }
-               else {
+               } else {
                        return $s;
                }
        }
@@ -387,7 +390,7 @@ class ParserTest {
 
                        $this->teardownDatabase();
                        $this->recorder->report();
-               } catch (DBError $e) {
+               } catch ( DBError $e ) {
                        echo $e->getMessage();
                }
                $this->recorder->end();
@@ -460,8 +463,7 @@ class ParserTest {
 
                if ( isset( $opts['title'] ) ) {
                        $titleText = $opts['title'];
-               }
-               else {
+               } else {
                        $titleText = 'Parser test';
                }
 
@@ -634,24 +636,27 @@ class ParserTest {
                        'wgScriptPath' => '/',
                        'wgArticlePath' => '/wiki/$1',
                        'wgActionPaths' => array(),
-                       'wgLockManagers' => array(
-                               'name'          => 'fsLockManager',
-                               'class'         => 'FSLockManager',
+                       'wgLockManagers' => array( array(
+                               'name' => 'fsLockManager',
+                               'class' => 'FSLockManager',
                                'lockDirectory' => $this->uploadDir . '/lockdir',
-                       ),
+                       ), array(
+                               'name' => 'nullLockManager',
+                               'class' => 'NullLockManager',
+                       ) ),
                        'wgLocalFileRepo' => array(
                                'class' => 'LocalRepo',
                                'name' => 'local',
                                'url' => 'http://example.com/images',
                                'hashLevels' => 2,
                                'transformVia404' => false,
-                               'backend'         => new FSFileBackend( array(
-                                       'name'        => 'local-backend',
+                               'backend' => new FSFileBackend( array(
+                                       'name' => 'local-backend',
                                        'lockManager' => 'fsLockManager',
                                        'containerPaths' => array(
-                                               'local-public'  => $this->uploadDir,
-                                               'local-thumb'   => $this->uploadDir . '/thumb',
-                                               'local-temp'    => $this->uploadDir . '/temp',
+                                               'local-public' => $this->uploadDir,
+                                               'local-thumb' => $this->uploadDir . '/thumb',
+                                               'local-temp' => $this->uploadDir . '/temp',
                                                'local-deleted' => $this->uploadDir . '/delete',
                                        )
                                ) )
@@ -679,10 +684,10 @@ class ParserTest {
                        'wgVariantArticlePath' => false,
                        'wgGroupPermissions' => array( '*' => array(
                                'createaccount' => true,
-                               'read'          => true,
-                               'edit'          => true,
-                               'createpage'    => true,
-                               'createtalk'    => true,
+                               'read' => true,
+                               'edit' => true,
+                               'createpage' => true,
+                               'createtalk' => true,
                        ) ),
                        'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ),
                        'wgDefaultExternalStore' => array(),
@@ -749,7 +754,7 @@ class ParserTest {
                $tables = array( 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions',
                        'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks',
                        'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks',
-                       'site_stats', 'hitcounter',     'ipblocks', 'image', 'oldimage',
+                       'site_stats', 'hitcounter', 'ipblocks', 'image', 'oldimage',
                        'recentchanges', 'watchlist', 'interwiki', 'logging',
                        'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
                        'archive', 'user_groups', 'page_props', 'category', 'msg_resource', 'msg_resource_links'
@@ -812,44 +817,44 @@ class ParserTest {
 
                        # Anonymous user
                        $this->db->insert( 'user', array(
-                               'user_id'         => 0,
-                               'user_name'       => 'Anonymous' ) );
+                               'user_id' => 0,
+                               'user_name' => 'Anonymous' ) );
                }
 
                # Hack: insert a few Wikipedia in-project interwiki prefixes,
                # for testing inter-language links
                $this->db->insert( 'interwiki', array(
                        array( 'iw_prefix' => 'wikipedia',
-                                  'iw_url'    => 'http://en.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
+                               'iw_url' => 'http://en.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 0 ),
                        array( 'iw_prefix' => 'meatball',
-                                  'iw_url'    => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
+                               'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 0 ),
                        array( 'iw_prefix' => 'zh',
-                                  'iw_url'    => 'http://zh.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
+                               'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
                        array( 'iw_prefix' => 'es',
-                                  'iw_url'    => 'http://es.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
+                               'iw_url' => 'http://es.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
                        array( 'iw_prefix' => 'fr',
-                                  'iw_url'    => 'http://fr.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
+                               'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
                        array( 'iw_prefix' => 'ru',
-                                  'iw_url'    => 'http://ru.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       ) );
+                               'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
+               ) );
 
                # Update certain things in site_stats
                $this->db->insert( 'site_stats', array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ) );
@@ -864,30 +869,30 @@ class ParserTest {
                $user = User::createNew( 'WikiSysop' );
                $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
                $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', array(
-                       'size'        => 12345,
-                       'width'       => 1941,
-                       'height'      => 220,
-                       'bits'        => 24,
-                       'media_type'  => MEDIATYPE_BITMAP,
-                       'mime'        => 'image/jpeg',
-                       'metadata'    => serialize( array() ),
-                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                       'fileExists'  => true
-                       ), $this->db->timestamp( '20010115123500' ), $user );
+                       'size' => 12345,
+                       'width' => 1941,
+                       'height' => 220,
+                       'bits' => 24,
+                       'media_type' => MEDIATYPE_BITMAP,
+                       'mime' => 'image/jpeg',
+                       'metadata' => serialize( array() ),
+                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                       'fileExists' => true
+               ), $this->db->timestamp( '20010115123500' ), $user );
 
                # This image will be blacklisted in [[MediaWiki:Bad image list]]
                $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) );
                $image->recordUpload2( '', 'zomgnotcensored', 'Borderline image', array(
-                       'size'        => 12345,
-                       'width'       => 320,
-                       'height'      => 240,
-                       'bits'        => 24,
-                       'media_type'  => MEDIATYPE_BITMAP,
-                       'mime'        => 'image/jpeg',
-                       'metadata'    => serialize( array() ),
-                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                       'fileExists'  => true
-                       ), $this->db->timestamp( '20010115123500' ), $user );
+                       'size' => 12345,
+                       'width' => 320,
+                       'height' => 240,
+                       'bits' => 24,
+                       'media_type' => MEDIATYPE_BITMAP,
+                       'mime' => 'image/jpeg',
+                       'metadata' => serialize( array() ),
+                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                       'fileExists' => true
+               ), $this->db->timestamp( '20010115123500' ), $user );
        }
 
        public function teardownDatabase() {
@@ -901,7 +906,7 @@ class ParserTest {
                $this->databaseSetupDone = false;
 
                if ( $this->useTemporaryTables ) {
-                       if( $this->db->getType() == 'sqlite' ) {
+                       if ( $this->db->getType() == 'sqlite' ) {
                                # Under SQLite the searchindex table is virtual and need
                                # to be explicitly destroyed. See bug 29912
                                # See also MediaWikiTestCase::destroyDB()
@@ -920,8 +925,9 @@ class ParserTest {
                        $this->db->query( $sql );
                }
 
-               if ( $this->db->getType() == 'oracle' )
+               if ( $this->db->getType() == 'oracle' ) {
                        $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
+               }
 
                $this->teardownGlobals();
        }
@@ -966,7 +972,7 @@ class ParserTest {
        private function teardownGlobals() {
                RepoGroup::destroySingleton();
                FileBackendGroup::destroySingleton();
-               LockManagerGroup::destroySingleton();
+               LockManagerGroup::destroySingletons();
                LinkCache::singleton()->clear();
 
                foreach ( $this->savedGlobals as $var => $val ) {
@@ -984,7 +990,7 @@ class ParserTest {
 
                // delete the files first, then the dirs.
                self::deleteFiles(
-                       array (
+                       array(
                                "$dir/3/3a/Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
@@ -1008,7 +1014,7 @@ class ParserTest {
                );
 
                self::deleteDirs(
-                       array (
+                       array(
                                "$dir/3/3a",
                                "$dir/3",
                                "$dir/thumb/6/65",
@@ -1129,8 +1135,8 @@ class ParserTest {
                $outfile = "$prefix-$outFileTail";
                $this->dumpToFile( $output, $outfile );
 
-               $shellInfile = wfEscapeShellArg($infile);
-               $shellOutfile = wfEscapeShellArg($outfile);
+               $shellInfile = wfEscapeShellArg( $infile );
+               $shellOutfile = wfEscapeShellArg( $outfile );
 
                global $wgDiff3;
                // we assume that people with diff3 also have usual diff
@@ -1166,7 +1172,7 @@ class ParserTest {
                return preg_replace(
                        array( '/^(-.*)$/m', '/^(\+.*)$/m' ),
                        array( $this->term->color( 34 ) . '$1' . $this->term->reset(),
-                                  $this->term->color( 31 ) . '$1' . $this->term->reset() ),
+                               $this->term->color( 31 ) . '$1' . $this->term->reset() ),
                        $text );
        }
 
@@ -1189,7 +1195,7 @@ class ParserTest {
         * @param $line Integer: the input line number, for reporting errors
         * @param $ignoreDuplicate Boolean: whether to silently ignore duplicate pages
         */
-       static public function addArticle( $name, $text, $line = 'unknown', $ignoreDuplicate = '' ) {
+       public static function addArticle( $name, $text, $line = 'unknown', $ignoreDuplicate = '' ) {
                global $wgCapitalLinks;
 
                $oldCapitalLinks = $wgCapitalLinks;
@@ -1231,7 +1237,7 @@ class ParserTest {
        public function requireHook( $name ) {
                global $wgParser;
 
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
 
                if ( isset( $wgParser->mTagHooks[$name] ) ) {
                        $this->hooks[$name] = $wgParser->mTagHooks[$name];
@@ -1254,7 +1260,7 @@ class ParserTest {
        public function requireFunctionHook( $name ) {
                global $wgParser;
 
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
 
                if ( isset( $wgParser->mFunctionHooks[$name] ) ) {
                        $this->functionHooks[$name] = $wgParser->mFunctionHooks[$name];
@@ -1286,9 +1292,9 @@ class ParserTest {
        private function wellFormed( $text ) {
                $html =
                        Sanitizer::hackDocType() .
-                       '<html>' .
-                       $text .
-                       '</html>';
+                               '<html>' .
+                               $text .
+                               '</html>';
 
                $parser = xml_parser_create( "UTF-8" );
 
index 78cbf23..df8b9e2 100644 (file)
@@ -162,6 +162,16 @@ baz
 </p>
 !! end
 
+!! test
+Parsing an URL
+!! input
+http://fr.wikipedia.org/wiki/🍺
+<!-- EasterEgg we love beer, better be able be able to link to it -->
+!! result
+<p><a rel="nofollow" class="external free" href="http://fr.wikipedia.org/wiki/🍺">http://fr.wikipedia.org/wiki/🍺</a>
+</p>
+!! end
+
 !! test
 Simple list
 !! input
@@ -549,6 +559,15 @@ nowiki 3
 
 !! end
 
+!! test
+Entities inside <nowiki>
+!! input
+<nowiki>&lt;</nowiki>
+!! result
+<p>&lt;
+</p>
+!! end
+
 
 ###
 ### Comments
@@ -907,6 +926,15 @@ Bug 6200: Preformatted in <blockquote>
 
 !! end
 
+!! test
+Entities inside <pre>
+!! input
+<pre>&lt;</pre>
+!! result
+<pre>&lt;</pre>
+
+!! end
+
 !! test
 <pre> with forbidden attribute values (bug 3202)
 !! input
@@ -4240,6 +4268,25 @@ disabled
 </li></ol>
 !! end
 
+!!test
+List embedded in a non-block tag
+(Ugly Parsoid output -- worth fixing; Disabled for PHP parser since it relies on Tidy)
+!! options
+disabled
+!!input
+<small>
+* foo
+</small>
+!!result
+<p><small></small></p>
+<small>
+<ul>
+<li> foo</li>
+</ul>
+</small>
+<p><small></small></p>
+!!end
+
 !! test
 List items are not parsed correctly following a <pre> block (bug 785)
 !! input
@@ -4729,7 +4776,7 @@ Magic links: RFC (bug 479)
 !! input
 RFC 822
 !! result
-<p><a class="external mw-magiclink-rfc" href="//tools.ietf.org/html/rfc822">RFC 822</a>
+<p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc822">RFC 822</a>
 </p>
 !! end
 
@@ -4747,7 +4794,7 @@ Magic links: PMID incorrectly converts space to underscore
 !! input
 PMID 1234
 !! result
-<p><a class="external mw-magiclink-pmid" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a>
+<p><a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a>
 </p>
 !! end
 
@@ -6907,7 +6954,7 @@ BUG 1887: A RFC with a thumbnail
 !! input
 [[Image:foobar.jpg|thumb|This is RFC 12354]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is <a class="external mw-magiclink-rfc" href="//tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div>
 
 !! end
 
@@ -10517,7 +10564,7 @@ Double RFC
 !! input
 RFC RFC 1234
 !! result
-<p>RFC <a class="external mw-magiclink-rfc" href="//tools.ietf.org/html/rfc1234">RFC 1234</a>
+<p>RFC <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc1234">RFC 1234</a>
 </p>
 !! end
 
@@ -10535,7 +10582,7 @@ RFC code coverage
 !! input
 RFC   983&#x20;987
 !! result
-<p><a class="external mw-magiclink-rfc" href="//tools.ietf.org/html/rfc983">RFC 983</a>&#x20;987
+<p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc983">RFC 983</a>&#x20;987
 </p>
 !! end
 
@@ -10995,6 +11042,22 @@ Both [[Dunav]] and [[Дунав]] are names for this river.
 </p>
 !!end
 
+!! article
+Дуна
+!! text
+content
+!! endarticle
+
+!! test
+Link to another existing title shouldn't be parsed as self-link even if it's a variant of this title
+!! options
+title=[[Duna]] language=sr
+!! input
+[[Дуна]] is not a self-link while [[Duna]] and [[Dуна]] are still self-links.
+!! result
+<p><a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Дуна</a> is not a self-link while <strong class="selflink">Duna</strong> and <strong class="selflink">Dуна</strong> are still self-links.
+</p>
+!! end
 
 !! test
 Link to pages in language variants
@@ -11753,17 +11816,6 @@ Multibyte character in padright
 </p>
 !! end
 
-!! test
-Formatted date
-!! config
-wgUseDynamicDates=1
-!! input
-[[2009-03-24]]
-!! result
-<p><span class="mw-formatted-date" title="2009-03-24"><a href="/index.php?title=2009&amp;action=edit&amp;redlink=1" class="new" title="2009 (page does not exist)">2009</a>-<a href="/index.php?title=March_24&amp;action=edit&amp;redlink=1" class="new" title="March 24 (page does not exist)">03-24</a></span>
-</p>
-!!end
-
 !!test
 formatdate parser function
 !!input
@@ -11782,17 +11834,6 @@ formatdate parser function, with default format
 </p>
 !! end
 
-!! test
-Linked date with autoformatting disabled
-!! config
-wgUseDynamicDates=false
-!! input
-[[2009-03-24]]
-!! result
-<p><a href="/index.php?title=2009-03-24&amp;action=edit&amp;redlink=1" class="new" title="2009-03-24 (page does not exist)">2009-03-24</a>
-</p>
-!! end
-
 !! test
 Spacing of numbers in formatted dates
 !! input
@@ -11802,17 +11843,6 @@ Spacing of numbers in formatted dates
 </p>
 !! end
 
-!! test
-Spacing of numbers in formatted dates (linked)
-!! config
-wgUseDynamicDates=true
-!! input
-[[January 15]]
-!! result
-<p><span class="mw-formatted-date" title="01-15"><a href="/index.php?title=January_15&amp;action=edit&amp;redlink=1" class="new" title="January 15 (page does not exist)">January 15</a></span>
-</p>
-!! end
-
 !! test
 formatdate parser function, with default format and on a page of which the content language is always English and different from the wiki content language
 !! options
@@ -12675,6 +12705,23 @@ File:foobar.jpg|caption|alt=galleryalt|link=" onclick="alert('malicious javascri
 
 !! end
 
+!!test
+Gallery with invalid title as link (bug 43964)
+!! input
+<gallery>
+File:foobar.jpg|link=<
+</gallery>
+!! result
+<ul class="gallery">
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="gallerytext">
+                       </div>
+               </div></li>
+</ul>
+
+!! end
+
 !!test
 Language parser function
 !! input
@@ -13551,6 +13598,120 @@ HTML tag with 'unnecessary' entity encoding in attributes
 </p>
 !! end
 
+!! test
+HTML tag with broken attribute value quoting
+!! input
+<span title="Hello world>Foo</span>
+!! result
+<p><span>Foo</span>
+</p>
+!! end
+
+!! test
+Parsoid-only: HTML tag with broken attribute value quoting
+!! options
+disabled
+!! input
+<span title="Hello world>Foo</span>
+!! result
+<p><span title="Hello world">Foo</span>
+</p>
+!! end
+
+!! test
+Table with broken attribute value quoting
+!! input
+{|
+| title="Hello world|Foo
+|}
+!! result
+<table>
+<tr>
+<td>Foo
+</td></tr></table>
+
+!! end
+
+!! test
+Table with broken attribute value quoting on consecutive lines
+!! input
+{|
+| title="Hello world|Foo
+| style="color:red|Bar
+|}
+!! result
+<table>
+<tr>
+<td>Foo
+</td>
+<td>Bar
+</td></tr></table>
+
+!! end
+
+!! test
+Parsoid-only: Table with broken attribute value quoting on consecutive lines
+!! options
+disabled
+!! input
+{|
+| title="Hello world|Foo
+| style="color:red|Bar
+|}
+!! result
+<table>
+<tr>
+<td title="Hello world">Foo
+</td><td style="color: red;">Bar
+</td></tr></table>
+
+!! end
+
+!!test
+Accept empty td cell attribute
+!!input
+{|
+| align="center" | foo ||  |
+|}
+!!result
+<table>
+<tr>
+<td align="center"> foo </td>
+<td>
+</td></tr></table>
+
+!!end
+
+!!test
+Non-empty attributes in th-cells
+!!input
+{|
+! Foo !! style="color: red" | Bar
+|}
+!!result
+<table>
+<tr>
+<th> Foo </th>
+<th style="color: red"> Bar
+</th></tr></table>
+
+!!end
+
+!!test
+Accept empty attributes in th-cells
+!!input
+{|
+!| foo !!| bar
+|}
+!!result
+<table>
+<tr>
+<th> foo </th>
+<th> bar
+</th></tr></table>
+
+!!end
+
 TODO:
 more images
 more tables
index f01665c..c8b3e89 100644 (file)
@@ -35,18 +35,18 @@ class ParserTestParserHook {
 
        static function dumpHook( $in, $argv ) {
                return "<pre>\n" .
-                          var_export( $in, true ) . "\n" .
-                          var_export( $argv, true ) . "\n" .
-                          "</pre>";
+                       var_export( $in, true ) . "\n" .
+                       var_export( $argv, true ) . "\n" .
+                       "</pre>";
        }
 
        static function staticTagHook( $in, $argv, $parser ) {
-               if ( ! count( $argv ) ) {
+               if ( !count( $argv ) ) {
                        $parser->static_tag_buf = $in;
                        return '';
                } elseif ( count( $argv ) === 1 && isset( $argv['action'] )
-                       && $argv['action'] === 'flush' && $in === null )
-               {
+                       && $argv['action'] === 'flush' && $in === null
+               {
                        // Clear the buffer, we probably don't need to
                        if ( isset( $parser->static_tag_buf ) ) {
                                $tmp = $parser->static_tag_buf;
@@ -55,12 +55,12 @@ class ParserTestParserHook {
                        }
                        $parser->static_tag_buf = null;
                        return $tmp;
-               } else
-                       // wtf?
+               } else { // wtf?
                        return
                                "\nCall this extension as <statictag>string</statictag> or as" .
                                " <statictag action=flush/>, not in any other way.\n" .
                                "text: " . var_export( $in, true ) . "\n" .
                                "argv: " . var_export( $argv, true ) . "\n";
+               }
        }
 }
diff --git a/tests/parser/preprocess/NestedTemplates.expected b/tests/parser/preprocess/NestedTemplates.expected
new file mode 100644 (file)
index 0000000..645626d
--- /dev/null
@@ -0,0 +1,90 @@
+<root><template><title>vorlage</title></template>
+
+<tplarg lineStart="1"><title>argument</title></tplarg>
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{<tplarg><title>vorlagenname</title></tplarg>}
+<template lineStart="1"><title> <template><title>vorlagenname</title></template></title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template> </title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template>erweiterung</title></template>
+
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title> <template><title>vorlagenname</title></template></title></tplarg>
+<template lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title><template><title>vorlagenname</title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></template>
+
+nur etwas erweitert
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></tplarg>
+<template lineStart="1"><title> {<tplarg><title>vorlagenname</title></tplarg></title></template>}
+{<tplarg><title> <template><title>vorlagenname</title></template></title></tplarg>}
+<template lineStart="1"><title> <template><title> <template><title>vorlagenname</title></template></title></template></title></template>
+{<tplarg><title> <template><title>vorlagenname</title></template>} </title></tplarg>
+{<template><title><tplarg><title>vorlagenname</title></tplarg>} </title></template>
+{<tplarg><title><template><title>vorlagenname</title></template> </title></tplarg>}
+<template lineStart="1"><title> <template><title><template><title>vorlagenname</title></template> </title></template></title></template>
+<tplarg lineStart="1"><title> {<template><title>vorlagenname</title></template> </title></tplarg>}
+
+{<tplarg><title><tplarg><title> </title></tplarg></title></tplarg>}
+
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg></title></template>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg></title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg></title></template>
+{{<tplarg><title><tplarg><title> </title></tplarg>} </title></tplarg>}
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg></title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg> </title></template>
+{<tplarg><title><template><title><template><title> </title></template> </title></template> </title></tplarg>}
+{<template><title><tplarg><title><template><title> </title></template> </title></tplarg>} </title></template>
+{<template><title><template><title><tplarg><title> </title></tplarg>} </title></template> </title></template>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg> </title></template>
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg> </title></template> </title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg> </title></tplarg>
+<template lineStart="1"><title><template><title><template><title><template><title> </title></template> </title></template> </title></template> </title></template>
+
+<template lineStart="1"><title>vorlage</title></template>
+
+<tplarg lineStart="1"><title>argument</title></tplarg>
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{<tplarg><title>vorlagenname</title></tplarg>}
+<template lineStart="1"><title> <template><title>vorlagenname</title></template></title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template> </title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template>erweiterung</title></template>
+
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title> <template><title>vorlagenname</title></template></title></tplarg>
+<template lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title><template><title>vorlagenname</title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></template>
+
+nur etwas erweitert
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></tplarg>
+<template lineStart="1"><title> {<tplarg><title>vorlagenname</title></tplarg></title></template>}
+{<tplarg><title> <template><title>vorlagenname</title></template></title></tplarg>}
+<template lineStart="1"><title> <template><title> <template><title>vorlagenname</title></template></title></template></title></template>
+{<tplarg><title> <template><title>vorlagenname</title></template>} </title></tplarg>
+{<template><title><tplarg><title>vorlagenname</title></tplarg>} </title></template>
+{<tplarg><title><template><title>vorlagenname</title></template> </title></tplarg>}
+<template lineStart="1"><title> <template><title><template><title>vorlagenname</title></template> </title></template></title></template>
+<tplarg lineStart="1"><title> {<template><title>vorlagenname</title></template> </title></tplarg>}
+
+{<tplarg><title><tplarg><title> </title></tplarg></title></tplarg>}
+
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg></title></template>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg></title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg></title></template>
+{{<tplarg><title><tplarg><title> </title></tplarg>} </title></tplarg>}
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg></title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg> </title></template>
+{<tplarg><title><template><title><template><title> </title></template> </title></template> </title></tplarg>}
+{<template><title><tplarg><title><template><title> </title></template> </title></tplarg>} </title></template>
+{<template><title><template><title><tplarg><title> </title></tplarg>} </title></template> </title></template>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg> </title></template>
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg> </title></template> </title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg> </title></tplarg>
+<template lineStart="1"><title><template><title><template><title><template><title> </title></template> </title></template> </title></template> </title></template>
+</root>
\ No newline at end of file
diff --git a/tests/parser/preprocess/NestedTemplates.txt b/tests/parser/preprocess/NestedTemplates.txt
new file mode 100644 (file)
index 0000000..aa9a472
--- /dev/null
@@ -0,0 +1,89 @@
+{{vorlage}}
+
+{{{argument}}}
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{{{{vorlagenname}}}}
+{{ {{vorlagenname}}}}
+{{{{vorlagenname}} }}
+{{{{vorlagenname}}erweiterung}}
+
+{{{{{vorlagenname}}}}}
+{{{ {{vorlagenname}}}}}
+{{ {{{vorlagenname}}}}}
+{{{{{vorlagenname}} }}}
+{{{{{vorlagenname}}} }}
+
+nur etwas erweitert
+{{{{{{vorlagenname}}}}}}
+{{{ {{{vorlagenname}}}}}}
+{{{{{{vorlagenname}}} }}}
+{{ {{{{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}}}}}
+{{ {{ {{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}} }}}
+{{{{{{vorlagenname}}}} }}
+{{{{{{vorlagenname}} }}}}
+{{ {{{{vorlagenname}} }}}}
+{{{ {{{vorlagenname}} }}}}
+
+{{{{{{{ }}}}}}}
+
+{{{{{{{{ }}}}}}}}
+{{{{{{{{ }} }}}}}}
+{{{{{{{{ }}} }}}}}
+{{{{{{{{ }}}} }}}}
+{{{{{{{{ }}}}} }}}
+{{{{{{{{ }}}}}} }}
+{{{{{{{{ }} }} }}}}
+{{{{{{{{ }} }}}} }}
+{{{{{{{{ }}}} }} }}
+{{{{{{{{ }}} }}} }}
+{{{{{{{{ }}} }} }}}
+{{{{{{{{ }} }}} }}}
+{{{{{{{{ }} }} }} }}
+
+{{vorlage}}
+
+{{{argument}}}
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{{{{vorlagenname}}}}
+{{ {{vorlagenname}}}}
+{{{{vorlagenname}} }}
+{{{{vorlagenname}}erweiterung}}
+
+{{{{{vorlagenname}}}}}
+{{{ {{vorlagenname}}}}}
+{{ {{{vorlagenname}}}}}
+{{{{{vorlagenname}} }}}
+{{{{{vorlagenname}}} }}
+
+nur etwas erweitert
+{{{{{{vorlagenname}}}}}}
+{{{ {{{vorlagenname}}}}}}
+{{{{{{vorlagenname}}} }}}
+{{ {{{{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}}}}}
+{{ {{ {{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}} }}}
+{{{{{{vorlagenname}}}} }}
+{{{{{{vorlagenname}} }}}}
+{{ {{{{vorlagenname}} }}}}
+{{{ {{{vorlagenname}} }}}}
+
+{{{{{{{ }}}}}}}
+
+{{{{{{{{ }}}}}}}}
+{{{{{{{{ }} }}}}}}
+{{{{{{{{ }}} }}}}}
+{{{{{{{{ }}}} }}}}
+{{{{{{{{ }}}}} }}}
+{{{{{{{{ }}}}}} }}
+{{{{{{{{ }} }} }}}}
+{{{{{{{{ }} }}}} }}
+{{{{{{{{ }}}} }} }}
+{{{{{{{{ }}} }}} }}
+{{{{{{{{ }}} }} }}}
+{{{{{{{{ }} }}} }}}
+{{{{{{{{ }} }} }} }}
index 1ef6473..4d2c402 100644 (file)
@@ -72,7 +72,7 @@ if ( $wgDBtype == 'sqlite' ) {
 # refer to $wgTitle directly, but instead use the title
 # passed to it.
 $wgTitle = Title::newFromText( 'Parser test script do not use' );
-$tester = new ParserTest($options);
+$tester = new ParserTest( $options );
 
 if ( isset( $options['file'] ) ) {
        $files = array( $options['file'] );
index 3034601..0cf6e38 100644 (file)
@@ -10,7 +10,7 @@ abstract class MediaWikiLangTestCase extends MediaWikiTestCase {
                parent::setUp();
 
                if ( $wgLanguageCode != $wgContLang->getCode() ) {
-                       throw new MWException("Error in MediaWikiLangTestCase::setUp(): " .
+                       throw new MWException( "Error in MediaWikiLangTestCase::setUp(): " .
                                "\$wgLanguageCode ('$wgLanguageCode') is different from " .
                                "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")" );
                }
index 3894435..12c2e00 100644 (file)
@@ -2,11 +2,12 @@
 
 class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
 
-       static $additionalOptions = array(
+       public static $additionalOptions = array(
                'regex=' => false,
                'file=' => false,
                'use-filebackend=' => false,
                'use-bagostuff=' => false,
+               'use-jobqueue=' => false,
                'keep-uploads' => false,
                'use-normal-tables' => false,
                'reuse-db' => false,
@@ -14,7 +15,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
        );
 
        public function __construct() {
-               foreach( self::$additionalOptions as $option => $default ) {
+               foreach ( self::$additionalOptions as $option => $default ) {
                        $this->longOptions[$option] = $option . 'Handler';
                }
 
@@ -23,7 +24,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
        public static function main( $exit = true ) {
                $command = new self;
 
-               if( wfIsWindows() ) {
+               if ( wfIsWindows() ) {
                        # Windows does not come anymore with ANSI.SYS loaded by default
                        # PHPUnit uses the suite.xml parameters to enable/disable colors
                        # which can be then forced to be enabled with --colors.
@@ -40,18 +41,20 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
                # See bug 32022
                set_include_path(
                        __DIR__
-                       .PATH_SEPARATOR
-                       . get_include_path()
+                               . PATH_SEPARATOR
+                               . get_include_path()
                );
 
-               $command->run($_SERVER['argv'], $exit);
+               $command->run( $_SERVER['argv'], $exit );
        }
 
        public function __call( $func, $args ) {
 
-               if( substr( $func, -7 ) == 'Handler' ) {
-                       if( is_null( $args[0] ) ) $args[0] = true; //Booleans
-                       self::$additionalOptions[substr( $func, 0, -7 ) ] = $args[0];
+               if ( substr( $func, -7 ) == 'Handler' ) {
+                       if ( is_null( $args[0] ) ) {
+                               $args[0] = true;
+                       } //Booleans
+                       self::$additionalOptions[substr( $func, 0, -7 )] = $args[0];
                }
        }
 
index cbf9a8e..f16d06c 100644 (file)
@@ -71,7 +71,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $this->backupStaticAttributes = false;
        }
 
-       function run( PHPUnit_Framework_TestResult $result = NULL ) {
+       function run( PHPUnit_Framework_TestResult $result = null ) {
                /* Some functions require some kind of caching, and will end up using the db,
                 * which we can't allow, as that would open a new connection for mysql.
                 * Replace with a HashBag. They would not be going to persist anyway.
@@ -81,17 +81,17 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $needsResetDB = false;
                $logName = get_class( $this ) . '::' . $this->getName( false );
 
-               if( $this->needsDB() ) {
+               if ( $this->needsDB() ) {
                        // set up a DB connection for this test to use
 
                        self::$useTemporaryTables = !$this->getCliArg( 'use-normal-tables' );
-                       self::$reuseDB = $this->getCliArg('reuse-db');
+                       self::$reuseDB = $this->getCliArg( 'reuse-db' );
 
                        $this->db = wfGetDB( DB_MASTER );
 
                        $this->checkDbIsSupported();
 
-                       if( !self::$dbSetup ) {
+                       if ( !self::$dbSetup ) {
                                wfProfileIn( $logName . ' (clone-db)' );
 
                                // switch to a temporary clone of the database
@@ -116,7 +116,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                parent::run( $result );
                wfProfileOut( $logName );
 
-               if( $needsResetDB ) {
+               if ( $needsResetDB ) {
                        wfProfileIn( $logName . ' (reset-db)' );
                        $this->resetDB();
                        wfProfileOut( $logName . ' (reset-db)' );
@@ -188,7 +188,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                if ( $this->needsDB() && $this->db ) {
                        // Clean up open transactions
-                       while( $this->db->trxLevel() > 0 ) {
+                       while ( $this->db->trxLevel() > 0 ) {
                                $this->db->rollback();
                        }
 
@@ -213,7 +213,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                if ( $this->needsDB() && $this->db ) {
                        // Clean up open transactions
-                       while( $this->db->trxLevel() > 0 ) {
+                       while ( $this->db->trxLevel() > 0 ) {
                                $this->db->rollback();
                        }
 
@@ -276,7 +276,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function setMwGlobals( $pairs, $value = null ) {
 
                // Normalize (string, value) to an array
-               if( is_string( $pairs ) ) {
+               if ( is_string( $pairs ) ) {
                        $pairs = array( $pairs => $value );
                }
 
@@ -356,8 +356,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        # Insert 0 user to prevent FK violations
                        # Anonymous user
                        $this->db->insert( 'user', array(
-                               'user_id'               => 0,
-                               'user_name'     => 'Anonymous' ), __METHOD__, array( 'IGNORE' ) );
+                               'user_id' => 0,
+                               'user_name' => 'Anonymous' ), __METHOD__, array( 'IGNORE' ) );
 
                        # Insert 0 page to prevent FK violations
                        # Blank page
@@ -365,7 +365,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                                'page_id' => 0,
                                'page_namespace' => 0,
                                'page_title' => ' ',
-                               'page_restrictions' => NULL,
+                               'page_restrictions' => null,
                                'page_counter' => 0,
                                'page_is_redirect' => 0,
                                'page_is_new' => 0,
@@ -471,20 +471,24 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * Empty all tables so they can be repopulated for tests
         */
        private function resetDB() {
-               if( $this->db ) {
-                       if ( $this->db->getType() == 'oracle' )  {
+               if ( $this->db ) {
+                       if ( $this->db->getType() == 'oracle' ) {
                                if ( self::$useTemporaryTables ) {
                                        wfGetLB()->closeAll();
                                        $this->db = wfGetDB( DB_MASTER );
                                } else {
-                                       foreach( $this->tablesUsed as $tbl ) {
-                                               if( $tbl == 'interwiki') continue;
-                                               $this->db->query( 'TRUNCATE TABLE '.$this->db->tableName($tbl), __METHOD__ );
+                                       foreach ( $this->tablesUsed as $tbl ) {
+                                               if ( $tbl == 'interwiki' ) {
+                                                       continue;
+                                               }
+                                               $this->db->query( 'TRUNCATE TABLE ' . $this->db->tableName( $tbl ), __METHOD__ );
                                        }
                                }
                        } else {
-                               foreach( $this->tablesUsed as $tbl ) {
-                                       if( $tbl == 'interwiki' || $tbl == 'user' ) continue;
+                               foreach ( $this->tablesUsed as $tbl ) {
+                                       if ( $tbl == 'interwiki' || $tbl == 'user' ) {
+                                               continue;
+                                       }
                                        $this->db->delete( $tbl, '*', __METHOD__ );
                                }
                        }
@@ -500,9 +504,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                );
 
                if ( method_exists( $this->suite, $func ) ) {
-                       return call_user_func_array( array( $this->suite, $func ), $args);
+                       return call_user_func_array( array( $this->suite, $func ), $args );
                } elseif ( isset( $compatibility[$func] ) ) {
-                       return call_user_func_array( array( $this, $compatibility[$func] ), $args);
+                       return call_user_func_array( array( $this, $compatibility[$func] ), $args );
                } else {
                        throw new MWException( "Called non-existant $func method on "
                                . get_class( $this ) );
@@ -513,12 +517,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                return $this->assertTrue( $value == '', $msg );
        }
 
-       static private function unprefixTable( $tableName ) {
+       private static function unprefixTable( $tableName ) {
                global $wgDBprefix;
                return substr( $tableName, strlen( $wgDBprefix ) );
        }
 
-       static private function isNotUnittest( $table ) {
+       private static function isNotUnittest( $table ) {
                return strpos( $table, 'unittest_' ) !== 0;
        }
 
@@ -543,14 +547,14 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        }
 
        protected function checkDbIsSupported() {
-               if( !in_array( $this->db->getType(), $this->supportedDBs ) ) {
+               if ( !in_array( $this->db->getType(), $this->supportedDBs ) ) {
                        throw new MWException( $this->db->getType() . " is not currently supported for unit testing." );
                }
        }
 
        public function getCliArg( $offset ) {
 
-               if( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) {
+               if ( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) {
                        return MediaWikiPHPUnitCommand::$additionalOptions[$offset];
                }
 
@@ -595,7 +599,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function assertSelect( $table, $fields, $condition, array $expectedRows ) {
                if ( !$this->needsDB() ) {
                        throw new MWException( 'When testing database state, the test cases\'s needDB()' .
-                               ' method should return true. Use @group Database or $this->tablesUsed.');
+                               ' method should return true. Use @group Database or $this->tablesUsed.' );
                }
 
                $db = wfGetDB( DB_SLAVE );
@@ -634,7 +638,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         */
        protected function arrayWrap( array $elements ) {
                return array_map(
-                       function( $element ) {
+                       function ( $element ) {
                                return array( $element );
                        },
                        $elements
@@ -682,9 +686,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * @param String $actual HTML on oneline
         * @param String $msg Optional message
         */
-       protected function assertHTMLEquals( $expected, $actual, $msg='' ) {
+       protected function assertHTMLEquals( $expected, $actual, $msg = '' ) {
                $expected = str_replace( '>', ">\n", $expected );
-               $actual   = str_replace( '>', ">\n", $actual   );
+               $actual = str_replace( '>', ">\n", $actual );
 
                $this->assertEquals( $expected, $actual, $msg );
        }
@@ -699,7 +703,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function objectAssociativeSort( array &$array ) {
                uasort(
                        $array,
-                       function( $a, $b ) {
+                       function ( $a, $b ) {
                                return serialize( $a ) > serialize( $b ) ? 1 : -1;
                        }
                );
@@ -742,8 +746,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function assertTypeOrValue( $type, $actual, $value = false, $message = '' ) {
                if ( $actual === $value ) {
                        $this->assertTrue( true, $message );
-               }
-               else {
+               } else {
                        $this->assertType( $type, $actual, $message );
                }
        }
@@ -762,8 +765,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function assertType( $type, $actual, $message = '' ) {
                if ( class_exists( $type ) || interface_exists( $type ) ) {
                        $this->assertInstanceOf( $type, $actual, $message );
-               }
-               else {
+               } else {
                        $this->assertInternalType( $type, $actual, $message );
                }
        }
@@ -816,7 +818,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                $namespaces = array_diff( $namespaces, array(
                        NS_FILE, NS_CATEGORY, NS_MEDIAWIKI, NS_USER // don't mess with magic namespaces
-               ));
+               ) );
 
                $talk = array_filter( $namespaces, function ( $ns ) {
                        return MWNamespace::isTalk( $ns );
@@ -829,7 +831,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                // check default content model of each namespace
                foreach ( $namespaces as $ns ) {
                        if ( !isset( $wgNamespaceContentModels[$ns] ) ||
-                               $wgNamespaceContentModels[$ns] === CONTENT_MODEL_WIKITEXT ) {
+                               $wgNamespaceContentModels[$ns] === CONTENT_MODEL_WIKITEXT
+                       ) {
 
                                $wikitextNS = $ns;
                                return $wikitextNS;
@@ -857,11 +860,51 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
                wfRestoreWarnings();
 
-               if( !$haveDiff3 ) {
+               if ( !$haveDiff3 ) {
                        $this->markTestSkipped( "Skip test, since diff3 is not configured" );
                }
        }
 
+       /**
+        * Check whether we have the 'gzip' commandline utility, will skip
+        * the test whenever "gzip -V" fails.
+        *
+        * Result is cached at the process level.
+        *
+        * @return bool
+        *
+        * @since 1.21
+        */
+       protected function checkHasGzip() {
+               static $haveGzip;
+
+               if ( $haveGzip === null ) {
+                       $retval = null;
+                       wfShellExec( 'gzip -V', $retval );
+                       $haveGzip = ( $retval === 0 );
+               }
+
+               if ( !$haveGzip ) {
+                       $this->markTestSkipped( "Skip test, requires the gzip utility in PATH" );
+               }
+
+               return $haveGzip;
+       }
+
+       /**
+        * Check if $extName is a loaded PHP extension, will skip the
+        * test whenever it is not loaded.
+        *
+        * @since 1.21
+        */
+       protected function checkPHPExtension( $extName ) {
+               $loaded = extension_loaded( $extName );
+               if ( !$loaded ) {
+                       $this->markTestSkipped( "PHP extension '$extName' is not loaded, skipping." );
+               }
+               return $loaded;
+       }
+
        /**
         * Asserts that an exception of the specified type occurs when running
         * the provided code.
@@ -877,8 +920,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                try {
                        call_user_func( $code );
-               }
-               catch ( Exception $pokemons ) {
+               } catch ( Exception $pokemons ) {
                        // Gotta Catch 'Em All!
                }
 
index dfbcc9d..e3e2138 100644 (file)
@@ -29,7 +29,7 @@ class StructureTest extends MediaWikiTestCase {
 
                $results = null;
                $exitCode = null;
-               exec($finder, $results, $exitCode);
+               exec( $finder, $results, $exitCode );
 
                $this->assertEquals(
                        0,
@@ -42,7 +42,7 @@ class StructureTest extends MediaWikiTestCase {
                        array( $this, 'filterSuites' )
                );
                $strip = strlen( $rootPath ) - 1;
-               foreach( $results as $k => $v) {
+               foreach ( $results as $k => $v ) {
                        $results[$k] = substr( $v, $strip );
                }
                $this->assertEquals(
index 933767e..01caf8f 100644 (file)
@@ -16,7 +16,7 @@ EOF;
 
 // Output a notice when running with older versions of PHPUnit
 if ( version_compare( PHPUnit_Runner_Version::id(), "3.6.7", "<" ) ) {
-  echo <<<EOF
+       echo <<<EOF
 ********************************************************************************
 
 These tests run best with version PHPUnit 3.6.7 or better. Earlier versions may
index 0efcfa3..9aa867b 100644 (file)
@@ -1,52 +1,52 @@
 <?php
 $result = array (
-  'xmp-exif' => 
-  array (
-    'CameraOwnerName' => 'Me!',
-  ),
-  'xmp-general' => 
-  array (
-    'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9',
-    'ImageDescription' => 
-    array (
-      'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp',
-      '_type' => 'lang',
-    ),
-    'ObjectName' => 
-    array (
-      'x-default' => 'xmp core/xmp rights/cc ns test',
-      '_type' => 'lang',
-    ),
-    'DateTimeDigitized' => '2005:04:03',
-    'Software' => 'The one true editor: Vi (ok i used gimp)',
-    'Identifier' => 
-    array (
-      0 => 'http://example.com/identifierurl',
-      1 => 'urn:sha1:342524abcdef',
-      '_type' => 'ul',
-    ),
-    'Label' => 'Test image',
-    'DateTimeMetadata' => '2011:05:12',
-    'DateTime' => '2007:03:04 06:34:10',
-    'Nickname' => 'My little xmp test image',
-    'Rating' => '5',
-    'RightsCertificate' => 'http://example.com/rights-certificate/',
-    'Copyrighted' => 'True',
-    'CopyrightOwner' => 
-    array (
-      0 => 'Bawolff is copyright owner',
-      '_type' => 'ul',
-    ),
-    'UsageTerms' => 
-    array (
-      'x-default' => 'do whatever you want',
-      'en-gb' => 'Do whatever you want in british english',
-      '_type' => 'lang',
-    ),
-    'WebStatement' => 'http://example.com/web_statement',
-  ),
-  'xmp-deprecated' => 
-  array (
-    'Identifier' => 'http://example.com/identifierurl/wrong',
-  ),
+       'xmp-exif' =>
+       array (
+               'CameraOwnerName' => 'Me!',
+       ),
+       'xmp-general' =>
+       array (
+               'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9',
+               'ImageDescription' =>
+               array (
+                       'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp',
+                       '_type' => 'lang',
+               ),
+               'ObjectName' =>
+               array (
+                       'x-default' => 'xmp core/xmp rights/cc ns test',
+                       '_type' => 'lang',
+               ),
+               'DateTimeDigitized' => '2005:04:03',
+               'Software' => 'The one true editor: Vi (ok i used gimp)',
+               'Identifier' =>
+               array (
+                       0 => 'http://example.com/identifierurl',
+                       1 => 'urn:sha1:342524abcdef',
+                       '_type' => 'ul',
+               ),
+               'Label' => 'Test image',
+               'DateTimeMetadata' => '2011:05:12',
+               'DateTime' => '2007:03:04 06:34:10',
+               'Nickname' => 'My little xmp test image',
+               'Rating' => '5',
+               'RightsCertificate' => 'http://example.com/rights-certificate/',
+               'Copyrighted' => 'True',
+               'CopyrightOwner' =>
+               array (
+                       0 => 'Bawolff is copyright owner',
+                       '_type' => 'ul',
+               ),
+               'UsageTerms' =>
+               array (
+                       'x-default' => 'do whatever you want',
+                       'en-gb' => 'Do whatever you want in british english',
+                       '_type' => 'lang',
+               ),
+               'WebStatement' => 'http://example.com/web_statement',
+       ),
+       'xmp-deprecated' =>
+       array (
+               'Identifier' => 'http://example.com/identifierurl/wrong',
+       ),
 );
index 2d1243d..8ea9c68 100644 (file)
@@ -9,4 +9,3 @@ $result = array( 'xmp-exif' =>
                'GPSVersionID' => '2.2.0.0'
         )
 );
-
index 211de26..b09487a 100644 (file)
@@ -32,7 +32,7 @@ class ExportDemoTest extends DumpTestCase {
                try {
                        $this->assertTrue( $dom->schemaValidate( "../../docs/export-" . $version . ".xsd" ),
                                "schemaValidate has found an error" );
-               } catch( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->fail( "xml not valid against xsd: " . $e->getMessage() );
                }
        }
index 82b947b..867c4f0 100644 (file)
@@ -50,7 +50,7 @@ class ArticleTest extends MediaWikiTestCase {
                $this->article->ext_someNewProperty = 12;
                $this->assertEquals( 12, $this->article->ext_someNewProperty,
                        "Article get/set magic on new field" );
-               
+
                $this->article->ext_someNewProperty = -8;
                $this->assertEquals( -8, $this->article->ext_someNewProperty,
                        "Article get/set magic on update to new field" );
@@ -80,11 +80,11 @@ class ArticleTest extends MediaWikiTestCase {
                $title = Title::makeTitle( NS_FILE, 'Someimage.png' );
                $page = WikiPage::factory( $title );
                $this->assertEquals( 'WikiFilePage', get_class( $page ) );
-               
+
                $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' );
                $page = WikiPage::factory( $title );
                $this->assertEquals( 'WikiCategoryPage', get_class( $page ) );
-               
+
                $title = Title::makeTitle( NS_MAIN, 'SomePage' );
                $page = WikiPage::factory( $title );
                $this->assertEquals( 'WikiPage', get_class( $page ) );
index 29931c8..19c9b68 100644 (file)
@@ -59,7 +59,7 @@ class BlockTest extends MediaWikiLangTestCase {
        function dumpBlocks() {
                $v = $this->db->query( 'SELECT * FROM unittest_ipblocks' );
                print "Got " . $v->numRows() . " rows. Full dump follow:\n";
-               foreach( $v as $row ) {
+               foreach ( $v as $row ) {
                        print_r( $row );
                }
        }
@@ -67,9 +67,9 @@ class BlockTest extends MediaWikiLangTestCase {
        function testInitializerFunctionsReturnCorrectBlock() {
                // $this->dumpBlocks();
 
-               $this->assertTrue( $this->block->equals( Block::newFromTarget('UTBlockee') ), "newFromTarget() returns the same block as the one that was made");
+               $this->assertTrue( $this->block->equals( Block::newFromTarget( 'UTBlockee' ) ), "newFromTarget() returns the same block as the one that was made" );
 
-               $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made");
+               $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made" );
 
        }
 
@@ -79,7 +79,7 @@ class BlockTest extends MediaWikiLangTestCase {
        function testBug26425BlockTimestampDefaultsToTime() {
                // delta to stop one-off errors when things happen to go over a second mark.
                $delta = abs( $this->madeAt - $this->block->mTimestamp );
-               $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()");
+               $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()" );
 
        }
 
@@ -95,7 +95,7 @@ class BlockTest extends MediaWikiLangTestCase {
                $this->hideDeprecated( 'Block::load' );
 
                $uid = User::idFromName( 'UTBlockee' );
-               $this->assertTrue( ($uid > 0), 'Must be able to look up the target user during tests' );
+               $this->assertTrue( ( $uid > 0 ), 'Must be able to look up the target user during tests' );
 
                $block = new Block();
                $ok = $block->load( $vagueTarget, $uid );
@@ -112,7 +112,7 @@ class BlockTest extends MediaWikiLangTestCase {
         * @dataProvider provideBug29116Data
         */
        function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) {
-               $block = Block::newFromTarget('UTBlockee', $vagueTarget);
+               $block = Block::newFromTarget( 'UTBlockee', $vagueTarget );
                $this->assertTrue( $this->block->equals( $block ), "newFromTarget() returns the same block as the one that was made when given empty vagueTarget param " . var_export( $vagueTarget, true ) );
        }
 
@@ -167,7 +167,7 @@ class BlockTest extends MediaWikiLangTestCase {
                // Reload block from DB
                $userBlock = Block::newFromTarget( $username );
                $this->assertTrue(
-                       (bool) $block->prevents( 'createaccount' ),
+                       (bool)$block->prevents( 'createaccount' ),
                        "Block object in DB should prevents 'createaccount'"
                );
 
@@ -180,7 +180,7 @@ class BlockTest extends MediaWikiLangTestCase {
                // Reload user
                $u = User::newFromName( $username );
                $this->assertTrue(
-                       (bool) $u->isBlockedFromCreateAccount(),
+                       (bool)$u->isBlockedFromCreateAccount(),
                        "Our sandbox user '$username' should NOT be able to create account"
                );
        }
@@ -223,7 +223,7 @@ class BlockTest extends MediaWikiLangTestCase {
 
                $block = Block::newFromID( $res['id'] );
                $this->assertEquals( 'UserOnForeignWiki', $block->getTarget()->getName(), 'Correct blockee name' );
-               $this->assertEquals( '14146',  $block->getTarget()->getId(), 'Correct blockee id' );
+               $this->assertEquals( '14146', $block->getTarget()->getId(), 'Correct blockee id' );
                $this->assertEquals( 'MetaWikiUser', $block->getBlocker(), 'Correct blocker name' );
                $this->assertEquals( 'MetaWikiUser', $block->getByName(), 'Correct blocker name' );
                $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' );
index 32c84ef..add585d 100644 (file)
@@ -3,7 +3,6 @@
 /**
  * Test the CDB reader/writer
  */
-
 class CdbTest extends MediaWikiTestCase {
 
        protected function setUp() {
@@ -13,6 +12,9 @@ class CdbTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * @group medium
+        */
        public function testCdb() {
                $dir = wfTempDir();
                if ( !is_writable( $dir ) ) {
index 361b412..dcd9ddd 100644 (file)
@@ -22,7 +22,7 @@ class DiffHistoryBlobTest extends MediaWikiTestCase {
         * @dataProvider provideXdiffAdler32
         */
        function testXdiffAdler32( $input ) {
-               $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ),  0, 4 );
+               $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 );
                $dhb = new DiffHistoryBlob;
                $myHash = $dhb->xdiffAdler32( $input );
                $this->assertSame( bin2hex( $xdiffHash ), bin2hex( $myHash ),
index 36fde85..b64a54e 100644 (file)
@@ -59,8 +59,8 @@ class EditPageTest extends MediaWikiTestCase {
         * wrapper around assertEquals() which calls rrtrim() to normalize the
         * expected and actual texts.
         */
-       function assertEditedTextEquals( $expected, $actual, $msg='' ) {
-               return $this->assertEquals( rtrim($expected), rtrim($actual), $msg );
+       function assertEditedTextEquals( $expected, $actual, $msg = '' ) {
+               return $this->assertEquals( rtrim( $expected ), rtrim( $actual ), $msg );
        }
 
        /**
@@ -209,8 +209,7 @@ class EditPageTest extends MediaWikiTestCase {
        }
 
        public static function provideSectionEdit() {
-               $text =
-'Intro
+               $text = 'Intro
 
 == one ==
 first section.
@@ -219,19 +218,19 @@ first section.
 second section.
 ';
 
-               $sectionOne =
-'== one ==
+               $sectionOne = '== one ==
 hello
 ';
 
-               $newSection =
-'== new section ==
+               $newSection = '== new section ==
 
 hello
 ';
 
-               $textWithNewSectionOne = preg_replace( '/== one ==.*== two ==/ms',
-                                                                               "$sectionOne\n== two ==", $text );
+               $textWithNewSectionOne = preg_replace(
+                       '/== one ==.*== two ==/ms',
+                       "$sectionOne\n== two ==", $text
+               );
 
                $textWithNewSectionAdded = "$text\n$newSection";
 
@@ -343,12 +342,12 @@ hello
                );
 
                // see whether it makes a difference who did the base edit
-               $testsWithAdam = array_map( function( $test ) {
+               $testsWithAdam = array_map( function ( $test ) {
                        $test[0] = 'Adam'; // change base edit user
                        return $test;
                }, $tests );
 
-               $testsWithBerta = array_map( function( $test ) {
+               $testsWithBerta = array_map( function ( $test ) {
                        $test[0] = 'Berta'; // change base edit user
                        return $test;
                }, $tests );
@@ -360,7 +359,7 @@ hello
         * @dataProvider provideAutoMerge
         */
        public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit,
-                               $expectedCode, $expectedText, $message = null
+               $expectedCode, $expectedText, $message = null
        ) {
                $this->checkHasDiff3();
 
@@ -378,7 +377,7 @@ hello
                );
 
                $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null,
-                                       $baseUser, $baseEdit, null, null, __METHOD__ );
+                       $baseUser, $baseEdit, null, null, __METHOD__ );
 
                $this->forceRevisionDate( $page, '20120101000000' );
 
index fe6c60d..99544e7 100644 (file)
@@ -78,4 +78,4 @@ class ExternalStoreFOO {
 
                return $this->data[$cluster][$id];
        }
-}
\ No newline at end of file
+}
index ca1615e..e0e5535 100644 (file)
@@ -18,7 +18,7 @@ class ExtraParserTest extends MediaWikiTestCase {
                        'wgAlwaysUseTidy' => false,
                        'wgCleanSignatures' => true,
                ) );
-               
+
                $this->options = ParserOptions::newFromUserAndLang( new User, $contLang );
                $this->options->setTemplateCallback( array( __CLASS__, 'statelessFetchTemplate' ) );
                $this->parser = new Parser;
@@ -26,24 +26,35 @@ class ExtraParserTest extends MediaWikiTestCase {
                MagicWord::clearCache();
        }
 
-       // Bug 8689 - Long numeric lines kill the parser
+       /**
+        * Bug 8689 - Long numeric lines kill the parser
+        *
+        * @group Database
+        */
        function testBug8689() {
                global $wgUser;
                $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n";
-               
+
                $t = Title::newFromText( 'Unit test' );
                $options = ParserOptions::newFromUser( $wgUser );
                $this->assertEquals( "<p>$longLine</p>",
                        $this->parser->parse( $longLine, $t, $options )->getText() );
        }
-       
-       /* Test the parser entry points */
+
+       /**
+        * Test the parser entry points
+        *
+        * @group Database
+        */
        function testParse() {
                $title = Title::newFromText( __FUNCTION__ );
-               $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}" , $title, $this->options );
+               $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options );
                $this->assertEquals( "<p>Test\nContent of <i>Template:Foo</i>\nContent of <i>Template:Bar</i>\n</p>", $parserOutput->getText() );
        }
-       
+
+       /**
+        * @group Database
+        */
        function testPreSaveTransform() {
                global $wgUser;
                $title = Title::newFromText( __FUNCTION__ );
@@ -51,21 +62,24 @@ class ExtraParserTest extends MediaWikiTestCase {
 
                $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText );
        }
-       
+
+       /**
+        * @group Database
+        */
        function testPreprocess() {
                $title = Title::newFromText( __FUNCTION__ );
-               $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}" , $title, $this->options );
-               
+               $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options );
+
                $this->assertEquals( "Test\nContent of ''Template:Foo''\nContent of ''Template:Bar''", $outputText );
        }
-       
+
        /**
         * cleanSig() makes all templates substs and removes tildes
         */
        function testCleanSig() {
                $title = Title::newFromText( __FUNCTION__ );
                $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" );
-               
+
                $this->assertEquals( "{{SUBST:Foo}} ", $outputText );
        }
 
@@ -78,18 +92,18 @@ class ExtraParserTest extends MediaWikiTestCase {
 
                $title = Title::newFromText( __FUNCTION__ );
                $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" );
-               
+
                $this->assertEquals( "{{Foo}} ~~~~", $outputText );
        }
-       
+
        /**
         * cleanSigInSig() just removes tildes
         * @dataProvider provideStringsForCleanSigInSig
         */
        function testCleanSigInSig( $in, $out ) {
-               $this->assertEquals( Parser::cleanSigInSig( $in), $out );
+               $this->assertEquals( Parser::cleanSigInSig( $in ), $out );
        }
-       
+
        public static function provideStringsForCleanSigInSig() {
                return array(
                        array( "{{Foo}} ~~~~", "{{Foo}} " ),
@@ -97,35 +111,35 @@ class ExtraParserTest extends MediaWikiTestCase {
                        array( "~~~~~", "" ),
                );
        }
-       
+
        function testGetSection() {
                $outputText2 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 2 );
                $outputText1 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1 );
-               
+
                $this->assertEquals( "=== Heading 2 ===\nSection 2", $outputText2 );
                $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 );
        }
-       
+
        function testReplaceSection() {
                $outputText = $this->parser->replaceSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1, "New section 1" );
-               
+
                $this->assertEquals( "Section 0\nNew section 1\n\n== Heading 3 ==\nSection 3", $outputText );
        }
-       
+
        /**
         * Templates and comments are not affected, but noinclude/onlyinclude is.
         */
        function testGetPreloadText() {
                $title = Title::newFromText( __FUNCTION__ );
                $outputText = $this->parser->getPreloadText( "{{Foo}}<noinclude> censored</noinclude> information <!-- is very secret -->", $title, $this->options );
-               
+
                $this->assertEquals( "{{Foo}} information <!-- is very secret -->", $outputText );
        }
-       
-       static function statelessFetchTemplate( $title, $parser=false ) {
+
+       static function statelessFetchTemplate( $title, $parser = false ) {
                $text = "Content of ''" . $title->getFullText() . "''";
                $deps = array();
-               
+
                return array(
                        'text' => $text,
                        'finalTitle' => $title,
@@ -137,10 +151,10 @@ class ExtraParserTest extends MediaWikiTestCase {
         */
        function testTrackingCategory() {
                $title = Title::newFromText( __FUNCTION__ );
-               $catName =  wfMessage( 'broken-file-category' )->inContentLanguage()->text();
+               $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text();
                $cat = Title::makeTitleSafe( NS_CATEGORY, $catName );
                $expected = array( $cat->getDBkey() );
-               $parserOutput = $this->parser->parse( "[[file:nonexistent]]" , $title, $this->options );
+               $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options );
                $result = $parserOutput->getCategoryLinks();
                $this->assertEquals( $expected, $result );
        }
@@ -151,8 +165,8 @@ class ExtraParserTest extends MediaWikiTestCase {
        function testTrackingCategorySpecial() {
                // Special pages shouldn't have tracking cats.
                $title = SpecialPage::getTitleFor( 'Contributions' );
-               $parserOutput = $this->parser->parse( "[[file:nonexistent]]" , $title, $this->options );
+               $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options );
                $result = $parserOutput->getCategoryLinks();
                $this->assertEmpty( $result );
        }
- }
+}
index af28f79..4053683 100644 (file)
@@ -46,37 +46,37 @@ class FormOptionsInitializationTest extends MediaWikiTestCase {
        }
 
        public function testAddStringOption() {
-               $this->object->add( 'foo', 'string value' ); 
+               $this->object->add( 'foo', 'string value' );
                $this->assertEquals(
                        array(
                                'foo' => array(
-                                       'default'  => 'string value',
+                                       'default' => 'string value',
                                        'consumed' => false,
-                                       'type'   => FormOptions::STRING,
-                                       'value' => null,
-                                       )
+                                       'type' => FormOptions::STRING,
+                                       'value' => null,
+                               )
                        ),
                        $this->object->getOptions()
                );
        }
 
        public function testAddIntegers() {
-               $this->object->add( 'one',     1 ); 
-               $this->object->add( 'negone', -1 ); 
+               $this->object->add( 'one', 1 );
+               $this->object->add( 'negone', -1 );
                $this->assertEquals(
                        array(
                                'negone' => array(
-                                       'default'  => -1, 
-                                       'value' => null,
+                                       'default' => -1,
+                                       'value' => null,
                                        'consumed' => false,
-                                       'type'   => FormOptions::INT,
-                                       ),
+                                       'type' => FormOptions::INT,
+                               ),
                                'one' => array(
-                                       'default'  => 1,
-                                       'value' => null,
+                                       'default' => 1,
+                                       'value' => null,
                                        'consumed' => false,
-                                       'type'   => FormOptions::INT,
-                                       )
+                                       'type' => FormOptions::INT,
+                               )
                        ),
                        $this->object->getOptions()
                );
index d4e3c5e..0a13cfe 100644 (file)
@@ -33,8 +33,8 @@ class FormOptionsTest extends MediaWikiTestCase {
                $this->object = new FormOptions;
                $this->object->add( 'string1', 'string one' );
                $this->object->add( 'string2', 'string two' );
-               $this->object->add( 'integer',  0 );
-               $this->object->add( 'intnull',  0, FormOptions::INTNULL );
+               $this->object->add( 'integer', 0 );
+               $this->object->add( 'intnull', 0, FormOptions::INTNULL );
        }
 
        /** Helpers for testGuessType() */
@@ -62,30 +62,30 @@ class FormOptionsTest extends MediaWikiTestCase {
         * Reuse helpers above assertGuessBoolean assertGuessInt assertGuessString
         */
        public function testGuessTypeDetection() {
-               $this->assertGuessBoolean( true  );
+               $this->assertGuessBoolean( true );
                $this->assertGuessBoolean( false );
 
-               $this->assertGuessInt(    0 );
-               $this->assertGuessInt(   -5 );
-               $this->assertGuessInt(    5 );
+               $this->assertGuessInt( 0 );
+               $this->assertGuessInt( -5 );
+               $this->assertGuessInt( 5 );
                $this->assertGuessInt( 0x0F );
 
-               $this->assertGuessString( 'true'  );
-               $this->assertGuessString( 'false' ); 
-               $this->assertGuessString( '5'     ); 
-               $this->assertGuessString( '0'     ); 
+               $this->assertGuessString( 'true' );
+               $this->assertGuessString( 'false' );
+               $this->assertGuessString( '5' );
+               $this->assertGuessString( '0' );
        }
 
        /**
-        * @expectedException MWException 
+        * @expectedException MWException
         */
        public function testGuessTypeOnArrayThrowException() {
-               $this->object->guessType( array( 'foo' ) ); 
+               $this->object->guessType( array( 'foo' ) );
        }
        /**
-        * @expectedException MWException 
+        * @expectedException MWException
         */
        public function testGuessTypeOnNullThrowException() {
-               $this->object->guessType( null ); 
+               $this->object->guessType( null );
        }
 }
index 1a02cb8..24fc47c 100644 (file)
@@ -32,7 +32,7 @@ class GlobalTest extends MediaWikiTestCase {
        /** @dataProvider provideForWfArrayDiff2 */
        public function testWfArrayDiff2( $a, $b, $expected ) {
                $this->assertEquals(
-                       wfArrayDiff2( $a, $b), $expected
+                       wfArrayDiff2( $a, $b ), $expected
                );
        }
 
@@ -41,13 +41,13 @@ class GlobalTest extends MediaWikiTestCase {
                // $a $b $expected
                return array(
                        array(
-                               array( 'a', 'b'),
-                               array( 'a', 'b'),
+                               array( 'a', 'b' ),
+                               array( 'a', 'b' ),
                                array(),
                        ),
                        array(
-                               array( array( 'a'), array( 'a', 'b', 'c' )),
-                               array( array( 'a'), array( 'a', 'b' )),
+                               array( array( 'a' ), array( 'a', 'b', 'c' ) ),
+                               array( array( 'a' ), array( 'a', 'b' ) ),
                                array( 1 => array( 'a', 'b', 'c' ) ),
                        ),
                );
@@ -132,14 +132,14 @@ class GlobalTest extends MediaWikiTestCase {
         * @dataProvider provideArrayToCGI
         */
        function testArrayToCGI( $array, $result ) {
-               $this->assertEquals( $result, wfArrayToCGI( $array ) );
+               $this->assertEquals( $result, wfArrayToCgi( $array ) );
        }
 
 
        function testArrayToCGI2() {
                $this->assertEquals(
                        "baz=bar&foo=bar",
-                       wfArrayToCGI(
+                       wfArrayToCgi(
                                array( 'baz' => 'bar' ),
                                array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) );
        }
@@ -183,7 +183,7 @@ class GlobalTest extends MediaWikiTestCase {
         * @dataProvider provideCgiRoundTrip
         */
        function testCgiRoundTrip( $cgi ) {
-               $this->assertEquals( $cgi, wfArrayToCGI( wfCgiToArray( $cgi ) ) );
+               $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) );
        }
 
        function testMimeTypeMatch() {
@@ -191,21 +191,21 @@ class GlobalTest extends MediaWikiTestCase {
                        'text/html',
                        mimeTypeMatch( 'text/html',
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.7,
-                                      'text/plain'            => 0.3 ) ) );
+                                       'text/html' => 0.7,
+                                       'text/plain' => 0.3 ) ) );
                $this->assertEquals(
                        'text/*',
                        mimeTypeMatch( 'text/html',
                                array( 'image/*' => 1.0,
-                                      'text/*'  => 0.5 ) ) );
+                                       'text/*' => 0.5 ) ) );
                $this->assertEquals(
                        '*/*',
                        mimeTypeMatch( 'text/html',
                                array( '*/*' => 1.0 ) ) );
                $this->assertNull(
                        mimeTypeMatch( 'text/html',
-                               array( 'image/png'     => 1.0,
-                                      'image/svg+xml' => 0.5 ) ) );
+                               array( 'image/png' => 1.0,
+                                       'image/svg+xml' => 0.5 ) ) );
        }
 
        function testNegotiateType() {
@@ -213,51 +213,51 @@ class GlobalTest extends MediaWikiTestCase {
                        'text/html',
                        wfNegotiateType(
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.7,
-                                      'text/plain'            => 0.5,
-                                      'text/*'                => 0.2 ),
-                               array( 'text/html'             => 1.0 ) ) );
+                                       'text/html' => 0.7,
+                                       'text/plain' => 0.5,
+                                       'text/*' => 0.2 ),
+                               array( 'text/html' => 1.0 ) ) );
                $this->assertEquals(
                        'application/xhtml+xml',
                        wfNegotiateType(
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.7,
-                                      'text/plain'            => 0.5,
-                                      'text/*'                => 0.2 ),
+                                       'text/html' => 0.7,
+                                       'text/plain' => 0.5,
+                                       'text/*' => 0.2 ),
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.5 ) ) );
+                                       'text/html' => 0.5 ) ) );
                $this->assertEquals(
                        'text/html',
                        wfNegotiateType(
-                               array( 'text/html'             => 1.0,
-                                      'text/plain'            => 0.5,
-                                      'text/*'                => 0.5,
-                                      'application/xhtml+xml' => 0.2 ),
+                               array( 'text/html' => 1.0,
+                                       'text/plain' => 0.5,
+                                       'text/*' => 0.5,
+                                       'application/xhtml+xml' => 0.2 ),
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.5 ) ) );
+                                       'text/html' => 0.5 ) ) );
                $this->assertEquals(
                        'text/html',
                        wfNegotiateType(
-                               array( 'text/*'                => 1.0,
-                                      'image/*'               => 0.7,
-                                      '*/*'                   => 0.3 ),
+                               array( 'text/*' => 1.0,
+                                       'image/*' => 0.7,
+                                       '*/*' => 0.3 ),
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.5 ) ) );
+                                       'text/html' => 0.5 ) ) );
                $this->assertNull(
                        wfNegotiateType(
-                               array( 'text/*'                => 1.0 ),
+                               array( 'text/*' => 1.0 ),
                                array( 'application/xhtml+xml' => 1.0 ) ) );
        }
-       
+
        function testFallbackMbstringFunctions() {
-               
-               if( !extension_loaded( 'mbstring' ) ) {
+
+               if ( !extension_loaded( 'mbstring' ) ) {
                        $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" );
                }
-               
+
                $sampleUTF = "Östergötland_coat_of_arms.png";
-               
-               
+
+
                //mb_substr
                $substr_params = array(
                        array( 0, 0 ),
@@ -268,27 +268,27 @@ class GlobalTest extends MediaWikiTestCase {
                        array( 1, 1 ),
                        array( 2, -1 )
                );
-               
-               foreach( $substr_params as $param_set ) {
+
+               foreach ( $substr_params as $param_set ) {
                        $old_param_set = $param_set;
                        array_unshift( $param_set, $sampleUTF );
-                       
+
                        $this->assertEquals(
                                MWFunction::callArray( 'mb_substr', $param_set ),
                                MWFunction::callArray( 'Fallback::mb_substr', $param_set ),
                                'Fallback mb_substr with params ' . implode( ', ', $old_param_set )
-                       );                      
+                       );
                }
-               
-               
+
+
                //mb_strlen
                $this->assertEquals(
                        mb_strlen( $sampleUTF ),
                        Fallback::mb_strlen( $sampleUTF ),
                        'Fallback mb_strlen'
-               );                      
-               
-               
+               );
+
+
                //mb_str(r?)pos
                $strpos_params = array(
                        //array( 'ter' ),
@@ -298,24 +298,24 @@ class GlobalTest extends MediaWikiTestCase {
                        //array( 'c', -10 ),
                        //Broken for now
                );
-               
-               foreach( $strpos_params as $param_set ) {
+
+               foreach ( $strpos_params as $param_set ) {
                        $old_param_set = $param_set;
                        array_unshift( $param_set, $sampleUTF );
-                       
+
                        $this->assertEquals(
                                MWFunction::callArray( 'mb_strpos', $param_set ),
                                MWFunction::callArray( 'Fallback::mb_strpos', $param_set ),
                                'Fallback mb_strpos with params ' . implode( ', ', $old_param_set )
-                       );              
-                       
+                       );
+
                        $this->assertEquals(
                                MWFunction::callArray( 'mb_strrpos', $param_set ),
                                MWFunction::callArray( 'Fallback::mb_strrpos', $param_set ),
                                'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set )
-                       );      
+                       );
                }
-               
+
        }
 
 
@@ -347,7 +347,7 @@ class GlobalTest extends MediaWikiTestCase {
                $this->assertGreaterThan( 5000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
                unlink( $wgDebugLogFile );
 
-               wfDebugMem(true);
+               wfDebugMem( true );
                $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
                unlink( $wgDebugLogFile );
 
@@ -357,7 +357,7 @@ class GlobalTest extends MediaWikiTestCase {
        }
 
        function testClientAcceptsGzipTest() {
-               
+
                $settings = array(
                        'gzip' => true,
                        'bzip' => false,
@@ -370,25 +370,24 @@ class GlobalTest extends MediaWikiTestCase {
                        'gzip;q=12345678.9' => true,
                        ' gzip' => true,
                );
-               
-               if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING'];
-               
+
+               if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
+                       $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING'];
+               }
+
                foreach ( $settings as $encoding => $expect ) {
                        $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding;
-                       
+
                        $this->assertEquals( $expect, wfClientAcceptsGzip( true ),
                                "'$encoding' => " . wfBoolToStr( $expect ) );
                }
-               
-               if( isset( $old_server_setting ) ) $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting;
 
+               if ( isset( $old_server_setting ) ) {
+                       $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting;
+               }
        }
-       
-       
-       
-       function testSwapVarsTest() {
-       
 
+       function testSwapVarsTest() {
                $var1 = 1;
                $var2 = 2;
 
@@ -402,36 +401,29 @@ class GlobalTest extends MediaWikiTestCase {
 
        }
 
-
        function testWfPercentTest() {
 
                $pcts = array(
-                       array( 6/7, '0.86%', 2, false ),
-                       array( 3/3, '1%' ),
-                       array( 22/7, '3.14286%', 5 ),
-                       array( 3/6, '0.5%' ),
-                       array( 1/3, '0%', 0 ),
-                       array( 10/3, '0%', -1 ),
-                       array( 3/4/5, '0.1%', 1 ),
-                       array( 6/7*8, '6.8571428571%', 10 ),
+                       array( 6 / 7, '0.86%', 2, false ),
+                       array( 3 / 3, '1%' ),
+                       array( 22 / 7, '3.14286%', 5 ),
+                       array( 3 / 6, '0.5%' ),
+                       array( 1 / 3, '0%', 0 ),
+                       array( 10 / 3, '0%', -1 ),
+                       array( 3 / 4 / 5, '0.1%', 1 ),
+                       array( 6 / 7 * 8, '6.8571428571%', 10 ),
                );
-               
-               foreach( $pcts as $pct ) {
-                       if( !isset( $pct[2] ) ) $pct[2] = 2;
-                       if( !isset( $pct[3] ) ) $pct[3] = true;
-                       
-                       $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] );
-               }
-
-       }
 
+               foreach ( $pcts as $pct ) {
+                       if ( !isset( $pct[2] ) ) {
+                               $pct[2] = 2;
+                       }
+                       if ( !isset( $pct[3] ) ) {
+                               $pct[3] = true;
+                       }
 
-       function testInStringTest() {
-       
-               $this->assertTrue( in_string( 'foo', 'foobar' ), 'foo is in foobar' );
-               $this->assertFalse( in_string( 'Bar', 'foobar' ), 'Case-sensitive by default' );
-               $this->assertTrue( in_string( 'Foo', 'foobar', true ), 'Case-insensitive when asked' );
-       
+                       $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] );
+               }
        }
 
        /**
@@ -441,47 +433,47 @@ class GlobalTest extends MediaWikiTestCase {
        public function testWfShorthandToInteger( $shorthand, $expected ) {
                $this->assertEquals( $expected,
                        wfShorthandToInteger( $shorthand )
-               );      
+               );
        }
 
        /** array( shorthand, expected integer ) */
        public static function provideShorthand() {
                return array(
                        # Null, empty ... 
-                       array(     '', -1),
-                       array(   '  ', -1),
-                       array(   null, -1),
+                       array( '', -1 ),
+                       array( '  ', -1 ),
+                       array( null, -1 ),
 
                        # Failures returns 0 :(
                        array( 'ABCDEFG', 0 ),
-                       array( 'Ak',      0 ),
+                       array( 'Ak', 0 ),
 
                        # Int, strings with spaces
-                       array(        1,    1 ),
-                       array(    ' 1 ',    1 ),
-                       array(     1023, 1023 ),
+                       array( 1, 1 ),
+                       array( ' 1 ', 1 ),
+                       array( 1023, 1023 ),
                        array( ' 1023 ', 1023 ),
 
                        # kilo, Mega, Giga
-                       array(   '1k', 1024 ),
-                       array(   '1K', 1024 ),
-                       array(   '1m', 1024 * 1024 ),
-                       array(   '1M', 1024 * 1024 ),
-                       array(   '1g', 1024 * 1024 * 1024 ),
-                       array(   '1G', 1024 * 1024 * 1024 ),
+                       array( '1k', 1024 ),
+                       array( '1K', 1024 ),
+                       array( '1m', 1024 * 1024 ),
+                       array( '1M', 1024 * 1024 ),
+                       array( '1g', 1024 * 1024 * 1024 ),
+                       array( '1G', 1024 * 1024 * 1024 ),
 
                        # Negatives
-                       array(     -1,    -1 ),
-                       array(   -500,  -500 ),
-                       array( '-500',  -500 ),
-                       array(  '-1k', -1024 ),
+                       array( -1, -1 ),
+                       array( -500, -500 ),
+                       array( '-500', -500 ),
+                       array( '-1k', -1024 ),
 
                        # Zeroes
-                       array(   '0', 0 ),
-                       array(  '0k', 0 ),
-                       array(  '0M', 0 ),
-                       array(  '0G', 0 ),
-                       array(  '-0', 0 ),
+                       array( '0', 0 ),
+                       array( '0k', 0 ),
+                       array( '0M', 0 ),
+                       array( '0G', 0 ),
+                       array( '-0', 0 ),
                        array( '-0k', 0 ),
                        array( '-0M', 0 ),
                        array( '-0G', 0 ),
@@ -508,7 +500,7 @@ class GlobalTest extends MediaWikiTestCase {
                $msg .= $expectedMergeResult ? 'success' : 'failure';
                $this->assertEquals( $expectedMergeResult, $isMerged, $msg );
 
-               if( $isMerged ) {
+               if ( $isMerged ) {
                        // Verify the merged text
                        $this->assertEquals( $expectedText, $mergedText,
                                'is merged text as expected?' );
@@ -520,31 +512,30 @@ class GlobalTest extends MediaWikiTestCase {
                $EXPECT_MERGE_FAILURE = false;
 
                return array(
-
                        // #0: clean merge
                        array(
                                // old:
                                "one one one\n" . // trimmed
-                               "\n" .
-                               "two two two",
+                                       "\n" .
+                                       "two two two",
 
                                // mine:
                                "one one one ONE ONE\n" .
-                               "\n" .
-                               "two two two\n", // with tailing whitespace
+                                       "\n" .
+                                       "two two two\n", // with tailing whitespace
 
                                // yours:
                                "one one one\n" .
-                               "\n" .
-                               "two two TWO TWO", // trimmed
+                                       "\n" .
+                                       "two two TWO TWO", // trimmed
 
                                // ok:
                                $EXPECT_MERGE_SUCCESS,
 
                                // result:
                                "one one one ONE ONE\n" .
-                               "\n" .
-                               "two two TWO TWO\n", // note: will always end in a newline
+                                       "\n" .
+                                       "two two TWO TWO\n", // note: will always end in a newline
                        ),
 
                        // #1: conflict, fail
@@ -554,14 +545,14 @@ class GlobalTest extends MediaWikiTestCase {
 
                                // mine:
                                "one one one ONE ONE\n" .
-                               "\n" .
-                               "bla bla\n" .
-                               "\n", // with tailing whitespace
+                                       "\n" .
+                                       "bla bla\n" .
+                                       "\n", // with tailing whitespace
 
                                // yours:
                                "one one one\n" .
-                               "\n" .
-                               "two two", // trimmed
+                                       "\n" .
+                                       "two two", // trimmed
 
                                $EXPECT_MERGE_FAILURE,
 
@@ -627,7 +618,7 @@ class GlobalTest extends MediaWikiTestCase {
                        ),
                );
        }
-       
+
        /**
         * @dataProvider provideWfMatchesDomainList
         */
@@ -635,7 +626,7 @@ class GlobalTest extends MediaWikiTestCase {
                $actual = wfMatchesDomainList( $url, $domains );
                $this->assertEquals( $expected, $actual, $description );
        }
-       
+
        function provideWfMatchesDomainList() {
                $a = array();
                $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' );
@@ -647,7 +638,7 @@ class GlobalTest extends MediaWikiTestCase {
                                array( "$p//www.example2.com", array( 'www.example.com', 'www.example2.com', 'www.example3.com' ), true, "Exact match with other domains in array, $pDesc URL" ),
                                array( "$p//www.example2.com", array( 'example.com', 'example2.com', 'example3,com' ), true, "Match without subdomain with other domains in array, $pDesc URL" ),
                                array( "$p//www.example4.com", array( 'example.com', 'example2.com', 'example3,com' ), false, "Domain not in array, $pDesc URL" ),
-                               
+
                                // FIXME: This is a bug in wfMatchesDomainList(). If and when this is fixed, update this test case
                                array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), true, "Substrings of domains match while they shouldn't, $pDesc URL" ),
                        ) );
@@ -659,7 +650,7 @@ class GlobalTest extends MediaWikiTestCase {
         * @dataProvider provideWfShellMaintenanceCmdList
         */
        function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) {
-               if( wfIsWindows() ) {
+               if ( wfIsWindows() ) {
                        // Approximation that's good enough for our purposes just now
                        $expected = str_replace( "'", '"', $expected );
                }
@@ -673,17 +664,16 @@ class GlobalTest extends MediaWikiTestCase {
                        array( 'eval.php', array( '--help', '--test' ), array(),
                                "'$wgPhpCli' 'eval.php' '--help' '--test'",
                                "Called eval.php --help --test" ),
-                       array( 'eval.php', array( '--help', '--test space' ), array('php' => 'php5'),
+                       array( 'eval.php', array( '--help', '--test space' ), array( 'php' => 'php5' ),
                                "'php5' 'eval.php' '--help' '--test space'",
                                "Called eval.php --help --test with php option" ),
-                       array( 'eval.php', array( '--help', '--test', 'X' ), array('wrapper' => 'MWScript.php'),
+                       array( 'eval.php', array( '--help', '--test', 'X' ), array( 'wrapper' => 'MWScript.php' ),
                                "'$wgPhpCli' 'MWScript.php' 'eval.php' '--help' '--test' 'X'",
                                "Called eval.php --help --test with wrapper option" ),
-                       array( 'eval.php', array( '--help', '--test', 'y' ), array('php' => 'php5', 'wrapper' => 'MWScript.php'),
+                       array( 'eval.php', array( '--help', '--test', 'y' ), array( 'php' => 'php5', 'wrapper' => 'MWScript.php' ),
                                "'php5' 'MWScript.php' 'eval.php' '--help' '--test' 'y'",
                                "Called eval.php --help --test with wrapper and php option" ),
                );
        }
        /* TODO: many more! */
 }
-
index bed435a..4bd8c68 100644 (file)
@@ -1,9 +1,8 @@
 <?php
 /**
- * Unit tests for wfAssembleUrl()
+ * Tests for wfAssembleUrl()
  */
-
-class wfAssembleUrl extends MediaWikiTestCase {
+class WfAssembleUrlTest extends MediaWikiTestCase {
        /** @dataProvider provideURLParts */
        public function testWfAssembleUrl( $parts, $output ) {
                $partsDump = print_r( $parts, true );
@@ -83,7 +82,7 @@ class wfAssembleUrl extends MediaWikiTestCase {
                                                                $parts['query'] = $query;
                                                                $url .= '?' . $query;
                                                        }
-                                                       if( $fragment ) {
+                                                       if ( $fragment ) {
                                                                $parts['fragment'] = $fragment;
                                                                $url .= '#' . $fragment;
                                                        }
index 4a0f406..8df038d 100644 (file)
@@ -1,8 +1,8 @@
 <?php
 /**
- * Unit tests for wfBCP47()
+ * Tests for wfBCP47()
  */
-class wfBCP47 extends MediaWikiTestCase {
+class WfBCP47Test extends MediaWikiTestCase {
        /**
         * test @see wfBCP47().
         * Please note the BCP explicitly state that language codes are case
@@ -15,12 +15,12 @@ class wfBCP47 extends MediaWikiTestCase {
         */
        function testBCP47( $code, $expected ) {
                $code = strtolower( $code );
-               $this->assertEquals( $expected, wfBCP47($code),
+               $this->assertEquals( $expected, wfBCP47( $code ),
                        "Applying BCP47 standard to lower case '$code'"
                );
 
                $code = strtoupper( $code );
-               $this->assertEquals( $expected, wfBCP47($code),
+               $this->assertEquals( $expected, wfBCP47( $code ),
                        "Applying BCP47 standard to upper case '$code'"
                );
        }
@@ -32,15 +32,15 @@ class wfBCP47 extends MediaWikiTestCase {
                return array(
                        // Extracted from BCP47 (list not exhaustive)
                        # 2.1.1
-                       array( 'en-ca-x-ca'    , 'en-CA-x-ca'     ),
-                       array( 'sgn-be-fr'     , 'sgn-BE-FR'      ),
+                       array( 'en-ca-x-ca', 'en-CA-x-ca' ),
+                       array( 'sgn-be-fr', 'sgn-BE-FR' ),
                        array( 'az-latn-x-latn', 'az-Latn-x-latn' ),
                        # 2.2
                        array( 'sr-Latn-RS', 'sr-Latn-RS' ),
                        array( 'az-arab-ir', 'az-Arab-IR' ),
 
                        # 2.2.5
-                       array( 'sl-nedis'  , 'sl-nedis'   ),
+                       array( 'sl-nedis', 'sl-nedis' ),
                        array( 'de-ch-1996', 'de-CH-1996' ),
 
                        # 2.2.6
@@ -56,40 +56,40 @@ class wfBCP47 extends MediaWikiTestCase {
                        array( 'ja', 'ja' ),
 
                        # Language subtag plus script subtag:
-                       array( 'zh-hans', 'zh-Hans'),
-                       array( 'sr-cyrl', 'sr-Cyrl'),
-                       array( 'sr-latn', 'sr-Latn'),
+                       array( 'zh-hans', 'zh-Hans' ),
+                       array( 'sr-cyrl', 'sr-Cyrl' ),
+                       array( 'sr-latn', 'sr-Latn' ),
 
                        # Extended language subtags and their primary language subtag
                        # counterparts:
                        array( 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ),
-                       array( 'cmn-hans-cn'   , 'cmn-Hans-CN'    ),
-                       array( 'zh-yue-hk'     , 'zh-yue-HK'      ),
-                       array( 'yue-hk'        , 'yue-HK'         ),
+                       array( 'cmn-hans-cn', 'cmn-Hans-CN' ),
+                       array( 'zh-yue-hk', 'zh-yue-HK' ),
+                       array( 'yue-hk', 'yue-HK' ),
 
                        # Language-Script-Region:
                        array( 'zh-hans-cn', 'zh-Hans-CN' ),
                        array( 'sr-latn-RS', 'sr-Latn-RS' ),
 
                        # Language-Variant:
-                       array( 'sl-rozaj'      , 'sl-rozaj'       ),
+                       array( 'sl-rozaj', 'sl-rozaj' ),
                        array( 'sl-rozaj-biske', 'sl-rozaj-biske' ),
-                       array( 'sl-nedis'      , 'sl-nedis'       ),
+                       array( 'sl-nedis', 'sl-nedis' ),
 
                        # Language-Region-Variant:
-                       array( 'de-ch-1901'  , 'de-CH-1901'  ),
-                       array( 'sl-it-nedis' , 'sl-IT-nedis' ),
+                       array( 'de-ch-1901', 'de-CH-1901' ),
+                       array( 'sl-it-nedis', 'sl-IT-nedis' ),
 
                        # Language-Script-Region-Variant:
                        array( 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ),
 
                        # Language-Region:
-                       array( 'de-de' , 'de-DE' ),
-                       array( 'en-us' , 'en-US' ),
-                       array( 'es-419', 'es-419'),
+                       array( 'de-de', 'de-DE' ),
+                       array( 'en-us', 'en-US' ),
+                       array( 'es-419', 'es-419' ),
 
                        # Private use subtags:
-                       array( 'de-ch-x-phonebk'      , 'de-CH-x-phonebk' ),
+                       array( 'de-ch-x-phonebk', 'de-CH-x-phonebk' ),
                        array( 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ),
                        /**
                         * Previous test does not reflect the BCP which states:
@@ -102,7 +102,7 @@ class wfBCP47 extends MediaWikiTestCase {
                        # Private use registry values:
                        array( 'x-whatever', 'x-whatever' ),
                        array( 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ),
-                       array( 'de-qaaa'   , 'de-Qaaa'    ),
+                       array( 'de-qaaa', 'de-Qaaa' ),
                        array( 'sr-latn-qm', 'sr-Latn-QM' ),
                        array( 'sr-qaaa-rs', 'sr-Qaaa-RS' ),
 
@@ -115,8 +115,8 @@ class wfBCP47 extends MediaWikiTestCase {
                        // de-419-DE
                        // a-DE
                        // ar-a-aaa-b-bbb-a-ccc
-       
-               /*      
+
+                       /*
                        // ISO 15924 :
                        array( 'sr-Cyrl', 'sr-Cyrl' ),
                        # @todo FIXME: Fix our function?
@@ -128,6 +128,7 @@ class wfBCP47 extends MediaWikiTestCase {
                        array( 'uS', 'us' ),  # USA
                        array( 'Fr', 'fr' ),  # France
                        array( 'va', 'va' ),  # Holy See (Vatican City State)
-                */);
+                        */
+               );
        }
 }
index 21e5032..10b62b3 100644 (file)
@@ -1,9 +1,8 @@
 <?php
-
 /**
  * Tests for wfBaseConvert()
  */
-class wfBaseConvertTest extends MediaWikiTestCase {
+class WfBaseConvertTest extends MediaWikiTestCase {
        public static function provideSingleDigitConversions() {
                return array(
                        //      2    3    5    8   10   16   36
@@ -142,13 +141,13 @@ class wfBaseConvertTest extends MediaWikiTestCase {
        public static function provideNumbers() {
                $x = array();
                $chars = '0123456789abcdefghijklmnopqrstuvwxyz';
-               for( $i = 0; $i < 50; $i++ ) {
+               for ( $i = 0; $i < 50; $i++ ) {
                        $base = mt_rand( 2, 36 );
                        $len = mt_rand( 10, 100 );
 
                        $str = '';
-                       for( $j = 0; $j < $len; $j++ ) {
-                               $str .= $chars[mt_rand(0, $base - 1)];
+                       for ( $j = 0; $j < $len; $j++ ) {
+                               $str .= $chars[mt_rand( 0, $base - 1 )];
                        }
 
                        $x[] = array( $base, $str );
index 59954b2..407be8d 100644 (file)
@@ -2,15 +2,15 @@
 /**
  * Tests for wfBaseName()
  */
-class wfBaseName extends MediaWikiTestCase {
+class WfBaseNameTest extends MediaWikiTestCase {
        /**
         * @dataProvider providePaths
         */
        function testBaseName( $fullpath, $basename ) {
                $this->assertEquals( $basename, wfBaseName( $fullpath ),
-                               "wfBaseName('$fullpath') => '$basename'" );
+                       "wfBaseName('$fullpath') => '$basename'" );
        }
-       
+
        function providePaths() {
                return array(
                        array( '', '' ),
index cb6e6c4..c1225e3 100644 (file)
@@ -1,9 +1,8 @@
 <?php
 /**
- * Unit tests for wfExpandUrl()
+ * Tests for wfExpandUrl()
  */
-
-class wfExpandUrl extends MediaWikiTestCase {
+class WfExpandUrlTest extends MediaWikiTestCase {
        /** @dataProvider provideExpandableUrls */
        public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto, $server, $canServer, $httpsMode, $message ) {
                // Fake $wgServer and $wgCanonicalServer
@@ -51,7 +50,7 @@ class wfExpandUrl extends MediaWikiTestCase {
                foreach ( $modes as $mode ) {
                        $httpsMode = $mode == 'https';
                        foreach ( $servers as $serverDesc => $server ) {
-                               foreach ( $modes as $canServerMode  ) {
+                               foreach ( $modes as $canServerMode ) {
                                        $canServer = "$canServerMode://example2.com";
                                        foreach ( $defaultProtos as $protoDesc => $defaultProto ) {
                                                $retval[] = array(
index 4c4c4c0..58cf6b9 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-class wfGetCaller extends MediaWikiTestCase {
+class WfGetCallerTest extends MediaWikiTestCase {
 
        function testZero() {
                $this->assertEquals( __METHOD__, wfGetCaller( 1 ) );
@@ -11,25 +11,25 @@ class wfGetCaller extends MediaWikiTestCase {
        }
 
        function testOne() {
-               $this->assertEquals( "wfGetCaller::testOne", self::callerOne() );
+               $this->assertEquals( 'WfGetCallerTest::testOne', self::callerOne() );
        }
 
        function intermediateFunction( $level = 2, $n = 0 ) {
-               if ( $n > 0 )
+               if ( $n > 0 ) {
                        return self::intermediateFunction( $level, $n - 1 );
+               }
                return wfGetCaller( $level );
        }
 
        function testTwo() {
-               $this->assertEquals( "wfGetCaller::testTwo", self::intermediateFunction() );
+               $this->assertEquals( 'WfGetCallerTest::testTwo', self::intermediateFunction() );
        }
 
        function testN() {
-               $this->assertEquals( "wfGetCaller::testN", self::intermediateFunction( 2, 0 ) );
-               $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( 1, 0 ) );
+               $this->assertEquals( 'WfGetCallerTest::testN', self::intermediateFunction( 2, 0 ) );
+               $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( 1, 0 ) );
 
-               for ($i=0; $i < 10; $i++)
-                       $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( $i + 1, $i ) );
+               for ( $i = 0; $i < 10; $i++ )
+                       $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( $i + 1, $i ) );
        }
 }
-
diff --git a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php
new file mode 100644 (file)
index 0000000..841a1b1
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Tests for wfParseUrl()
+ *
+ * Copyright © 2013 Alexandre Emsenhuber
+ *
+ * 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 WfParseUrlTest extends MediaWikiTestCase {
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( 'wgUrlProtocols', array(
+                       '//', 'http://', 'file://', 'mailto:',
+               ) );
+       }
+
+       /** @dataProvider provideURLs */
+       public function testWfParseUrl( $url, $parts ) {
+               $partsDump = var_export( $parts, true );
+               $this->assertEquals(
+                       $parts,
+                       wfParseUrl( $url ),
+                       "Testing $url parses to $partsDump"
+               );
+       }
+
+       /**
+        * Provider of URLs for testing wfParseUrl()
+        *
+        * @return array
+        */
+       public static function provideURLs() {
+               return array(
+                       array(
+                               '//example.org',
+                               array(
+                                       'scheme' => '',
+                                       'delimiter' => '//',
+                                       'host' => 'example.org',
+                               )
+                       ),
+                       array(
+                               'http://example.org',
+                               array(
+                                       'scheme' => 'http',
+                                       'delimiter' => '://',
+                                       'host' => 'example.org',
+                               )
+                       ),
+                       array(
+                               'http://id:key@example.org:123/path?foo=bar#baz',
+                               array(
+                                       'scheme' => 'http',
+                                       'delimiter' => '://',
+                                       'user' => 'id',
+                                       'pass' => 'key',
+                                       'host' => 'example.org',
+                                       'port' => 123,
+                                       'path' => '/path',
+                                       'query' => 'foo=bar',
+                                       'fragment' => 'baz',
+                               )
+                       ),
+                       array(
+                               'file://example.org/etc/php.ini',
+                               array(
+                                       'scheme' => 'file',
+                                       'delimiter' => '://',
+                                       'host' => 'example.org',
+                                       'path' => '/etc/php.ini',
+                               )
+                       ),
+                       array(
+                               'file:///etc/php.ini',
+                               array(
+                                       'scheme' => 'file',
+                                       'delimiter' => '://',
+                                       'host' => '',
+                                       'path' => '/etc/php.ini',
+                               )
+                       ),
+                       array(
+                               'file:///c:/',
+                               array(
+                                       'scheme' => 'file',
+                                       'delimiter' => '://',
+                                       'host' => '',
+                                       'path' => '/c:/',
+                               )
+                       ),
+                       array(
+                               'mailto:id@example.org',
+                               array(
+                                       'scheme' => 'mailto',
+                                       'delimiter' => ':',
+                                       'host' => 'id@example.org',
+                                       'path' => '',
+                               )
+                       ),
+                       array(
+                               'mailto:id@example.org?subject=Foo',
+                               array(
+                                       'scheme' => 'mailto',
+                                       'delimiter' => ':',
+                                       'host' => 'id@example.org',
+                                       'path' => '',
+                                       'query' => 'subject=Foo',
+                               )
+                       ),
+                       array(
+                               'mailto:?subject=Foo',
+                               array(
+                                       'scheme' => 'mailto',
+                                       'delimiter' => ':',
+                                       'host' => '',
+                                       'path' => '',
+                                       'query' => 'subject=Foo',
+                               )
+                       ),
+                       array(
+                               'invalid://test/',
+                               false
+                       ),
+               );
+       }
+}
index af784bd..67861ee 100644 (file)
@@ -1,9 +1,8 @@
 <?php
 /**
- * Unit tests for wfRemoveDotSegments()
+ * Tests for wfRemoveDotSegments()
  */
-
-class wfRemoveDotSegments extends MediaWikiTestCase {
+class WfRemoveDotSegmentsTest extends MediaWikiTestCase {
        /** @dataProvider providePaths */
        public function testWfRemoveDotSegments( $inputPath, $outputPath ) {
                $this->assertEquals(
index 1df26d2..9d66d6b 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-class wfShorthandToIntegerTest extends MediaWikiTestCase {
+class WfShorthandToIntegerTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideABunchOfShorthands
         */
@@ -24,5 +24,5 @@ class wfShorthandToIntegerTest extends MediaWikiTestCase {
                        array( '1k', 1024, 'One kb lowercased' ),
                );
        }
-       
+
 }
index 505c28c..cf1830f 100644 (file)
@@ -1,9 +1,8 @@
 <?php
-
 /*
  * Tests for wfTimestamp()
  */
-class wfTimestamp extends MediaWikiTestCase {
+class WfTimestampTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideNormalTimestamps
         */
@@ -13,7 +12,7 @@ class wfTimestamp extends MediaWikiTestCase {
 
        function provideNormalTimestamps() {
                $t = gmmktime( 12, 34, 56, 1, 15, 2001 );
-               return array (
+               return array(
                        // TS_UNIX
                        array( $t, TS_MW, '20010115123456', 'TS_UNIX to TS_MW' ),
                        array( -30281104, TS_MW, '19690115123456', 'Negative TS_UNIX to TS_MW' ),
@@ -21,13 +20,13 @@ class wfTimestamp extends MediaWikiTestCase {
                        array( $t, TS_DB, '2001-01-15 12:34:56', 'TS_UNIX to TS_DB' ),
 
                        array( $t, TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_ISO_8601_BASIC to TS_DB' ),
-                       
+
                        // TS_MW
                        array( '20010115123456', TS_MW, '20010115123456', 'TS_MW to TS_MW' ),
                        array( '20010115123456', TS_UNIX, 979562096, 'TS_MW to TS_UNIX' ),
                        array( '20010115123456', TS_DB, '2001-01-15 12:34:56', 'TS_MW to TS_DB' ),
                        array( '20010115123456', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_MW to TS_ISO_8601_BASIC' ),
-                       
+
                        // TS_DB
                        array( '2001-01-15 12:34:56', TS_MW, '20010115123456', 'TS_DB to TS_MW' ),
                        array( '2001-01-15 12:34:56', TS_UNIX, 979562096, 'TS_DB to TS_UNIX' ),
@@ -62,7 +61,7 @@ class wfTimestamp extends MediaWikiTestCase {
        }
 
        function provideOldTimestamps() {
-               return array (
+               return array(
                        array( '19011213204554', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:54 GMT', 'Earliest time according to php documentation' ),
                        array( '20380119031407', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:07 GMT', 'Latest 32 bit time' ),
                        array( '19011213204552', TS_UNIX, '-2147483648', 'Earliest 32 bit unix time' ),
index 673702e..77685d5 100644 (file)
@@ -1,14 +1,12 @@
 <?php
 /**
- * Tests for includes/GlobalFunctions.php -> wfUrlencode()
+ * Tests for wfUrlencode()
  *
  * The function only need a string parameter and might react to IIS7.0
  */
-
-class wfUrlencodeTest extends MediaWikiTestCase {
-
+class WfUrlencodeTest extends MediaWikiTestCase {
        #### TESTS ##############################################################
-       
+
        /** @dataProvider provideURLS */
        public function testEncodingUrlWith( $input, $expected ) {
                $this->verifyEncodingFor( 'Apache', $input, $expected );
@@ -20,7 +18,7 @@ class wfUrlencodeTest extends MediaWikiTestCase {
        }
 
        #### HELPERS #############################################################
-       
+
        /**
         * Internal helper that actually run the test.
         * Called by the public methods testEncodingUrlWith...()
@@ -30,10 +28,9 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                $expected = $this->extractExpect( $server, $expectations );
 
                // save up global
-               $old = isset($_SERVER['SERVER_SOFTWARE'])
+               $old = isset( $_SERVER['SERVER_SOFTWARE'] )
                        ? $_SERVER['SERVER_SOFTWARE']
-                       : null
-               ;
+                       : null;
                $_SERVER['SERVER_SOFTWARE'] = $server;
                wfUrlencode( null );
 
@@ -45,7 +42,7 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                );
 
                // restore global
-               if( $old === null ) {
+               if ( $old === null ) {
                        unset( $_SERVER['SERVER_SOFTWARE'] );
                } else {
                        $_SERVER['SERVER_SOFTWARE'] = $old;
@@ -58,19 +55,18 @@ class wfUrlencodeTest extends MediaWikiTestCase {
         * the HTTP server name.
         */
        private function extractExpect( $server, $expectations ) {
-               if( is_string( $expectations ) ) {
+               if ( is_string( $expectations ) ) {
                        return $expectations;
-               } elseif( is_array( $expectations ) ) {
-                       if( !array_key_exists( $server, $expectations ) ) {
+               } elseif ( is_array( $expectations ) ) {
+                       if ( !array_key_exists( $server, $expectations ) ) {
                                throw new MWException( __METHOD__ . " expectation does not have any value for server name $server. Check the provider array.\n" );
                        } else {
                                return $expectations[$server];
                        }
-               } else {
+               } else {
                        throw new MWException( __METHOD__ . " given invalid expectation for '$server'. Should be a string or an array( <http server name> => <string> ).\n" );
-               }
-       }  
-
+               }
+       }
 
        #### PROVIDERS ###########################################################
 
@@ -83,11 +79,11 @@ class wfUrlencodeTest extends MediaWikiTestCase {
         *       array( 'Microsoft-IIS/7', 'expected' ),
         *    ),
         * If you want to add other HTTP server name, you will have to add a new
-        * testing method much like the testEncodingUrlWith() method above. 
+        * testing method much like the testEncodingUrlWith() method above.
         */
        public static function provideURLS() {
                return array(
-               ### RFC 1738 chars      
+                       ### RFC 1738 chars
                        // + is not safe
                        array( '+', '%2B' ),
                        // & and = not safe in queries
@@ -95,7 +91,7 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                        array( '=', '%3D' ),
 
                        array( ':', array(
-                               'Apache'          => ':',
+                               'Apache' => ':',
                                'Microsoft-IIS/7' => '%3A',
                        ) ),
 
@@ -105,10 +101,10 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                                ';@$-_.!*',
                        ),
 
-               ### Other tests
+                       ### Other tests
                        // slash remain unchanged. %2F seems to break things
                        array( '/', '/' ),
-       
+
                        // Other 'funnies' chars
                        array( '[]', '%5B%5D' ),
                        array( '<>', '%3C%3E' ),
index e455f0f..89e789b 100644 (file)
@@ -111,7 +111,7 @@ class HooksTest extends MediaWikiTestCase {
 class NothingClass {
        public $calls = 0;
 
-       static public function someStatic( &$foo, &$bar ) {
+       public static function someStatic( &$foo, &$bar ) {
                $foo = 'bah';
                return true;
        }
index 47fa5f4..b6e23ab 100644 (file)
@@ -15,22 +15,22 @@ class HtmlTest extends MediaWikiTestCase {
                $langObj->setNamespaces( array(
                        -2 => 'Media',
                        -1 => 'Special',
-                       0  => '',
-                       1  => 'Talk',
-                       2  => 'User',
-                       3  => 'User_talk',
-                       4  => 'MyWiki',
-                       5  => 'MyWiki_Talk',
-                       6  => 'File',
-                       7  => 'File_talk',
-                       8  => 'MediaWiki',
-                       9  => 'MediaWiki_talk',
-                       10  => 'Template',
-                       11  => 'Template_talk',
-                       14  => 'Category',
-                       15  => 'Category_talk',
-                       100  => 'Custom',
-                       101  => 'Custom_talk',
+                       0 => '',
+                       1 => 'Talk',
+                       2 => 'User',
+                       3 => 'User_talk',
+                       4 => 'MyWiki',
+                       5 => 'MyWiki_Talk',
+                       6 => 'File',
+                       7 => 'File_talk',
+                       8 => 'MediaWiki',
+                       9 => 'MediaWiki_talk',
+                       10 => 'Template',
+                       11 => 'Template_talk',
+                       14 => 'Category',
+                       15 => 'Category_talk',
+                       100 => 'Custom',
+                       101 => 'Custom_talk',
                ) );
 
                $this->setMwGlobals( array(
@@ -165,22 +165,22 @@ class HtmlTest extends MediaWikiTestCase {
                $this->assertEquals(
                        ' empty_string=""',
                        Html::expandAttributes( array( 'empty_string' => '' ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Empty string'
+                       'Attribute values are always quoted (wgWellFormedXml): Empty string'
                );
                $this->assertEquals(
                        ' key="value"',
                        Html::expandAttributes( array( 'key' => 'value' ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Simple string'
+                       'Attribute values are always quoted (wgWellFormedXml): Simple string'
                );
                $this->assertEquals(
                        ' one="1"',
                        Html::expandAttributes( array( 'one' => 1 ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Number 1'
+                       'Attribute values are always quoted (wgWellFormedXml): Number 1'
                );
                $this->assertEquals(
                        ' zero="0"',
                        Html::expandAttributes( array( 'zero' => 0 ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Number 0'
+                       'Attribute values are always quoted (wgWellFormedXml): Number 0'
                );
        }
 
@@ -248,12 +248,12 @@ class HtmlTest extends MediaWikiTestCase {
                                'one' => 1,
 
                                # Method use isset() internally, make sure we do discard
-                           # attributes values which have been assigned well known values
+                               # attributes values which have been assigned well known values
                                'emptystring' => '',
                                'boolfalse' => false,
                                'zero' => 0,
                                'null' => null,
-                       )))
+                       ) ) )
                );
        }
 
@@ -271,55 +271,55 @@ class HtmlTest extends MediaWikiTestCase {
                                'GREEN',
                                'GREEN' => false,
                                'GREEN',
-                       )))
+                       ) ) )
                );
        }
 
        function testNamespaceSelector() {
                $this->assertEquals(
                        '<select id=namespace name=namespace>' . "\n" .
-'<option value=0>(Main)</option>' . "\n" .
-'<option value=1>Talk</option>' . "\n" .
-'<option value=2>User</option>' . "\n" .
-'<option value=3>User talk</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                               '<option value=0>(Main)</option>' . "\n" .
+                               '<option value=1>Talk</option>' . "\n" .
+                               '<option value=2>User</option>' . "\n" .
+                               '<option value=3>User talk</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(),
                        'Basic namespace selector without custom options'
                );
 
                $this->assertEquals(
                        '<label for=mw-test-namespace>Select a namespace:</label>&#160;' .
-'<select id=mw-test-namespace name=wpNamespace>' . "\n" .
-'<option value=all>all</option>' . "\n" .
-'<option value=0>(Main)</option>' . "\n" .
-'<option value=1>Talk</option>' . "\n" .
-'<option value=2 selected>User</option>' . "\n" .
-'<option value=3>User talk</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                               '<select id=mw-test-namespace name=wpNamespace>' . "\n" .
+                               '<option value=all>all</option>' . "\n" .
+                               '<option value=0>(Main)</option>' . "\n" .
+                               '<option value=1>Talk</option>' . "\n" .
+                               '<option value=2 selected>User</option>' . "\n" .
+                               '<option value=3>User talk</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(
                                array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ),
                                array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' )
@@ -329,24 +329,24 @@ class HtmlTest extends MediaWikiTestCase {
 
                $this->assertEquals(
                        '<label for=namespace>Select a namespace:</label>&#160;' .
-'<select id=namespace name=namespace>' . "\n" .
-'<option value=0>(Main)</option>' . "\n" .
-'<option value=1>Talk</option>' . "\n" .
-'<option value=2>User</option>' . "\n" .
-'<option value=3>User talk</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                               '<select id=namespace name=namespace>' . "\n" .
+                               '<option value=0>(Main)</option>' . "\n" .
+                               '<option value=1>Talk</option>' . "\n" .
+                               '<option value=2>User</option>' . "\n" .
+                               '<option value=3>User talk</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(
                                array( 'label' => 'Select a namespace:' )
                        ),
@@ -356,19 +356,19 @@ class HtmlTest extends MediaWikiTestCase {
 
        function testCanFilterOutNamespaces() {
                $this->assertEquals(
-'<select id=namespace name=namespace>' . "\n" .
-'<option value=2>User</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'</select>',
+                       '<select id=namespace name=namespace>' . "\n" .
+                               '<option value=2>User</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(
                                array( 'exclude' => array( 0, 1, 3, 100, 101 ) )
                        ),
@@ -378,24 +378,24 @@ class HtmlTest extends MediaWikiTestCase {
 
        function testCanDisableANamespaces() {
                $this->assertEquals(
-'<select id=namespace name=namespace>' . "\n" .
-'<option disabled value=0>(Main)</option>' . "\n" .
-'<option disabled value=1>Talk</option>' . "\n" .
-'<option disabled value=2>User</option>' . "\n" .
-'<option disabled value=3>User talk</option>' . "\n" .
-'<option disabled value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                       '<select id=namespace name=namespace>' . "\n" .
+                               '<option disabled value=0>(Main)</option>' . "\n" .
+                               '<option disabled value=1>Talk</option>' . "\n" .
+                               '<option disabled value=2>User</option>' . "\n" .
+                               '<option disabled value=3>User talk</option>' . "\n" .
+                               '<option disabled value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector( array(
                                'disable' => array( 0, 1, 2, 3, 4 )
                        ) ),
@@ -435,7 +435,7 @@ class HtmlTest extends MediaWikiTestCase {
                        'color',
                );
                $cases = array();
-               foreach( $types as $type ) {
+               foreach ( $types as $type ) {
                        $cases[] = array( $type );
                }
                return $cases;
@@ -595,7 +595,7 @@ class HtmlTest extends MediaWikiTestCase {
 
                # Craft the Html elements
                $ret = array();
-               foreach( $cases as $case ) {
+               foreach ( $cases as $case ) {
                        $ret[] = array(
                                $case[0],
                                $case[1], $case[2],
index b49de65..7698776 100644 (file)
@@ -19,10 +19,10 @@ class HttpTest extends MediaWikiTestCase {
 
        public static function cookieDomains() {
                return array(
-                       array( false, "org"),
-                       array( false, ".org"),
-                       array( true, "wikipedia.org"),
-                       array( true, ".wikipedia.org"),
+                       array( false, "org" ),
+                       array( false, ".org" ),
+                       array( true, "wikipedia.org" ),
+                       array( true, ".wikipedia.org" ),
                        array( false, "co.uk" ),
                        array( false, ".co.uk" ),
                        array( false, "gov.uk" ),
@@ -54,7 +54,7 @@ class HttpTest extends MediaWikiTestCase {
        function testIsValidUri( $expect, $URI, $message = '' ) {
                $this->assertEquals(
                        $expect,
-                       (bool) Http::isValidURI( $URI ),
+                       (bool)Http::isValidURI( $URI ),
                        $message
                );
        }
@@ -68,26 +68,26 @@ class HttpTest extends MediaWikiTestCase {
                        array( false, '¿non sens before!! http://a', 'Allow anything before URI' ),
 
                        # (http|https) - only two schemes allowed
-                       array( true,  'http://www.example.org/' ),
-                       array( true,  'https://www.example.org/' ),
-                       array( true,  'http://www.example.org', 'URI without directory' ),
-                       array( true,  'http://a', 'Short name' ),
-                       array( true, 'http://étoile', 'Allow UTF-8 in hostname' ),  # 'étoile' is french for 'star'
+                       array( true, 'http://www.example.org/' ),
+                       array( true, 'https://www.example.org/' ),
+                       array( true, 'http://www.example.org', 'URI without directory' ),
+                       array( true, 'http://a', 'Short name' ),
+                       array( true, 'http://étoile', 'Allow UTF-8 in hostname' ), # 'étoile' is french for 'star'
                        array( false, '\\host\directory', 'CIFS share' ),
                        array( false, 'gopher://host/dir', 'Reject gopher scheme' ),
                        array( false, 'telnet://host', 'Reject telnet scheme' ),
 
                        # :\/\/ - double slashes
-                       array( false,  'http//example.org', 'Reject missing colon in protocol' ),
-                       array( false,  'http:/example.org', 'Reject missing slash in protocol' ),
-                       array( false,  'http:example.org', 'Must have two slashes' ),
+                       array( false, 'http//example.org', 'Reject missing colon in protocol' ),
+                       array( false, 'http:/example.org', 'Reject missing slash in protocol' ),
+                       array( false, 'http:example.org', 'Must have two slashes' ),
                        # Following fail since hostname can be made of anything
-                       array( false,  'http:///example.org', 'Must have exactly two slashes, not three' ),
+                       array( false, 'http:///example.org', 'Must have exactly two slashes, not three' ),
 
                        # (\w+:{0,1}\w*@)? - optional user:pass
-                       array( true,  'http://user@host', 'Username provided' ),
-                       array( true,  'http://user:@host', 'Username provided, no password' ),
-                       array( true,  'http://user:pass@host', 'Username and password provided' ),
+                       array( true, 'http://user@host', 'Username provided' ),
+                       array( true, 'http://user:@host', 'Username provided, no password' ),
+                       array( true, 'http://user:pass@host', 'Username and password provided' ),
 
                        # (\S+) - host part is made of anything not whitespaces
                        array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ),
@@ -115,7 +115,7 @@ class HttpTest extends MediaWikiTestCase {
                        array( true, 'http://example/&' ),
 
                        # Fragment
-                       array( true, 'http://exam#ple.org', ),  # This one is valid, really!
+                       array( true, 'http://exam#ple.org', ), # This one is valid, really!
                        array( true, 'http://example.org:80#anchor' ),
                        array( true, 'http://example.org/?id#anchor' ),
                        array( true, 'http://example.org/?#anchor' ),
@@ -126,7 +126,7 @@ class HttpTest extends MediaWikiTestCase {
 
        /**
         * Warning:
-        * 
+        *
         * These tests are for code that makes use of an artifact of how CURL
         * handles header reporting on redirect pages, and will need to be
         * rewritten when bug 29232 is taken care of (high-level handling of
@@ -137,8 +137,8 @@ class HttpTest extends MediaWikiTestCase {
 
                # Forge a Location header
                $h->setRespHeaders( 'location', array(
-                       'http://newsite/file.ext',
-                       '/newfile.ext',
+                               'http://newsite/file.ext',
+                               '/newfile.ext',
                        )
                );
                # Verify we correctly fix the Location
@@ -149,7 +149,7 @@ class HttpTest extends MediaWikiTestCase {
                );
 
                $h->setRespHeaders( 'location', array(
-                       'https://oldsite/file.ext'
+                               'https://oldsite/file.ext'
                        )
                );
                $this->assertEquals(
@@ -159,14 +159,14 @@ class HttpTest extends MediaWikiTestCase {
                );
 
                $h->setRespHeaders( 'location', array(
-                       '/anotherfile.ext',
-                       'http://anotherfile/hoster.ext',
-                       'https://anotherfile/hoster.ext'
+                               '/anotherfile.ext',
+                               'http://anotherfile/hoster.ext',
+                               'https://anotherfile/hoster.ext'
                        )
                );
                $this->assertEquals(
                        'https://anotherfile/hoster.ext',
-                       $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!")
+                       $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" )
                );
        }
 }
@@ -183,10 +183,10 @@ class MWHttpRequestTester extends MWHttpRequest {
                        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"' );
+                               'Http::$httpEngine is set to "curl"' );
                }
 
-               switch( Http::$httpEngine ) {
+               switch ( Http::$httpEngine ) {
                        case 'curl':
                                return new CurlHttpRequestTester( $url, $options );
                        case 'php':
index c4a6c55..7bc2938 100644 (file)
@@ -11,13 +11,13 @@ class IPTest extends MediaWikiTestCase {
         */
        public function testisIPAddress() {
                $this->assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' );
-               $this->assertFalse( IP::isIPAddress( true  ), 'Boolean true is not an IP' );
+               $this->assertFalse( IP::isIPAddress( true ), 'Boolean true is not an IP' );
                $this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' );
                $this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' );
                $this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' );
-               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1'), 'IPv6 with a double :: occurrence' );
-               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::'), 'IPv6 with a double :: occurrence, last at end' );
-               $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1'), 'IPv6 with a double :: occurrence, firt at beginning' );
+               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1' ), 'IPv6 with a double :: occurrence' );
+               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::' ), 'IPv6 with a double :: occurrence, last at end' );
+               $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1' ), 'IPv6 with a double :: occurrence, firt at beginning' );
                $this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' );
                $this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' );
                $this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' );
@@ -81,9 +81,9 @@ class IPTest extends MediaWikiTestCase {
                $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
                $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' );
                $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
-               $this->assertTrue( IP::isIPv6( '2001::df'), 'IPv6 with "::" and 2 words' );
-               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' );
-               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' );
+               $this->assertTrue( IP::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' );
+               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
+               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
 
                $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
                $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
@@ -96,7 +96,7 @@ class IPTest extends MediaWikiTestCase {
         */
        public function testisIPv4() {
                $this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' );
-               $this->assertFalse( IP::isIPv4( true  ), 'Boolean true is not an IP' );
+               $this->assertFalse( IP::isIPv4( true ), 'Boolean true is not an IP' );
                $this->assertFalse( IP::isIPv4( "" ), 'Empty string is not an IP' );
                $this->assertFalse( IP::isIPv4( 'abc' ) );
                $this->assertFalse( IP::isIPv4( ':' ) );
@@ -119,7 +119,7 @@ class IPTest extends MediaWikiTestCase {
                        $c = sprintf( "%01d", $i );
                        foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
                                $ip = "$f.$f.$f.$f";
-                               $this->assertTrue( IP::isValid( $ip ) , "$ip is a valid IPv4 address" );
+                               $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv4 address" );
                        }
                }
                foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) {
@@ -128,7 +128,7 @@ class IPTest extends MediaWikiTestCase {
                        $c = sprintf( "%02x", $i );
                        foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
                                $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
-                               $this->assertTrue( IP::isValid( $ip ) , "$ip is a valid IPv6 address" );
+                               $this->assertTrue( IP::isValid( $ip ), "$ip is a valid IPv6 address" );
                        }
                }
                // test with some abbreviations
@@ -143,9 +143,9 @@ class IPTest extends MediaWikiTestCase {
 
                $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
-               $this->assertTrue( IP::isValid( '2001::df'), 'IPv6 with "::" and 2 words' );
-               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' );
-               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' );
+               $this->assertTrue( IP::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' );
+               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
+               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
 
@@ -173,7 +173,7 @@ class IPTest extends MediaWikiTestCase {
                        $c = sprintf( "%02s", $i );
                        foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
                                $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
-                               $this->assertFalse( IP::isValid( $ip ) , "$ip is not a valid IPv6 address" );
+                               $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv6 address" );
                        }
                }
                // Have CIDR
@@ -254,8 +254,8 @@ class IPTest extends MediaWikiTestCase {
         * @todo Most probably incomplete
         */
        public function testSanitizeIP() {
-               $this->assertNull( IP::sanitizeIP('')  );
-               $this->assertNull( IP::sanitizeIP(' ') );
+               $this->assertNull( IP::sanitizeIP( '' ) );
+               $this->assertNull( IP::sanitizeIP( ' ' ) );
        }
 
        /**
@@ -264,7 +264,7 @@ class IPTest extends MediaWikiTestCase {
         */
        public function testip2longWrapper() {
                // @todo FIXME: Add more tests ?
-               $this->assertEquals( pow(2,32) - 1, IP::toUnsigned( '255.255.255.255' ));
+               $this->assertEquals( pow( 2, 32 ) - 1, IP::toUnsigned( '255.255.255.255' ) );
                $i = 'IN.VA.LI.D';
                $this->assertFalse( IP::toUnSigned( $i ) );
        }
@@ -284,7 +284,7 @@ class IPTest extends MediaWikiTestCase {
        }
 
        // Private wrapper used to test CIDR Parsing.
-       private function assertFalseCIDR( $CIDR, $msg='' ) {
+       private function assertFalseCIDR( $CIDR, $msg = '' ) {
                $ff = array( false, false );
                $this->assertEquals( $ff, IP::parseCIDR( $CIDR ), $msg );
        }
@@ -299,15 +299,15 @@ class IPTest extends MediaWikiTestCase {
         * @covers IP::hexToQuad
         */
        public function testHexToQuad() {
-               $this->assertEquals( '0.0.0.1'        , IP::hexToQuad( '00000001' ) );
-               $this->assertEquals( '255.0.0.0'      , IP::hexToQuad( 'FF000000' ) );
+               $this->assertEquals( '0.0.0.1', IP::hexToQuad( '00000001' ) );
+               $this->assertEquals( '255.0.0.0', IP::hexToQuad( 'FF000000' ) );
                $this->assertEquals( '255.255.255.255', IP::hexToQuad( 'FFFFFFFF' ) );
-               $this->assertEquals( '10.188.222.255' , IP::hexToQuad( '0ABCDEFF' ) );
+               $this->assertEquals( '10.188.222.255', IP::hexToQuad( '0ABCDEFF' ) );
                // hex not left-padded...
-               $this->assertEquals( '0.0.0.0'     , IP::hexToQuad( '0' ) );
-               $this->assertEquals( '0.0.0.1'     , IP::hexToQuad( '1' ) );
-               $this->assertEquals( '0.0.0.255'   , IP::hexToQuad( 'FF' ) );
-               $this->assertEquals( '0.0.255.0'   , IP::hexToQuad( 'FF00' ) );
+               $this->assertEquals( '0.0.0.0', IP::hexToQuad( '0' ) );
+               $this->assertEquals( '0.0.0.1', IP::hexToQuad( '1' ) );
+               $this->assertEquals( '0.0.0.255', IP::hexToQuad( 'FF' ) );
+               $this->assertEquals( '0.0.255.0', IP::hexToQuad( 'FF00' ) );
        }
 
        /**
@@ -325,11 +325,11 @@ class IPTest extends MediaWikiTestCase {
                $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
                        IP::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) );
                // hex not left-padded...
-               $this->assertEquals( '0:0:0:0:0:0:0:0'          , IP::hexToOctet( '0' ) );
-               $this->assertEquals( '0:0:0:0:0:0:0:1'          , IP::hexToOctet( '1' ) );
-               $this->assertEquals( '0:0:0:0:0:0:0:FF'         , IP::hexToOctet( 'FF' ) );
-               $this->assertEquals( '0:0:0:0:0:0:0:FFD0'       , IP::hexToOctet( 'FFD0' ) );
-               $this->assertEquals( '0:0:0:0:0:0:FA00:0'       , IP::hexToOctet( 'FA000000' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:0', IP::hexToOctet( '0' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:1', IP::hexToOctet( '1' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:FF', IP::hexToOctet( 'FF' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP::hexToOctet( 'FFD0' ) );
+               $this->assertEquals( '0:0:0:0:0:0:FA00:0', IP::hexToOctet( 'FA000000' ) );
                $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) );
        }
 
@@ -339,42 +339,41 @@ class IPTest extends MediaWikiTestCase {
         * @covers IP::parseCIDR
         */
        function testCIDRParsing() {
-               $this->assertFalseCIDR( '192.0.2.0' , "missing mask"    );
+               $this->assertFalseCIDR( '192.0.2.0', "missing mask" );
                $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" );
 
                // Verify if statement
-               $this->assertFalseCIDR( '256.0.0.0/32', "invalid net"      );
+               $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" );
                $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" );
-               $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0"         );
-               $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32"        );
+               $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" );
+               $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" );
 
                // Check internal logic
                # 0 mask always result in array(0,0)
-               $this->assertEquals( array( 0, 0 ), IP::parseCIDR('192.0.0.2/0') );
-               $this->assertEquals( array( 0, 0 ), IP::parseCIDR('0.0.0.0/0') );
-               $this->assertEquals( array( 0, 0 ), IP::parseCIDR('255.255.255.255/0') );
+               $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '192.0.0.2/0' ) );
+               $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '0.0.0.0/0' ) );
+               $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '255.255.255.255/0' ) );
 
                // @todo FIXME: Add more tests.
 
                # This part test network shifting
-               $this->assertNet( '192.0.0.0'  , '192.0.0.2/24'   );
-               $this->assertNet( '192.168.5.0', '192.168.5.13/24');
-               $this->assertNet( '10.0.0.160' , '10.0.0.161/28'  );
-               $this->assertNet( '10.0.0.0'   , '10.0.0.3/28'  );
-               $this->assertNet( '10.0.0.0'   , '10.0.0.3/30'  );
-               $this->assertNet( '10.0.0.4'   , '10.0.0.4/30'  );
+               $this->assertNet( '192.0.0.0', '192.0.0.2/24' );
+               $this->assertNet( '192.168.5.0', '192.168.5.13/24' );
+               $this->assertNet( '10.0.0.160', '10.0.0.161/28' );
+               $this->assertNet( '10.0.0.0', '10.0.0.3/28' );
+               $this->assertNet( '10.0.0.0', '10.0.0.3/30' );
+               $this->assertNet( '10.0.0.4', '10.0.0.4/30' );
                $this->assertNet( '172.17.32.0', '172.17.35.48/21' );
-               $this->assertNet( '10.128.0.0' , '10.135.0.0/9' );
-               $this->assertNet( '134.0.0.0'  , '134.0.5.1/8'  );
+               $this->assertNet( '10.128.0.0', '10.135.0.0/9' );
+               $this->assertNet( '134.0.0.0', '134.0.5.1/8' );
        }
 
-
        /**
         * @covers IP::canonicalize
         */
        public function testIPCanonicalizeOnValidIp() {
                $this->assertEquals( '192.0.2.152', IP::canonicalize( '192.0.2.152' ),
-               'Canonicalization of a valid IP returns it unchanged' );
+                       'Canonicalization of a valid IP returns it unchanged' );
        }
 
        /**
@@ -406,26 +405,26 @@ class IPTest extends MediaWikiTestCase {
 
        /** Provider for testIPIsInRange() */
        public static function provideIPsAndRanges() {
-                       # Format: (expected boolean, address, range, optional message)
+               # Format: (expected boolean, address, range, optional message)
                return array(
                        # IPv4
-                       array( true , '192.0.2.0'   , '192.0.2.0/24', 'Network address' ),
-                       array( true , '192.0.2.77'  , '192.0.2.0/24', 'Simple address' ),
-                       array( true , '192.0.2.255' , '192.0.2.0/24', 'Broadcast address' ),
+                       array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ),
+                       array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ),
+                       array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ),
 
-                       array( false, '0.0.0.0'     , '192.0.2.0/24' ),
-                       array( false, '255.255.255' , '192.0.2.0/24' ),
+                       array( false, '0.0.0.0', '192.0.2.0/24' ),
+                       array( false, '255.255.255', '192.0.2.0/24' ),
 
                        # IPv6
-                       array( false, '::1'    , '2001:DB8::/32' ),
-                       array( false, '::'     , '2001:DB8::/32' ),
+                       array( false, '::1', '2001:DB8::/32' ),
+                       array( false, '::', '2001:DB8::/32' ),
                        array( false, 'FE80::1', '2001:DB8::/32' ),
 
-                       array( true , '2001:DB8::'  , '2001:DB8::/32' ),
-                       array( true , '2001:0DB8::' , '2001:DB8::/32' ),
-                       array( true , '2001:DB8::1' , '2001:DB8::/32' ),
-                       array( true , '2001:0DB8::1', '2001:DB8::/32' ),
-                       array( true , '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
+                       array( true, '2001:DB8::', '2001:DB8::/32' ),
+                       array( true, '2001:0DB8::', '2001:DB8::/32' ),
+                       array( true, '2001:DB8::1', '2001:DB8::/32' ),
+                       array( true, '2001:0DB8::1', '2001:DB8::/32' ),
+                       array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
                                '2001:DB8::/32' ),
 
                        array( false, '2001:0DB8:F::', '2001:DB8::/96' ),
index 9b508f7..96a2ead 100644 (file)
@@ -1,25 +1,25 @@
 <?php
 
 class JsonTest extends MediaWikiTestCase {
-       
+
        function testPhpBug46944Test() {
-               $this->assertNotEquals( 
-                       '\ud840\udc00',                 
+               $this->assertNotEquals(
+                       '\ud840\udc00',
                        strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ),
                        'Test encoding an broken json_encode character (U+20000)'
                );
 
        }
-       
+
        function testDecodeVarTypes() {
-               $this->assertInternalType( 
-                       'object',                       
+               $this->assertInternalType(
+                       'object',
                        FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ),
                        'Default to object'
                );
 
-               $this->assertInternalType( 
-                       'array',                        
+               $this->assertInternalType(
+                       'array',
                        FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ),
                        'Optional array'
                );
index eb8912d..d4d93b0 100644 (file)
@@ -84,8 +84,8 @@ class LanguageConverterTest extends MediaWikiLangTestCase {
                $wgUser->setId( 1 );
                $wgUser->mFrom = 'defaults';
                $wgUser->mOptionsLoaded = true;
-               $wgUser->setOption( 'variant', 'tg-latn' ); // The user's data is ignored
-                                                                                                 // because the variant is set in the URL.
+               // The user's data is ignored because the variant is set in the URL.
+               $wgUser->setOption( 'variant', 'tg-latn' ); 
                $this->assertEquals( 'tg', $this->lc->getPreferredVariant() );
        }
 
@@ -120,7 +120,7 @@ class TestConverter extends LanguageConverter {
        function loadDefaultTables() {
                $this->mTables = array(
                        'tg-latn' => new ReplacementArray( $this->table ),
-                       'tg'      => new ReplacementArray()
+                       'tg' => new ReplacementArray()
                );
        }
 
index e467f3c..212b3b3 100644 (file)
@@ -14,8 +14,8 @@ class LicensesTest extends MediaWikiTestCase {
                        'section' => 'description',
                        'id' => 'wpLicense',
                        'label' => 'A label text', # Note can't test label-message because $wgOut is not defined
-                       'name' => 'AnotherName', 
-                       'licenses' => $str,             
+                       'name' => 'AnotherName',
+                       'licenses' => $str,
                ) );
                $this->assertThat( $lc, $this->isInstanceOf( 'Licenses' ) );
        }
index abb8374..90de96d 100644 (file)
@@ -6,11 +6,11 @@ class LinkerTest extends MediaWikiLangTestCase {
         * @dataProvider provideCasesForUserLink
         * @cover Linker::userLink
         */
-       function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg='' ) {
+       function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) {
                $this->setMwGlobals( array(
                        'wgArticlePath' => '/wiki/$1',
                        'wgWellFormedXml' => true,
-               ) );
+               ) );
 
                $this->assertEquals( $expected,
                        Linker::userLink( $userId, $userName, $altUserName, $msg )
index 3325885..244e4a8 100644 (file)
@@ -160,4 +160,3 @@ class LinksUpdateTest extends MediaWikiTestCase {
                $this->assertSelect( $table, $fields, $condition, $expectedRows );
        }
 }
-
index c5a9dc1..d6f0d2e 100644 (file)
@@ -13,13 +13,13 @@ class LocalFileTest extends MediaWikiTestCase {
                $this->setMwGlobals( 'wgCapitalLinks', true );
 
                $info = array(
-                       'name'            => 'test',
-                       'directory'       => '/testdir',
-                       'url'             => '/testurl',
-                       'hashLevels'      => 2,
+                       'name' => 'test',
+                       'directory' => '/testdir',
+                       'url' => '/testurl',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'local-backend',
                                'lockManager' => 'fsLockManager',
                                'containerPaths' => array(
                                        'cont1' => "/testdir/local-backend/tempimages/cont1",
@@ -105,5 +105,3 @@ class LocalFileTest extends MediaWikiTestCase {
                $this->assertThat( $file, $this->isInstanceOf( 'LocalFile' ), 'wfLocalFile() returns LocalFile for valid Titles' );
        }
 }
-
-
index f7be59f..6c17bf4 100644 (file)
@@ -1,27 +1,26 @@
 <?php
 
 class MWFunctionTest extends MediaWikiTestCase {
-       
        function testCallUserFuncWorkarounds() {
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func( array( 'MWFunctionTest', 'someMethod' ) ),
                        MWFunction::call( 'MWFunctionTest::someMethod' )
                );
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func( array( 'MWFunctionTest', 'someMethod' ), 'foo', 'bar', 'baz' ),
                        MWFunction::call( 'MWFunctionTest::someMethod', 'foo', 'bar', 'baz' )
                );
 
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array() ),
                        MWFunction::callArray( 'MWFunctionTest::someMethod', array() )
                );
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array( 'foo', 'bar', 'baz' ) ),
                        MWFunction::callArray( 'MWFunctionTest::someMethod', array( 'foo', 'bar', 'baz' ) )
                );
        }
-       
+
        function testNewObjFunction() {
                $arg1 = 'Foo';
                $arg2 = 'Bar';
@@ -31,36 +30,36 @@ class MWFunctionTest extends MediaWikiTestCase {
                $args = array( $arg1, $arg2, $arg3, $arg4 );
 
                $newObject = new MWBlankClass( $arg1, $arg2, $arg3, $arg4 );
-               $this->assertEquals( 
-                       MWFunction::newObj( 'MWBlankClass', $args )->args, 
+               $this->assertEquals(
+                       MWFunction::newObj( 'MWBlankClass', $args )->args,
                        $newObject->args
                );
 
-               $this->assertEquals( 
-                       MWFunction::newObj( 'MWBlankClass', $args, true )->args, 
+               $this->assertEquals(
+                       MWFunction::newObj( 'MWBlankClass', $args, true )->args,
                        $newObject->args,
                        'Works even with PHP version < 5.1.3'
                );
        }
-       
+
        /**
         * @expectedException MWException
         */
        function testCallingParentFails() {
                MWFunction::call( 'parent::foo' );
        }
-       
+
        /**
         * @expectedException MWException
         */
        function testCallingSelfFails() {
                MWFunction::call( 'self::foo' );
        }
-       
+
        public static function someMethod() {
                return func_get_args();
        }
-       
+
 }
 
 class MWBlankClass {
index 01d406a..45f8daf 100644 (file)
@@ -17,9 +17,9 @@ class MWNamespaceTest extends MediaWikiTestCase {
                $this->setMwGlobals( array(
                        'wgContentNamespaces' => array( NS_MAIN ),
                        'wgNamespacesWithSubpages' => array(
-                               NS_TALK           => true,
-                               NS_USER           => true,
-                               NS_USER_TALK      => true,
+                               NS_TALK => true,
+                               NS_USER => true,
+                               NS_USER_TALK => true,
                        ),
                        'wgCapitalLinks' => true,
                        'wgCapitalLinkOverrides' => array(),
@@ -42,18 +42,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testIsSubject() {
                // Special namespaces
-               $this->assertIsSubject( NS_MEDIA   );
+               $this->assertIsSubject( NS_MEDIA );
                $this->assertIsSubject( NS_SPECIAL );
 
                // Subject pages
                $this->assertIsSubject( NS_MAIN );
                $this->assertIsSubject( NS_USER );
-               $this->assertIsSubject( 100     );  # user defined
+               $this->assertIsSubject( 100 ); # user defined
 
                // Talk pages
-               $this->assertIsNotSubject( NS_TALK      );
+               $this->assertIsNotSubject( NS_TALK );
                $this->assertIsNotSubject( NS_USER_TALK );
-               $this->assertIsNotSubject( 101          ); # user defined
+               $this->assertIsNotSubject( 101 ); # user defined
        }
 
        /**
@@ -62,18 +62,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testIsTalk() {
                // Special namespaces
-               $this->assertIsNotTalk( NS_MEDIA   );
+               $this->assertIsNotTalk( NS_MEDIA );
                $this->assertIsNotTalk( NS_SPECIAL );
 
                // Subject pages
-               $this->assertIsNotTalk( NS_MAIN   );
-               $this->assertIsNotTalk( NS_USER   );
-               $this->assertIsNotTalk( 100       );  # user defined
+               $this->assertIsNotTalk( NS_MAIN );
+               $this->assertIsNotTalk( NS_USER );
+               $this->assertIsNotTalk( 100 ); # user defined
 
                // Talk pages
-               $this->assertIsTalk( NS_TALK      );
+               $this->assertIsTalk( NS_TALK );
                $this->assertIsTalk( NS_USER_TALK );
-               $this->assertIsTalk( 101          ); # user defined
+               $this->assertIsTalk( 101 ); # user defined
        }
 
        /**
@@ -135,7 +135,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
         * @expectedException MWException
         */
        public function testGetAssociatedExceptionsForNsMedia() {
-               $this->assertNull( MWNamespace::getAssociated( NS_MEDIA   ) );
+               $this->assertNull( MWNamespace::getAssociated( NS_MEDIA ) );
        }
 
        /**
@@ -148,14 +148,14 @@ class MWNamespaceTest extends MediaWikiTestCase {
        /**
         * @todo Implement testExists().
         */
-/*
+       /*
        public function testExists() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
 
        /**
         * Test MWNamespace::equals
@@ -189,7 +189,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
                $this->assertSameSubject( NS_USER, NS_USER_TALK );
 
                $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE );
-               $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN     );
+               $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN );
        }
 
        public function testSpecialAndMediaAreDifferentSubjects() {
@@ -207,56 +207,58 @@ class MWNamespaceTest extends MediaWikiTestCase {
        /**
         * @todo Implement testGetCanonicalNamespaces().
         */
-/*
+       /*
        public function testGetCanonicalNamespaces() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
        /**
         * @todo Implement testGetCanonicalName().
         */
-/*
-       public function testGetCanonicalName() {
-               // Remove the following lines when you implement this test.
-               $this->markTestIncomplete(
-                 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
-               );
-       }
-*/
+       /*
+               public function testGetCanonicalName() {
+                       // Remove the following lines when you implement this test.
+                       $this->markTestIncomplete(
+                         'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
+                       );
+               }
+       */
        /**
         * @todo Implement testGetCanonicalIndex().
         */
-/*
+       /*
        public function testGetCanonicalIndex() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
+
        /**
         * @todo Implement testGetValidNamespaces().
         */
-/*
+       /*
        public function testGetValidNamespaces() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
+
        /**
         */
        public function testCanTalk() {
-               $this->assertCanNotTalk( NS_MEDIA   );
+               $this->assertCanNotTalk( NS_MEDIA );
                $this->assertCanNotTalk( NS_SPECIAL );
 
-               $this->assertCanTalk( NS_MAIN      );
-               $this->assertCanTalk( NS_TALK      );
-               $this->assertCanTalk( NS_USER      );
+               $this->assertCanTalk( NS_MAIN );
+               $this->assertCanTalk( NS_TALK );
+               $this->assertCanTalk( NS_USER );
                $this->assertCanTalk( NS_USER_TALK );
 
                // User defined namespaces
@@ -303,7 +305,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
 
        public function testIsWatchable() {
                // Specials namespaces are not watchable
-               $this->assertIsNotWatchable( NS_MEDIA   );
+               $this->assertIsNotWatchable( NS_MEDIA );
                $this->assertIsNotWatchable( NS_SPECIAL );
 
                // Core defined namespaces are watchables
@@ -319,7 +321,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
                global $wgNamespacesWithSubpages;
 
                // Special namespaces:
-               $this->assertHasNotSubpages( NS_MEDIA   );
+               $this->assertHasNotSubpages( NS_MEDIA );
                $this->assertHasNotSubpages( NS_SPECIAL );
 
                // Namespaces without subpages
@@ -332,8 +334,8 @@ class MWNamespaceTest extends MediaWikiTestCase {
                $this->assertHasNotSubpages( NS_MAIN );
 
                // Some namespaces with subpages
-               $this->assertHasSubpages( NS_TALK      );
-               $this->assertHasSubpages( NS_USER      );
+               $this->assertHasSubpages( NS_TALK );
+               $this->assertHasSubpages( NS_USER );
                $this->assertHasSubpages( NS_USER_TALK );
        }
 
@@ -392,7 +394,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testGetSubjectNamespaces() {
                $subjectsNS = MWNamespace::getSubjectNamespaces();
-               $this->assertContains(    NS_MAIN, $subjectsNS,
+               $this->assertContains( NS_MAIN, $subjectsNS,
                        "Talk namespaces should have NS_MAIN" );
                $this->assertNotContains( NS_TALK, $subjectsNS,
                        "Talk namespaces should have NS_TALK" );
@@ -407,7 +409,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testGetTalkNamespaces() {
                $talkNS = MWNamespace::getTalkNamespaces();
-               $this->assertContains(    NS_TALK, $talkNS,
+               $this->assertContains( NS_TALK, $talkNS,
                        "Subject namespaces should have NS_TALK" );
                $this->assertNotContains( NS_MAIN, $talkNS,
                        "Subject namespaces should not have NS_MAIN" );
@@ -426,18 +428,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
                // NS_MEDIA and NS_FILE are treated the same
                $this->assertEquals(
                        MWNamespace::isCapitalized( NS_MEDIA ),
-                       MWNamespace::isCapitalized( NS_FILE  ),
+                       MWNamespace::isCapitalized( NS_FILE ),
                        'NS_MEDIA and NS_FILE have same capitalization rendering'
                );
 
                // Boths are capitalized by default
                $this->assertIsCapitalized( NS_MEDIA );
-               $this->assertIsCapitalized( NS_FILE  );
+               $this->assertIsCapitalized( NS_FILE );
 
                // Always capitalized namespaces
                // @see MWNamespace::$alwaysCapitalizedNamespaces
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
        }
 
@@ -456,18 +458,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
        public function testIsCapitalizedWithWgCapitalLinks() {
                global $wgCapitalLinks;
 
-               $this->assertIsCapitalized( NS_PROJECT      );
+               $this->assertIsCapitalized( NS_PROJECT );
                $this->assertIsCapitalized( NS_PROJECT_TALK );
 
                $wgCapitalLinks = false;
 
                // hardcoded namespaces (see above function) are still capitalized:
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
 
                // setting is correctly applied
-               $this->assertIsNotCapitalized( NS_PROJECT      );
+               $this->assertIsNotCapitalized( NS_PROJECT );
                $this->assertIsNotCapitalized( NS_PROJECT_TALK );
        }
 
@@ -481,27 +483,27 @@ class MWNamespaceTest extends MediaWikiTestCase {
                global $wgCapitalLinkOverrides;
 
                // Test default settings
-               $this->assertIsCapitalized( NS_PROJECT      );
+               $this->assertIsCapitalized( NS_PROJECT );
                $this->assertIsCapitalized( NS_PROJECT_TALK );
 
                // hardcoded namespaces (see above function) are capitalized:
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
 
                // Hardcoded namespaces remains capitalized
-               $wgCapitalLinkOverrides[NS_SPECIAL]   = false;
-               $wgCapitalLinkOverrides[NS_USER]      = false;
+               $wgCapitalLinkOverrides[NS_SPECIAL] = false;
+               $wgCapitalLinkOverrides[NS_USER] = false;
                $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false;
 
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
 
                $wgCapitalLinkOverrides[NS_PROJECT] = false;
                $this->assertIsNotCapitalized( NS_PROJECT );
 
-               $wgCapitalLinkOverrides[NS_PROJECT] = true ;
+               $wgCapitalLinkOverrides[NS_PROJECT] = true;
                $this->assertIsCapitalized( NS_PROJECT );
 
                unset( $wgCapitalLinkOverrides[NS_PROJECT] );
@@ -510,15 +512,14 @@ class MWNamespaceTest extends MediaWikiTestCase {
 
        public function testHasGenderDistinction() {
                // Namespaces with gender distinctions
-               $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER      ) );
+               $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER ) );
                $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER_TALK ) );
 
                // Other ones, "genderless"
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA   ) );
+               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA ) );
                $this->assertFalse( MWNamespace::hasGenderDistinction( NS_SPECIAL ) );
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN    ) );
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK    ) );
-
+               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN ) );
+               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK ) );
        }
 
        public function testIsNonincludable() {
@@ -533,25 +534,25 @@ class MWNamespaceTest extends MediaWikiTestCase {
        ####### HELPERS ###########################################################
        function __call( $method, $args ) {
                // Call the real method if it exists
-               if( method_exists($this, $method ) ) {
+               if ( method_exists( $this, $method ) ) {
                        return $this->$method( $args );
                }
 
-               if( preg_match( '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/', $method, $m ) ) {
+               if ( preg_match( '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/', $method, $m ) ) {
                        # Interprets arguments:
-                       $ns  = $args[0];
-                       $msg = isset($args[1]) ? $args[1] : " dummy message";
+                       $ns = $args[0];
+                       $msg = isset( $args[1] ) ? $args[1] : " dummy message";
 
                        # Forge the namespace constant name:
-                       if( $ns === 0 ) {
+                       if ( $ns === 0 ) {
                                $ns_name = "NS_MAIN";
                        } else {
-                               $ns_name = "NS_" . strtoupper(  MWNamespace::getCanonicalName( $ns ) );
+                               $ns_name = "NS_" . strtoupper( MWNamespace::getCanonicalName( $ns ) );
                        }
                        # ... and the MWNamespace method name
                        $nsMethod = strtolower( $m[1] ) . $m[3];
 
-                       $expect = ($m[2] === '');
+                       $expect = ( $m[2] === '' );
                        $expect_name = $expect ? 'TRUE' : 'FALSE';
 
                        return $this->assertEquals( $expect,
@@ -566,8 +567,8 @@ class MWNamespaceTest extends MediaWikiTestCase {
        function assertSameSubject( $ns1, $ns2, $msg = '' ) {
                $this->assertTrue( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) );
        }
+
        function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
                $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) );
        }
 }
-
index 8b68703..4084fb1 100644 (file)
@@ -26,7 +26,7 @@ class OutputPageTest extends MediaWikiTestCase {
         *
         * @param array $args key-value array of arguments as shown above
         */
-       protected function assertTransformCssMediaCase($args) {
+       protected function assertTransformCssMediaCase( $args ) {
                $queryData = array();
                if ( isset( $args['printableQuery'] ) ) {
                        $queryData['printable'] = $args['printableQuery'];
@@ -38,12 +38,12 @@ class OutputPageTest extends MediaWikiTestCase {
 
                $fauxRequest = new FauxRequest( $queryData, false );
                $this->setMWGlobals( array(
-                               'wgRequest' => $fauxRequest,
-                               'wgHandheldForIPhone' => $args['handheldForIPhone']
+                       'wgRequest' => $fauxRequest,
+                       'wgHandheldForIPhone' => $args['handheldForIPhone']
                ) );
 
                $actualReturn = OutputPage::transformCssMedia( $args['media'] );
-               $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message']);
+               $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message'] );
        }
 
        /**
@@ -55,11 +55,11 @@ class OutputPageTest extends MediaWikiTestCase {
         * @param array $args key-value array of arguments as shown in assertTransformCssMediaCase.
         * Will be mutated.
         */
-       protected function assertTransformCssMediaCaseWithBothHandheldForIPhone($args) {
+       protected function assertTransformCssMediaCaseWithBothHandheldForIPhone( $args ) {
                $message = $args['message'];
-               foreach( array( true, false ) as $handheldForIPhone ) {
+               foreach ( array( true, false ) as $handheldForIPhone ) {
                        $args['handheldForIPhone'] = $handheldForIPhone;
-                       $stringHandheldForIPhone = var_export($handheldForIPhone, true);
+                       $stringHandheldForIPhone = var_export( $handheldForIPhone, true );
                        $args['message'] = "$message. \$wgHandheldForIPhone was $stringHandheldForIPhone";
                        $this->assertTransformCssMediaCase( $args );
                }
@@ -132,14 +132,14 @@ class OutputPageTest extends MediaWikiTestCase {
         * Tests handheld and wgHandheldForIPhone behavior
         */
        public function testHandheld() {
-               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone(array(
+               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array(
                        'handheldQuery' => '1',
                        'media' => 'handheld',
                        'expectedReturn' => '',
                        'message' => 'On request with handheld querystring and media is handheld, returns empty string'
                ) );
 
-               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone(array(
+               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array(
                        'handheldQuery' => '1',
                        'media' => 'screen',
                        'expectedReturn' => null,
@@ -147,7 +147,7 @@ class OutputPageTest extends MediaWikiTestCase {
                ) );
 
                // A bit counter-intuitively, $wgHandheldForIPhone should only matter if the query handheld is false or omitted
-               $this->assertTransformCssMediaCase(array(
+               $this->assertTransformCssMediaCase( array(
                        'handheldQuery' => '0',
                        'media' => 'screen',
                        'handheldForIPhone' => true,
@@ -155,7 +155,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        'message' => 'With $wgHandheldForIPhone true, screen media type is transformed'
                ) );
 
-               $this->assertTransformCssMediaCase(array(
+               $this->assertTransformCssMediaCase( array(
                        'media' => 'handheld',
                        'handheldForIPhone' => true,
                        'expectedReturn' => 'handheld, only screen and (max-device-width: 480px)',
diff --git a/tests/phpunit/includes/ParserOptionsTest.php b/tests/phpunit/includes/ParserOptionsTest.php
deleted file mode 100644 (file)
index 5b2adaf..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-class ParserOptionsTest extends MediaWikiTestCase {
-
-       private $popts;
-       private $pcache;
-
-       protected function setUp() {
-               global $wgLanguageCode, $wgUser;
-               parent::setUp();
-
-               $langObj = Language::factory( $wgLanguageCode );
-
-               $this->setMwGlobals( array(
-                       'wgContLang' => $langObj,
-                       'wgUseDynamicDates' => true,
-               ) );
-
-               $this->popts = ParserOptions::newFromUserAndLang( $wgUser, $langObj );
-               $this->pcache = ParserCache::singleton();
-       }
-
-       /**
-        * ParserOptions::optionsHash was not giving consistent results when $wgUseDynamicDates was set
-        * @group Database
-        */
-       function testGetParserCacheKeyWithDynamicDates() {
-               $title = Title::newFromText( "Some test article" );
-               $page = WikiPage::factory( $title );
-
-               $pcacheKeyBefore = $this->pcache->getKey( $page, $this->popts );
-               $this->assertNotNull( $this->popts->getDateFormat() );
-
-               $pcacheKeyAfter = $this->pcache->getKey( $page, $this->popts );
-               $this->assertEquals( $pcacheKeyBefore, $pcacheKeyAfter );
-       }
-}
index 910743e..2259187 100644 (file)
@@ -8,7 +8,7 @@ class PathRouterTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
                $router = new PathRouter;
-               $router->add("/wiki/$1");
+               $router->add( "/wiki/$1" );
                $this->basicRouter = $router;
        }
 
@@ -25,17 +25,17 @@ class PathRouterTest extends MediaWikiTestCase {
         */
        public function testLoose() {
                $router = new PathRouter;
-               $router->add("/"); # Should be the same as "/$1"
+               $router->add( "/" ); # Should be the same as "/$1"
                $matches = $router->parse( "/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
 
                $router = new PathRouter;
-               $router->add("/wiki"); # Should be the same as /wiki/$1
+               $router->add( "/wiki" ); # Should be the same as /wiki/$1
                $matches = $router->parse( "/wiki/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
 
                $router = new PathRouter;
-               $router->add("/wiki/"); # Should be the same as /wiki/$1
+               $router->add( "/wiki/" ); # Should be the same as /wiki/$1
                $matches = $router->parse( "/wiki/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
        }
@@ -45,16 +45,16 @@ class PathRouterTest extends MediaWikiTestCase {
         */
        public function testOrder() {
                $router = new PathRouter;
-               $router->add("/$1");
-               $router->add("/a/$1");
-               $router->add("/b/$1");
+               $router->add( "/$1" );
+               $router->add( "/a/$1" );
+               $router->add( "/b/$1" );
                $matches = $router->parse( "/a/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
 
                $router = new PathRouter;
-               $router->add("/b/$1");
-               $router->add("/a/$1");
-               $router->add("/$1");
+               $router->add( "/b/$1" );
+               $router->add( "/a/$1" );
+               $router->add( "/$1" );
                $matches = $router->parse( "/a/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
        }
@@ -151,18 +151,18 @@ class PathRouterTest extends MediaWikiTestCase {
                $router->add( array( 'qwerty' => "/qwerty/$1" ), array( 'qwerty' => '$key' ) );
                $router->add( "/$2/$1", array( 'restricted-to-y' => '$2' ), array( '$2' => 'y' ) );
 
-               foreach( array(
-                       "/Foo" => array( 'title' => "Foo" ),
-                       "/Bar" => array( 'ping' => 'pong' ),
-                       "/Baz" => array( 'marco' => 'polo' ),
-                       "/asdf-foo" => array( 'title' => "qwerty-foo" ),
-                       "/qwerty-bar" => array( 'title' => "asdf-bar" ),
-                       "/a/Foo" => array( 'title' => "Foo" ),
-                       "/asdf/Foo" => array( 'title' => "Foo" ),
-                       "/qwerty/Foo" => array( 'title' => "Foo", 'qwerty' => 'qwerty' ),
-                       "/baz/Foo" => array( 'title' => "Foo", 'unrestricted' => 'baz' ),
-                       "/y/Foo" => array( 'title' => "Foo", 'restricted-to-y' => 'y' ),
-               ) as $path => $result ) {
+               foreach ( array(
+                                       '/Foo' => array( 'title' => 'Foo' ),
+                                       '/Bar' => array( 'ping' => 'pong' ),
+                                       '/Baz' => array( 'marco' => 'polo' ),
+                                       '/asdf-foo' => array( 'title' => 'qwerty-foo' ),
+                                       '/qwerty-bar' => array( 'title' => 'asdf-bar' ),
+                                       '/a/Foo' => array( 'title' => 'Foo' ),
+                                       '/asdf/Foo' => array( 'title' => 'Foo' ),
+                                       '/qwerty/Foo' => array( 'title' => 'Foo', 'qwerty' => 'qwerty' ),
+                                       '/baz/Foo' => array( 'title' => 'Foo', 'unrestricted' => 'baz' ),
+                                       '/y/Foo' => array( 'title' => 'Foo', 'restricted-to-y' => 'y' ),
+                               ) as $path => $result ) {
                        $this->assertEquals( $router->parse( $path ), $result );
                }
        }
index 5e546ce..7aa3c4a 100644 (file)
@@ -17,14 +17,14 @@ class PreferencesTest extends MediaWikiTestCase {
                $this->prefUsers['notauth']
                        ->setEmail( 'noauth@example.org' );
 
-               $this->prefUsers['auth']    = new User;
+               $this->prefUsers['auth'] = new User;
                $this->prefUsers['auth']
                        ->setEmail( 'noauth@example.org' );
                $this->prefUsers['auth']
                        ->setEmailAuthenticationTimestamp( 1330946623 );
 
                $this->context = new RequestContext;
-               $this->context->setTitle( Title::newFromText('PreferencesTest') );
+               $this->context->setTitle( Title::newFromText( 'PreferencesTest' ) );
        }
 
        protected function setUp() {
@@ -44,6 +44,7 @@ class PreferencesTest extends MediaWikiTestCase {
                );
                $this->assertEquals( 'mw-email-none', $prefs['emailaddress']['cssclass'] );
        }
+
        /**
         * Placeholder to verify bug 34302
         * @covers Preferences::profilePreferences
@@ -55,6 +56,7 @@ class PreferencesTest extends MediaWikiTestCase {
                );
                $this->assertEquals( 'mw-email-not-authenticated', $prefs['emailaddress']['cssclass'] );
        }
+
        /**
         * Placeholder to verify bug 34302
         * @covers Preferences::profilePreferences
index f451f8a..948b635 100644 (file)
@@ -13,7 +13,7 @@ class MediaWikiProvide {
        /* provide an array of numbers from 1 up to @param $num */
        private static function createProviderUpTo( $num ) {
                $ret = array();
-               for( $i=1; $i<=$num;$i++ ) {
+               for ( $i = 1; $i <= $num; $i++ ) {
                        $ret[] = array( $i );
                }
                return $ret;
@@ -33,9 +33,9 @@ class MediaWikiProvide {
                $ret = array();
 
                $months = self::Months();
-               $days   = self::Days();
-               foreach( $months as $month) {
-                       foreach( $days as $day ) {
+               $days = self::Days();
+               foreach ( $months as $month ) {
+                       foreach ( $days as $day ) {
                                $ret[] = array( $day[0], $month[0] );
                        }
                }
index 5b99628..a1e6236 100644 (file)
@@ -12,9 +12,9 @@ class RecentChangeTest extends MediaWikiTestCase {
        function __construct() {
                parent::__construct();
 
-               $this->title  = Title::newFromText( 'SomeTitle' );
+               $this->title = Title::newFromText( 'SomeTitle' );
                $this->target = Title::newFromText( 'TestTarget' );
-               $this->user   = User::newFromName( 'UserName' );
+               $this->user = User::newFromName( 'UserName' );
 
                $this->user_comment = '<User comment about action>';
                $this->context = RequestContext::newExtraneousContext( $this->title );
@@ -61,14 +61,14 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # block/block
                $this->assertIRCComment(
-                       $this->context->msg( 'blocklogentry', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'blocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'block', 'block',
                        array(),
                        $this->user_comment
                );
                # block/unblock
                $this->assertIRCComment(
-                       $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'block', 'unblock',
                        array(),
                        $this->user_comment
@@ -83,7 +83,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # delete/delete
                $this->assertIRCComment(
-                       $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'delete', 'delete',
                        array(),
                        $this->user_comment
@@ -91,7 +91,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # delete/restore
                $this->assertIRCComment(
-                       $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'delete', 'restore',
                        array(),
                        $this->user_comment
@@ -129,14 +129,14 @@ class RecentChangeTest extends MediaWikiTestCase {
         */
        function testIrcMsgForLogTypeMove() {
                $move_params = array(
-                       '4::target'  => $this->target->getPrefixedText(),
+                       '4::target' => $this->target->getPrefixedText(),
                        '5::noredir' => 0,
                );
                $sep = $this->context->msg( 'colon-separator' )->text();
 
                # move/move
                $this->assertIRCComment(
-                       $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment,
                        'move', 'move',
                        $move_params,
                        $this->user_comment
@@ -144,7 +144,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # move/move_redir
                $this->assertIRCComment(
-                       $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment,
                        'move', 'move_redir',
                        $move_params,
                        $this->user_comment
@@ -160,9 +160,9 @@ class RecentChangeTest extends MediaWikiTestCase {
                        $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(),
                        'patrol', 'patrol',
                        array(
-                               '4::curid'  => '777',
+                               '4::curid' => '777',
                                '5::previd' => '666',
-                               '6::auto'   => 0,
+                               '6::auto' => 0,
                        )
                );
        }
@@ -178,7 +178,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # protect/protect
                $this->assertIRCComment(
-                       $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment,
                        'protect', 'protect',
                        $protectParams,
                        $this->user_comment
@@ -186,7 +186,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # protect/unprotect
                $this->assertIRCComment(
-                       $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'protect', 'unprotect',
                        array(),
                        $this->user_comment
@@ -194,7 +194,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # protect/modify
                $this->assertIRCComment(
-                       $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment,
                        'protect', 'modify',
                        $protectParams,
                        $this->user_comment
@@ -209,7 +209,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # upload/upload
                $this->assertIRCComment(
-                       $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'upload', 'upload',
                        array(),
                        $this->user_comment
@@ -217,7 +217,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # upload/overwrite
                $this->assertIRCComment(
-                       $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'upload', 'overwrite',
                        array(),
                        $this->user_comment
@@ -229,7 +229,7 @@ class RecentChangeTest extends MediaWikiTestCase {
         * raw edit summary from RecentChange object
         * --
         */
-/*
+       /*
        function testIrcMsgForBlankingAES() {
                // $this->context->msg( 'autosumm-blank', .. );
        }
@@ -245,8 +245,7 @@ class RecentChangeTest extends MediaWikiTestCase {
        function testIrcMsgForUndoAES() {
                // $this->context->msg( 'undo-summary', .. );
        }
-
-*/
+       */
 
        /**
         * @param $expected String Expected IRC text without colors codes
index 893d260..60618b1 100644 (file)
@@ -84,7 +84,7 @@ class ResourceLoaderTest extends MediaWikiTestCase {
 
 /* Stubs */
 
-class ResourceLoaderTestModule extends ResourceLoaderModule { }
+class ResourceLoaderTestModule extends ResourceLoaderModule {}
 
 /* Hooks */
 global $wgHooks;
index 4fa42f3..e8d8db0 100644 (file)
@@ -21,21 +21,21 @@ class RevisionStorageTest extends MediaWikiTestCase {
                parent::__construct( $name, $data, $dataName );
 
                $this->tablesUsed = array_merge( $this->tablesUsed,
-                                                array( 'page',
-                                                     'revision',
-                                                     'text',
-
-                                                     'recentchanges',
-                                                     'logging',
-
-                                                     'page_props',
-                                                     'pagelinks',
-                                                     'categorylinks',
-                                                     'langlinks',
-                                                     'externallinks',
-                                                     'imagelinks',
-                                                     'templatelinks',
-                                                     'iwlinks' ) );
+                       array( 'page',
+                               'revision',
+                               'text',
+
+                               'recentchanges',
+                               'logging',
+
+                               'page_props',
+                               'pagelinks',
+                               'categorylinks',
+                               'langlinks',
+                               'externallinks',
+                               'imagelinks',
+                               'templatelinks',
+                               'iwlinks' ) );
        }
 
        public function setUp() {
@@ -43,11 +43,11 @@ class RevisionStorageTest extends MediaWikiTestCase {
 
                parent::setUp();
 
-               $wgExtraNamespaces[ 12312 ] = 'Dummy';
-               $wgExtraNamespaces[ 12313 ] = 'Dummy_talk';
+               $wgExtraNamespaces[12312] = 'Dummy';
+               $wgExtraNamespaces[12313] = 'Dummy_talk';
 
-               $wgNamespaceContentModels[ 12312 ] = 'DUMMY';
-               $wgContentHandlers[ 'DUMMY' ] = 'DummyContentHandlerForTesting';
+               $wgNamespaceContentModels[12312] = 'DUMMY';
+               $wgContentHandlers['DUMMY'] = 'DummyContentHandlerForTesting';
 
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
                $wgContLang->resetNamespaces(); # reset namespace cache
@@ -61,22 +61,32 @@ class RevisionStorageTest extends MediaWikiTestCase {
 
                parent::tearDown();
 
-               unset( $wgExtraNamespaces[ 12312 ] );
-               unset( $wgExtraNamespaces[ 12313 ] );
+               unset( $wgExtraNamespaces[12312] );
+               unset( $wgExtraNamespaces[12313] );
 
-               unset( $wgNamespaceContentModels[ 12312 ] );
-               unset( $wgContentHandlers[ 'DUMMY' ] );
+               unset( $wgNamespaceContentModels[12312] );
+               unset( $wgContentHandlers['DUMMY'] );
 
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
                $wgContLang->resetNamespaces(); # reset namespace cache
        }
 
        protected function makeRevision( $props = null ) {
-               if ( $props === null ) $props = array();
+               if ( $props === null ) {
+                       $props = array();
+               }
 
-               if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) $props['text'] = 'Lorem Ipsum';
-               if ( !isset( $props['comment'] ) ) $props['comment'] = 'just a test';
-               if ( !isset( $props['page'] ) ) $props['page'] = $this->the_page->getId();
+               if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) {
+                       $props['text'] = 'Lorem Ipsum';
+               }
+
+               if ( !isset( $props['comment'] ) ) {
+                       $props['comment'] = 'just a test';
+               }
+
+               if ( !isset( $props['page'] ) ) {
+                       $props['page'] = $this->the_page->getId();
+               }
 
                $rev = new Revision( $props );
 
@@ -89,8 +99,8 @@ class RevisionStorageTest extends MediaWikiTestCase {
        protected function createPage( $page, $text, $model = null ) {
                if ( is_string( $page ) ) {
                        if ( !preg_match( '/:/', $page ) &&
-                               ( $model === null || $model === CONTENT_MODEL_WIKITEXT ) ) {
-
+                               ( $model === null || $model === CONTENT_MODEL_WIKITEXT )
+                       ) {
                                $ns = $this->getDefaultWikitextNS();
                                $page = MWNamespace::getCanonicalName( $ns ) . ':' . $page;
                        }
@@ -127,8 +137,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::__construct
         */
-       public function testConstructFromRow()
-       {
+       public function testConstructFromRow() {
                $orig = $this->makeRevision();
 
                $dbr = wfgetDB( DB_SLAVE );
@@ -146,8 +155,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::newFromRow
         */
-       public function testNewFromRow()
-       {
+       public function testNewFromRow() {
                $orig = $this->makeRevision();
 
                $dbr = wfgetDB( DB_SLAVE );
@@ -166,8 +174,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::newFromArchiveRow
         */
-       public function testNewFromArchiveRow()
-       {
+       public function testNewFromArchiveRow() {
                $page = $this->createPage( 'RevisionStorageTest_testNewFromArchiveRow', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT );
                $orig = $page->getRevision();
                $page->doDeleteArticle( 'test Revision::newFromArchiveRow' );
@@ -187,8 +194,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::newFromId
         */
-       public function testNewFromId()
-       {
+       public function testNewFromId() {
                $orig = $this->makeRevision();
 
                $rev = Revision::newFromId( $orig->getId() );
@@ -199,8 +205,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::fetchRevision
         */
-       public function testFetchRevision()
-       {
+       public function testFetchRevision() {
                $page = $this->createPage( 'RevisionStorageTest_testFetchRevision', 'one', CONTENT_MODEL_WIKITEXT );
                $id1 = $page->getRevision()->getId();
 
@@ -212,41 +217,39 @@ class RevisionStorageTest extends MediaWikiTestCase {
                #note: order is unspecified
                $rows = array();
                while ( ( $row = $res->fetchObject() ) ) {
-                       $rows[ $row->rev_id ]= $row;
+                       $rows[$row->rev_id] = $row;
                }
 
                $row = $res->fetchObject();
-               $this->assertEquals( 1, count($rows), 'expected exactly one revision' );
+               $this->assertEquals( 1, count( $rows ), 'expected exactly one revision' );
                $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 );
        }
 
        /**
         * @covers Revision::selectFields
         */
-       public function testSelectFields()
-       {
+       public function testSelectFields() {
                global $wgContentHandlerUseDB;
 
                $fields = Revision::selectFields();
 
-               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields');
-               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields');
-               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields');
-               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields');
+               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' );
+               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' );
+               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' );
+               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' );
 
                if ( $wgContentHandlerUseDB ) {
                        $this->assertTrue( in_array( 'rev_content_model', $fields ),
-                                                               'missing rev_content_model in list of fields');
+                               'missing rev_content_model in list of fields' );
                        $this->assertTrue( in_array( 'rev_content_format', $fields ),
-                                                               'missing rev_content_format in list of fields');
+                               'missing rev_content_format in list of fields' );
                }
        }
 
        /**
         * @covers Revision::getPage
         */
-       public function testGetPage()
-       {
+       public function testGetPage() {
                $page = $this->the_page;
 
                $orig = $this->makeRevision( array( 'page' => $page->getId() ) );
@@ -258,8 +261,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getText
         */
-       public function testGetText()
-       {
+       public function testGetText() {
                $this->hideDeprecated( 'Revision::getText' );
 
                $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) );
@@ -271,10 +273,9 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getContent
         */
-       public function testGetContent_failure()
-       {
+       public function testGetContent_failure() {
                $rev = new Revision( array(
-                       'page'       =>  $this->the_page->getId(),
+                       'page' => $this->the_page->getId(),
                        'content_model' => $this->the_page->getContentModel(),
                        'text_id' => 123456789, // not in the test DB
                ) );
@@ -290,8 +291,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getContent
         */
-       public function testGetContent()
-       {
+       public function testGetContent() {
                $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) );
                $rev = Revision::newFromId( $orig->getId() );
 
@@ -301,8 +301,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::revText
         */
-       public function testRevText()
-       {
+       public function testRevText() {
                $this->hideDeprecated( 'Revision::revText' );
                $orig = $this->makeRevision( array( 'text' => 'hello hello rev.' ) );
                $rev = Revision::newFromId( $orig->getId() );
@@ -313,8 +312,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getRawText
         */
-       public function testGetRawText()
-       {
+       public function testGetRawText() {
                $this->hideDeprecated( 'Revision::getRawText' );
 
                $orig = $this->makeRevision( array( 'text' => 'hello hello raw.' ) );
@@ -326,8 +324,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getContentModel
         */
-       public function testGetContentModel()
-       {
+       public function testGetContentModel() {
                global $wgContentHandlerUseDB;
 
                if ( !$wgContentHandlerUseDB ) {
@@ -335,7 +332,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                }
 
                $orig = $this->makeRevision( array( 'text' => 'hello hello.',
-                                                                                       'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
+                       'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
                $rev = Revision::newFromId( $orig->getId() );
 
                $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
@@ -344,17 +341,18 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getContentFormat
         */
-       public function testGetContentFormat()
-       {
+       public function testGetContentFormat() {
                global $wgContentHandlerUseDB;
 
                if ( !$wgContentHandlerUseDB ) {
                        $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
                }
 
-               $orig = $this->makeRevision( array( 'text' => 'hello hello.',
-                                                                                       'content_model' => CONTENT_MODEL_JAVASCRIPT,
-                                                                                       'content_format' => CONTENT_FORMAT_JAVASCRIPT ) );
+               $orig = $this->makeRevision( array(
+                       'text' => 'hello hello.',
+                       'content_model' => CONTENT_MODEL_JAVASCRIPT,
+                       'content_format' => CONTENT_FORMAT_JAVASCRIPT
+               ) );
                $rev = Revision::newFromId( $orig->getId() );
 
                $this->assertEquals( CONTENT_FORMAT_JAVASCRIPT, $rev->getContentFormat() );
@@ -363,8 +361,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::isCurrent
         */
-       public function testIsCurrent()
-       {
+       public function testIsCurrent() {
                $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT );
                $rev1 = $page->getRevision();
 
@@ -390,15 +387,14 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getPrevious
         */
-       public function testGetPrevious()
-       {
+       public function testGetPrevious() {
                $page = $this->createPage( 'RevisionStorageTest_testGetPrevious', 'Lorem Ipsum testGetPrevious', CONTENT_MODEL_WIKITEXT );
                $rev1 = $page->getRevision();
 
                $this->assertNull( $rev1->getPrevious() );
 
                $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               'second rev testGetPrevious' );
+                       'second rev testGetPrevious' );
                $rev2 = $page->getRevision();
 
                $this->assertNotNull( $rev2->getPrevious() );
@@ -408,15 +404,14 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getNext
         */
-       public function testGetNext()
-       {
+       public function testGetNext() {
                $page = $this->createPage( 'RevisionStorageTest_testGetNext', 'Lorem Ipsum testGetNext', CONTENT_MODEL_WIKITEXT );
                $rev1 = $page->getRevision();
 
                $this->assertNull( $rev1->getNext() );
 
                $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               'second rev testGetNext' );
+                       'second rev testGetNext' );
                $rev2 = $page->getRevision();
 
                $this->assertNotNull( $rev1->getNext() );
@@ -426,8 +421,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::newNullRevision
         */
-       public function testNewNullRevision()
-       {
+       public function testNewNullRevision() {
                $page = $this->createPage( 'RevisionStorageTest_testNewNullRevision', 'some testing text', CONTENT_MODEL_WIKITEXT );
                $orig = $page->getRevision();
 
@@ -435,9 +429,9 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $rev = Revision::newNullRevision( $dbw, $page->getId(), 'a null revision', false );
 
                $this->assertNotEquals( $orig->getId(), $rev->getId(),
-                                                               'new null revision shold have a different id from the original revision' );
+                       'new null revision shold have a different id from the original revision' );
                $this->assertEquals( $orig->getTextId(), $rev->getTextId(),
-                                                               'new null revision shold have the same text id as the original revision' );
+                       'new null revision shold have the same text id as the original revision' );
                $this->assertEquals( 'some testing text', $rev->getContent()->getNativeData() );
        }
 
@@ -543,7 +537,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $revisions[4]->insertOn( $dbw );
 
                // test it ---------------------------------
-               $since = $revisions[ $sinceIdx ]->getTimestamp();
+               $since = $revisions[$sinceIdx]->getTimestamp();
 
                $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since );
 
index c372c3e..3948e34 100644 (file)
@@ -46,13 +46,13 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
        public function testSelectFields() {
                $fields = Revision::selectFields();
 
-               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields');
-               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields');
-               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields');
-               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields');
+               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' );
+               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' );
+               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' );
+               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' );
 
-               $this->assertFalse( in_array( 'rev_content_model', $fields ), 'missing rev_content_model in list of fields');
-               $this->assertFalse( in_array( 'rev_content_format', $fields ), 'missing rev_content_format in list of fields');
+               $this->assertFalse( in_array( 'rev_content_model', $fields ), 'missing rev_content_model in list of fields' );
+               $this->assertFalse( in_array( 'rev_content_format', $fields ), 'missing rev_content_format in list of fields' );
        }
 
        /**
@@ -61,7 +61,7 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
        public function testGetContentModel() {
                try {
                        $this->makeRevision( array( 'text' => 'hello hello.',
-                                                   'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
+                               'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
 
                        $this->fail( "Creating JavaScript content on a wikitext page should fail with "
                                . "\$wgContentHandlerUseDB disabled" );
@@ -82,8 +82,8 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
                        //       used for this though.
 
                        $this->makeRevision( array( 'text' => 'hello hello.',
-                                                   'content_model' => CONTENT_MODEL_JAVASCRIPT,
-                                                   'content_format' => 'text/javascript' ) );
+                               'content_model' => CONTENT_MODEL_JAVASCRIPT,
+                               'content_format' => 'text/javascript' ) );
 
                        $this->fail( "Creating JavaScript content on a wikitext page should fail with "
                                . "\$wgContentHandlerUseDB disabled" );
@@ -93,5 +93,3 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
        }
 
 }
-
-
index 9cddbe8..db0245b 100644 (file)
@@ -64,16 +64,14 @@ class RevisionTest extends MediaWikiTestCase {
        }
 
        function testGetRevisionTextGzip() {
-               if ( !function_exists( 'gzdeflate' ) ) {
-                       $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' );
-               } else {
-                       $row = new stdClass;
-                       $row->old_flags = 'gzip';
-                       $row->old_text = gzdeflate( 'This is a bunch of revision text.' );
-                       $this->assertEquals(
-                               'This is a bunch of revision text.',
-                               Revision::getRevisionText( $row ) );
-               }
+               $this->checkPHPExtension( 'zlib' );
+
+               $row = new stdClass;
+               $row->old_flags = 'gzip';
+               $row->old_text = gzdeflate( 'This is a bunch of revision text.' );
+               $this->assertEquals(
+                       'This is a bunch of revision text.',
+                       Revision::getRevisionText( $row ) );
        }
 
        function testGetRevisionTextUtf8Native() {
@@ -97,31 +95,27 @@ class RevisionTest extends MediaWikiTestCase {
        }
 
        function testGetRevisionTextUtf8NativeGzip() {
-               if ( !function_exists( 'gzdeflate' ) ) {
-                       $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' );
-               } else {
-                       $row = new stdClass;
-                       $row->old_flags = 'gzip,utf-8';
-                       $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" );
-                       $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
-                       $this->assertEquals(
-                               "Wiki est l'\xc3\xa9cole superieur !",
-                               Revision::getRevisionText( $row ) );
-               }
+               $this->checkPHPExtension( 'zlib' );
+
+               $row = new stdClass;
+               $row->old_flags = 'gzip,utf-8';
+               $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" );
+               $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
+               $this->assertEquals(
+                       "Wiki est l'\xc3\xa9cole superieur !",
+                       Revision::getRevisionText( $row ) );
        }
 
        function testGetRevisionTextUtf8LegacyGzip() {
-               if ( !function_exists( 'gzdeflate' ) ) {
-                       $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' );
-               } else {
-                       $row = new stdClass;
-                       $row->old_flags = 'gzip';
-                       $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" );
-                       $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
-                       $this->assertEquals(
-                               "Wiki est l'\xc3\xa9cole superieur !",
-                               Revision::getRevisionText( $row ) );
-               }
+               $this->checkPHPExtension( 'zlib' );
+
+               $row = new stdClass;
+               $row->old_flags = 'gzip';
+               $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" );
+               $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
+               $this->assertEquals(
+                       "Wiki est l'\xc3\xa9cole superieur !",
+                       Revision::getRevisionText( $row ) );
        }
 
        function testCompressRevisionTextUtf8() {
@@ -139,8 +133,9 @@ class RevisionTest extends MediaWikiTestCase {
        }
 
        function testCompressRevisionTextUtf8Gzip() {
-               global $wgCompressRevisions;
+               $this->checkPHPExtension( 'zlib' );
 
+               global $wgCompressRevisions;
                $wgCompressRevisions = true;
 
                $row = new stdClass;
@@ -173,13 +168,13 @@ class RevisionTest extends MediaWikiTestCase {
 
                $rev = new Revision(
                        array(
-                               'id'         => 42,
-                               'page'       => 23,
-                               'title'      => $title,
+                               'id' => 42,
+                               'page' => 23,
+                               'title' => $title,
 
-                               'content'    => $content,
-                               'length'     => $content->getSize(),
-                               'comment'    => "testing",
+                               'content' => $content,
+                               'length' => $content->getSize(),
+                               'comment' => "testing",
                                'minor_edit' => false,
 
                                'content_format' => $format,
@@ -194,7 +189,7 @@ class RevisionTest extends MediaWikiTestCase {
                return array(
                        array( 'hello world', 'Help:Hello', null, null, CONTENT_MODEL_WIKITEXT ),
                        array( 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, "testing" ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ),
                );
        }
 
@@ -214,7 +209,7 @@ class RevisionTest extends MediaWikiTestCase {
                        array( 'hello world', 'Help:Hello', null, null, CONTENT_FORMAT_WIKITEXT ),
                        array( 'hello world', 'Help:Hello', CONTENT_MODEL_CSS, null, CONTENT_FORMAT_CSS ),
                        array( 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, "testing" ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ),
                );
        }
 
@@ -233,7 +228,7 @@ class RevisionTest extends MediaWikiTestCase {
                return array(
                        array( 'hello world', 'Help:Hello', null, null, 'WikitextContentHandler' ),
                        array( 'hello world', 'User:hello/there.css', null, null, 'CssContentHandler' ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ),
                );
        }
 
@@ -251,8 +246,8 @@ class RevisionTest extends MediaWikiTestCase {
                //NOTE: we expect the help namespace to always contain wikitext
                return array(
                        array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ),
-                       array( serialize('hello world'), 'Hello', "testing", null, Revision::FOR_PUBLIC, serialize('hello world') ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, serialize('hello world') ),
+                       array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ),
                );
        }
 
@@ -271,8 +266,8 @@ class RevisionTest extends MediaWikiTestCase {
                //NOTE: we expect the help namespace to always contain wikitext
                return array(
                        array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ),
-                       array( serialize('hello world'), 'Hello', "testing", null, Revision::FOR_PUBLIC, null ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, null ),
+                       array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, null ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, null ),
                );
        }
 
@@ -301,7 +296,7 @@ class RevisionTest extends MediaWikiTestCase {
        }
 
 
-       public function dataGetSize( ) {
+       public function dataGetSize() {
                return array(
                        array( "hello world.", CONTENT_MODEL_WIKITEXT, 12 ),
                        array( serialize( "hello world." ), "testing", 12 ),
@@ -313,13 +308,12 @@ class RevisionTest extends MediaWikiTestCase {
         * @group Database
         * @dataProvider dataGetSize
         */
-       public function testGetSize( $text, $model, $expected_size )
-       {
+       public function testGetSize( $text, $model, $expected_size ) {
                $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSize', $model );
                $this->assertEquals( $expected_size, $rev->getSize() );
        }
 
-       public function dataGetSha1( ) {
+       public function dataGetSha1() {
                return array(
                        array( "hello world.", CONTENT_MODEL_WIKITEXT, Revision::base36Sha1( "hello world." ) ),
                        array( serialize( "hello world." ), "testing", Revision::base36Sha1( serialize( "hello world." ) ) ),
@@ -331,8 +325,7 @@ class RevisionTest extends MediaWikiTestCase {
         * @group Database
         * @dataProvider dataGetSha1
         */
-       public function testGetSha1( $text, $model, $expected_hash )
-       {
+       public function testGetSha1( $text, $model, $expected_hash ) {
                $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSha1', $model );
                $this->assertEquals( $expected_hash, $rev->getSha1() );
        }
@@ -341,9 +334,9 @@ class RevisionTest extends MediaWikiTestCase {
                $this->hideDeprecated( "Revision::getText" );
 
                $rev = new Revision( array(
-                                         'text' => 'hello world.',
-                                         'content_model' => CONTENT_MODEL_JAVASCRIPT
-                                    ));
+                       'text' => 'hello world.',
+                       'content_model' => CONTENT_MODEL_JAVASCRIPT
+               );
 
                $this->assertNotNull( $rev->getText(), 'no content text' );
                $this->assertNotNull( $rev->getContent(), 'no content object available' );
@@ -357,8 +350,8 @@ class RevisionTest extends MediaWikiTestCase {
                $title = Title::newFromText( 'RevisionTest_testConstructWithContent' );
 
                $rev = new Revision( array(
-                                         'content' => ContentHandler::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT ),
-                                    ));
+                       'content' => ContentHandler::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT ),
+               );
 
                $this->assertNotNull( $rev->getText(), 'no content text' );
                $this->assertNotNull( $rev->getContent(), 'no content object available' );
@@ -371,18 +364,18 @@ class RevisionTest extends MediaWikiTestCase {
         *
         * @group Database
         */
-       function testGetContentClone( ) {
+       function testGetContentClone() {
                $content = new RevisionTestModifyableContent( "foo" );
 
                $rev = new Revision(
                        array(
-                               'id'         => 42,
-                               'page'       => 23,
-                               'title'      => Title::newFromText( "testGetContentClone_dummy" ),
+                               'id' => 42,
+                               'page' => 23,
+                               'title' => Title::newFromText( "testGetContentClone_dummy" ),
 
-                               'content'    => $content,
-                               'length'     => $content->getSize(),
-                               'comment'    => "testing",
+                               'content' => $content,
+                               'length' => $content->getSize(),
+                               'comment' => "testing",
                                'minor_edit' => false,
                        )
                );
@@ -420,7 +413,7 @@ class RevisionTestModifyableContent extends TextContent {
                parent::__construct( $text, "RevisionTestModifyableContent" );
        }
 
-       public function copy( ) {
+       public function copy() {
                return new RevisionTestModifyableContent( $this->mText );
        }
 
@@ -436,7 +429,7 @@ class RevisionTestModifyableContent extends TextContent {
 
 class RevisionTestModifyableContentHandler extends TextContentHandler {
 
-       public function __construct( ) {
+       public function __construct() {
                parent::__construct( "RevisionTestModifyableContent", array( CONTENT_FORMAT_TEXT ) );
        }
 
index 88bbc07..8a88191 100644 (file)
@@ -34,12 +34,12 @@ class TestSample extends MediaWikiLangTestCase {
         * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html
         */
        function testTitleObjectStringConversion() {
-               $title = Title::newFromText("text");
-               $this->assertInstanceOf('Title', $title, "Title creation");
-               $this->assertEquals("Text", $title, "Automatic string conversion");
+               $title = Title::newFromText( "text" );
+               $this->assertInstanceOf( 'Title', $title, "Title creation" );
+               $this->assertEquals( "Text", $title, "Automatic string conversion" );
 
-               $title = Title::newFromText("text", NS_MEDIA);
-               $this->assertEquals("Media:Text", $title, "Title creation with namespace");
+               $title = Title::newFromText( "text", NS_MEDIA );
+               $this->assertEquals( "Media:Text", $title, "Title creation with namespace" );
        }
 
        /**
@@ -62,14 +62,14 @@ class TestSample extends MediaWikiLangTestCase {
         * @dataProvider provideTitles
         * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.dataProvider
         */
-       public function testCreateBasicListOfTitles($titleName, $ns, $text) {
-               $title = Title::newFromText($titleName, $ns);
-               $this->assertEquals($text, "$title", "see if '$titleName' matches '$text'");
+       public function testCreateBasicListOfTitles( $titleName, $ns, $text ) {
+               $title = Title::newFromText( $titleName, $ns );
+               $this->assertEquals( $text, "$title", "see if '$titleName' matches '$text'" );
        }
 
        public function testSetUpMainPageTitleForNextTest() {
                $title = Title::newMainPage();
-               $this->assertEquals("Main Page", "$title", "Test initial creation of a title");
+               $this->assertEquals( "Main Page", "$title", "Test initial creation of a title" );
 
                return $title;
        }
@@ -103,4 +103,3 @@ class TestSample extends MediaWikiLangTestCase {
                $this->assertEquals( "Test", $title->isLocal() );
        }
 }
-
index 28e2e30..9707f49 100644 (file)
@@ -74,9 +74,9 @@ class SanitizerTest extends MediaWikiTestCase {
                        # Enable HTML5 mode
                        'wgHtml5' => true,
                        'wgUseTidy' => false
-               ));
+               ) );
 
-               if( $escaped ) {
+               if ( $escaped ) {
                        $this->assertEquals( "&lt;$tag&gt;",
                                Sanitizer::removeHTMLtags( "<$tag>" )
                        );
@@ -91,8 +91,8 @@ class SanitizerTest extends MediaWikiTestCase {
         * Provide HTML5 tags
         */
        function provideHtml5Tags() {
-               $ESCAPED  = true; # We want tag to be escaped
-               $VERBATIM = false;  # We want to keep the tag
+               $ESCAPED = true; # We want tag to be escaped
+               $VERBATIM = false; # We want to keep the tag
                return array(
                        array( 'data', $VERBATIM ),
                        array( 'mark', $VERBATIM ),
@@ -104,7 +104,7 @@ class SanitizerTest extends MediaWikiTestCase {
        function testSelfClosingTag() {
                $this->setMwGlobals( array(
                        'wgUseTidy' => false
-               ));
+               ) );
 
                $this->assertEquals(
                        '<div>Hello world</div>',
@@ -211,19 +211,40 @@ class SanitizerTest extends MediaWikiTestCase {
                        array( ' ', "\\2f\\2a foo \\2a\\2f",
                                'Backslash-escaped comments must be stripped (bug 28450)' ),
                        array( '', '/* unfinished comment structure',
-                               'Remove anything after a comment-start token' ),
+                               'Remove anything after a comment-start token' ),
                        array( '', "\\2f\\2a unifinished comment'",
-                               'Remove anything after a backslash-escaped comment-start token' ),
-                       array( '/* insecure input */', 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\');'),
-                       array( '/* insecure input */', '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\')";'),
-                       array( '/* insecure input */', 'width: expression(1+1);'),
-                       array( '/* insecure input */', 'background-image: image(asdf.png);'),
-                       array( '/* insecure input */', 'background-image: -webkit-image(asdf.png);'),
-                       array( '/* insecure input */', 'background-image: -moz-image(asdf.png);'),
-                       array( '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);'),
-                       array( '/* insecure input */', 'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);'),
-                       array( '/* insecure input */', 'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);'),
+                               'Remove anything after a backslash-escaped comment-start token' ),
+                       array( '/* insecure input */', 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\');' ),
+                       array( '/* insecure input */', '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\')";' ),
+                       array( '/* insecure input */', 'width: expression(1+1);' ),
+                       array( '/* insecure input */', 'background-image: image(asdf.png);' ),
+                       array( '/* insecure input */', 'background-image: -webkit-image(asdf.png);' ),
+                       array( '/* insecure input */', 'background-image: -moz-image(asdf.png);' ),
+                       array( '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);' ),
+                       array( '/* insecure input */', 'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);' ),
+                       array( '/* insecure input */', 'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);' ),
+               );
+       }
+
+       /**
+        * Test for support or lack of support for specific attributes in the attribute whitelist.
+        */
+       function provideAttributeSupport() {
+               /** array( <attributes>, <expected>, <message> ) */
+               return array(
+                       array( 'div', ' role="presentation"', ' role="presentation"', 'Support for WAI-ARIA\'s role="presentation".' ),
+                       array( 'div', ' role="main"', '', "Other WAI-ARIA roles are currently not supported." ),
                );
        }
-}
 
+       /**
+        * @dataProvider provideAttributeSupport
+        */
+       function testAttributeSupport( $tag, $attributes, $expected, $message ) {
+               $this->assertEquals( $expected,
+                       Sanitizer::fixTagAttributes( $attributes, $tag ),
+                       $message
+               );
+       }
+
+}
index 14d799c..fe0bc64 100644 (file)
@@ -2,17 +2,22 @@
 
 class SanitizerValidateEmailTest extends MediaWikiTestCase {
 
-       private function checkEmail( $addr, $expected = true, $msg = '') {
-               if( $msg == '' ) { $msg = "Testing $addr"; }
+       private function checkEmail( $addr, $expected = true, $msg = '' ) {
+               if ( $msg == '' ) {
+                       $msg = "Testing $addr";
+               }
+
                $this->assertEquals(
                        $expected,
                        Sanitizer::validateEmail( $addr ),
                        $msg
                );
        }
+
        private function valid( $addr, $msg = '' ) {
                $this->checkEmail( $addr, true, $msg );
        }
+
        private function invalid( $addr, $msg = '' ) {
                $this->checkEmail( $addr, false, $msg );
        }
@@ -21,41 +26,49 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase {
                $this->valid( 'user@example.com' );
                $this->valid( 'user@example.museum' );
        }
+
        function testEmailWithUpperCaseCharactersAreValid() {
                $this->valid( 'USER@example.com' );
                $this->valid( 'user@EXAMPLE.COM' );
                $this->valid( 'user@Example.com' );
                $this->valid( 'USER@eXAMPLE.com' );
        }
+
        function testEmailWithAPlusInUserName() {
                $this->valid( 'user+sub@example.com' );
                $this->valid( 'user+@example.com' );
        }
+
        function testEmailDoesNotNeedATopLevelDomain() {
                $this->valid( "user@localhost" );
                $this->valid( "FooBar@localdomain" );
                $this->valid( "nobody@mycompany" );
        }
+
        function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() {
                $this->invalid( " user@host.com" );
                $this->invalid( "user@host.com " );
                $this->invalid( "\tuser@host.com" );
                $this->invalid( "user@host.com\t" );
        }
+
        function testEmailWithWhiteSpacesAreInvalids() {
                $this->invalid( "User user@host" );
                $this->invalid( "first last@mycompany" );
                $this->invalid( "firstlast@my company" );
        }
+
        // bug 26948 : comma were matched by an incorrect regexp range
        function testEmailWithCommasAreInvalids() {
                $this->invalid( "user,foo@example.org" );
                $this->invalid( "userfoo@ex,ample.org" );
        }
+
        function testEmailWithHyphens() {
                $this->valid( "user-foo@example.org" );
                $this->valid( "userfoo@ex-ample.org" );
        }
+
        function testEmailDomainCanNotBeginWithDot() {
                $this->invalid( "user@." );
                $this->invalid( "user@.localdomain" );
@@ -64,15 +77,19 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase {
                $this->valid( ".@localdomain" );
                $this->invalid( ".@a............" );
        }
+
        function testEmailWithFunnyCharacters() {
                $this->valid( "\$user!ex{this}@123.com" );
        }
+
        function testEmailTopLevelDomainCanBeNumerical() {
                $this->valid( "user@example.1234" );
        }
+
        function testEmailWithoutAtSignIsInvalid() {
                $this->invalid( 'useràexample.com' );
        }
+
        function testEmailWithOneCharacterDomainIsValid() {
                $this->valid( 'user@a' );
        }
index 8f6aafa..3422c90 100644 (file)
@@ -11,8 +11,7 @@ class SeleniumConfigurationTest extends MediaWikiTestCase {
        /**
         * String containing the a sample selenium settings
         */
-       private $testConfig0 =
-'
+       private $testConfig0 = '
 [SeleniumSettings]
 browsers[firefox]      = "*firefox"
 browsers[iexplorer] = "*iexploreproxy"
@@ -35,20 +34,20 @@ testSuite[TestSuiteName] = "testSuitePath"
        /**
         * Array of expected browsers from $testConfig0
         */
-       private $testBrowsers0 = array( 'firefox' => '*firefox',
-                                                       'iexplorer' => '*iexploreproxy',
-                                                       'chrome' => '*chrome'
+       private $testBrowsers0 = array( 'firefox' => '*firefox',
+               'iexplorer' => '*iexploreproxy',
+               'chrome' => '*chrome'
        );
        /**
         * Array of expected selenium settings from $testConfig0
         */
        private $testSettings0 = array(
-               'host'                  => 'localhost',
-               'port'                  => 'foobarr',
-               'wikiUrl'               => 'http://localhost/deployment',
-               'username'              => 'xxxxxxx',
-               'userPassword'  => '',
-               'testBrowser'   => 'chrome',
+               'host' => 'localhost',
+               'port' => 'foobarr',
+               'wikiUrl' => 'http://localhost/deployment',
+               'username' => 'xxxxxxx',
+               'userPassword' => '',
+               'testBrowser' => 'chrome',
                'startserver' => null,
                'stopserver' => null,
                'seleniumserverexecpath' => null,
@@ -59,16 +58,15 @@ testSuite[TestSuiteName] = "testSuitePath"
         * Array of expected testSuites from $testConfig0
         */
        private $testSuites0 = array(
-               'SimpleSeleniumTestSuite'       => 'tests/selenium/SimpleSeleniumTestSuite.php',
-               'TestSuiteName'                         => 'testSuitePath'
+               'SimpleSeleniumTestSuite' => 'tests/selenium/SimpleSeleniumTestSuite.php',
+               'TestSuiteName' => 'testSuitePath'
        );
 
-
        /**
         * Another sample selenium settings file contents
         */
        private $testConfig1 =
-'
+               '
 [SeleniumSettings]
 host                           = "localhost"
 testBrowser            = "firefox"
@@ -81,12 +79,12 @@ testBrowser                 = "firefox"
         * Expected selenium settings from $testConfig1
         */
        private $testSettings1 = array(
-               'host'                  => 'localhost',
-               'port'                  => null,
-               'wikiUrl'               => null,
-               'username'              => null,
-               'userPassword'  => null,
-               'testBrowser'   => 'firefox',
+               'host' => 'localhost',
+               'port' => null,
+               'wikiUrl' => null,
+               'username' => null,
+               'userPassword' => null,
+               'testBrowser' => 'firefox',
                'startserver' => null,
                'stopserver' => null,
                'seleniumserverexecpath' => null,
@@ -126,11 +124,10 @@ testBrowser               = "firefox"
                $seleniumBrowsers = array();
                $seleniumTestSuites = array();
 
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
                        $seleniumTestSuites,
                        "Some_fake_settings_file.ini" );
-
        }
 
        /**
@@ -143,9 +140,9 @@ testBrowser                 = "firefox"
                $seleniumTestSuites = array();
                global $wgSeleniumConfigFile;
                $wgSeleniumConfigFile = '';
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
-                       $seleniumTestSuites);
+                       $seleniumTestSuites );
        }
 
        /**
@@ -158,17 +155,17 @@ testBrowser               = "firefox"
                global $wgSeleniumConfigFile;
                $this->writeToTempFile( $this->testConfig0 );
                $wgSeleniumConfigFile = $this->tempFileName;
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
-                       $seleniumTestSuites);
-               $this->assertEquals($seleniumSettings, $this->testSettings0 ,
-               'The selenium settings should have been read from the file defined in $wgSeleniumConfigFile'
+                       $seleniumTestSuites );
+               $this->assertEquals( $seleniumSettings, $this->testSettings0,
+                       'The selenium settings should have been read from the file defined in $wgSeleniumConfigFile'
                );
-               $this->assertEquals($seleniumBrowsers, $this->testBrowsers0,
-               'The available browsers should have been read from the file defined in $wgSeleniumConfigFile'
+               $this->assertEquals( $seleniumBrowsers, $this->testBrowsers0,
+                       'The available browsers should have been read from the file defined in $wgSeleniumConfigFile'
                );
-               $this->assertEquals($seleniumTestSuites, $this->testSuites0,
-               'The test suites should have been read from the file defined in $wgSeleniumConfigFile'
+               $this->assertEquals( $seleniumTestSuites, $this->testSuites0,
+                       'The test suites should have been read from the file defined in $wgSeleniumConfigFile'
                );
        }
 
@@ -176,54 +173,50 @@ testBrowser               = "firefox"
         * @group SeleniumFramework
         * @dataProvider sampleConfigs
         */
-       public function testgetSeleniumSettings($sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) {
+       public function testgetSeleniumSettings( $sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) {
                $this->writeToTempFile( $sampleConfig );
                $seleniumSettings = array();
                $seleniumBrowsers = array();
                $seleniumTestSuites = null;
 
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
                        $seleniumTestSuites,
                        $this->tempFileName );
 
-               $this->assertEquals($seleniumSettings, $expectedSettings,
-               "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig
+               $this->assertEquals( $seleniumSettings, $expectedSettings,
+                       "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig
                );
-               $this->assertEquals($seleniumBrowsers, $expectedBrowsers,
-               "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig
+               $this->assertEquals( $seleniumBrowsers, $expectedBrowsers,
+                       "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig
                );
-               $this->assertEquals($seleniumTestSuites, $expectedSuites,
-               "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig
+               $this->assertEquals( $seleniumTestSuites, $expectedSuites,
+                       "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig
                );
-
-
        }
 
        /**
         * create a temp file and write text to it.
         * @param $testToWrite the text to write to the temp file
         */
-       private function writeToTempFile($textToWrite) {
-               $this->tempFileName = tempnam(sys_get_temp_dir(), 'test_settings.');
-               $tempFile =      fopen( $this->tempFileName, "w" );
-               fwrite($tempFile , $textToWrite);
-               fclose($tempFile);
+       private function writeToTempFile( $textToWrite ) {
+               $this->tempFileName = tempnam( sys_get_temp_dir(), 'test_settings.' );
+               $tempFile = fopen( $this->tempFileName, "w" );
+               fwrite( $tempFile, $textToWrite );
+               fclose( $tempFile );
        }
 
        /**
         * Returns an array containing:
-        *      The contents of the selenium cingiguration ini file
+        *     The contents of the selenium cingiguration ini file
         *  The expected selenium configuration array that getSeleniumSettings should return
         *  The expected available browsers array that getSeleniumSettings should return
         *  The expected test suites arrya that getSeleniumSettings should return
         */
        public function sampleConfigs() {
                return array(
-                       array($this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ),
-                       array($this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 )
+                       array( $this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ),
+                       array( $this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 )
                );
        }
-
-
 }
index 27c0bb5..fc7d8d0 100644 (file)
@@ -306,7 +306,7 @@ class SiteConfigurationTest extends MediaWikiTestCase {
                $this->assertEquals( $getall['simple'], $GLOBALS['simple'], 'extractAllGlobals(): simple setting' );
                $this->assertEquals( $getall['fallback'], $GLOBALS['fallback'], 'extractAllGlobals(): fallback setting' );
                $this->assertEquals( $getall['params'], $GLOBALS['params'], 'extractAllGlobals(): parameter replacement' );
-               $this->assertEquals( $getall['global'], $GLOBALS['global'],  'extractAllGlobals(): merging with global' );
-               $this->assertEquals( $getall['merge'], $GLOBALS['merge'],  'extractAllGlobals(): merging setting' );
+               $this->assertEquals( $getall['global'], $GLOBALS['global'], 'extractAllGlobals(): merging with global' );
+               $this->assertEquals( $getall['merge'], $GLOBALS['merge'], 'extractAllGlobals(): merging setting' );
        }
 }
index 401b322..31216b3 100644 (file)
@@ -9,8 +9,8 @@ class StringUtilsTest extends MediaWikiTestCase {
         * @cover StringUtils::isUtf8
         * @dataProvider provideStringsForIsUtf8Check
         */
-       function testIsUtf8WithMbstring($expected, $string ) {
-               if( !function_exists( 'mb_check_encoding' ) ) {
+       function testIsUtf8WithMbstring( $expected, $string ) {
+               if ( !function_exists( 'mb_check_encoding' ) ) {
                        $this->markTestSkipped( 'Test requires the mbstring PHP extension' );
                }
                $this->assertEquals( $expected,
@@ -27,7 +27,7 @@ class StringUtilsTest extends MediaWikiTestCase {
         * @cover StringUtils::isUtf8
         * @dataProvider provideStringsForIsUtf8Check
         */
-       function testIsUtf8WithPhpFallbackImplementation($expected, $string ) {
+       function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) {
                $this->assertEquals( $expected,
                        StringUtils::isUtf8( $string, /** disable mbstring: */ true ),
                        'Testing string "' . $this->escaped( $string ) . '" with pure PHP implementation'
@@ -39,11 +39,12 @@ class StringUtilsTest extends MediaWikiTestCase {
         */
        function escaped( $string ) {
                $escaped = '';
-               for($i=0; $i<strlen($string);$i++) {
+               $length = strlen( $string );
+               for ( $i = 0; $i < $length; $i++ ) {
                        $char = $string[$i];
-                       $val = ord($char);
-                       if( $val > 127 ) {
-                               $escaped .='\x' . dechex($val);
+                       $val = ord( $char );
+                       if ( $val > 127 ) {
+                               $escaped .= '\x' . dechex( $val );
                        } else {
                                $escaped .= $char;
                        }
index 07ce84b..a58702b 100644 (file)
@@ -20,14 +20,14 @@ class TimeAdjustTest extends MediaWikiLangTestCase {
                #  Collection of parameters for Language_t_Offset.
                # Format: date to be formatted, localTZoffset value, expected date
                $userAdjust_tests = array(
-                       array( 20061231235959,   0, 20061231235959 ),
-                       array( 20061231235959,   5, 20070101000459 ),
-                       array( 20061231235959,  15, 20070101001459 ),
-                       array( 20061231235959,  60, 20070101005959 ),
-                       array( 20061231235959,  90, 20070101012959 ),
+                       array( 20061231235959, 0, 20061231235959 ),
+                       array( 20061231235959, 5, 20070101000459 ),
+                       array( 20061231235959, 15, 20070101001459 ),
+                       array( 20061231235959, 60, 20070101005959 ),
+                       array( 20061231235959, 90, 20070101012959 ),
                        array( 20061231235959, 120, 20070101015959 ),
                        array( 20061231235959, 540, 20070101085959 ),
-                       array( 20061231235959,  -5, 20061231235459 ),
+                       array( 20061231235959, -5, 20061231235459 ),
                        array( 20061231235959, -30, 20061231232959 ),
                        array( 20061231235959, -60, 20061231225959 ),
                );
index d7da0db..91c23ec 100644 (file)
@@ -14,6 +14,7 @@ class TimestampTest extends MediaWikiTestCase {
                        'wgLang' => Language::factory( 'en' ),
                ) );
        }
+
        /**
         * Test parsing of valid timestamps and outputing to MW format.
         * @dataProvider provideValidTimestamps
@@ -29,7 +30,7 @@ class TimestampTest extends MediaWikiTestCase {
         */
        function testValidOutput( $format, $expected, $original ) {
                $timestamp = new MWTimestamp( $original );
-               $this->assertEquals( $expected, (string) $timestamp->getTimestamp( $format ) );
+               $this->assertEquals( $expected, (string)$timestamp->getTimestamp( $format ) );
        }
 
        /**
index 3a30b12..e2c079a 100644 (file)
@@ -116,7 +116,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createpage" );
                $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createtalk" );
@@ -127,7 +127,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_TALK );
                $this->setUserPerm( "createtalk" );
                $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_TALK );
                $this->setUserPerm( "createpage" );
@@ -142,7 +142,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createpage" );
                $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createtalk" );
@@ -239,7 +239,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        $this->setTitle( NS_MAIN );
                        $this->setUser( 'anon' );
                        $this->setUserPerm( "move" );
-                       $this->runGroupPermissions( 'move', array(  ) );
+                       $this->runGroupPermissions( 'move', array() );
 
                        $this->setUserPerm( "" );
                        $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ),
@@ -250,12 +250,12 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) );
 
                        $this->setUserPerm( "move" );
-                       $this->runGroupPermissions( 'move', array( ) );
+                       $this->runGroupPermissions( 'move', array() );
 
                        $this->setUser( 'anon' );
                        $this->setUserPerm( 'move' );
                        $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-                       $this->assertEquals( array( ), $res );
+                       $this->assertEquals( array(), $res );
 
                        $this->setUserPerm( '' );
                        $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
@@ -266,7 +266,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setUser( $this->userName );
                $this->setUserPerm( array( "move", "move-rootuserpages" ) );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setUserPerm( "move" );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
@@ -275,25 +275,25 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setUser( 'anon' );
                $this->setUserPerm( array( "move", "move-rootuserpages" ) );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_USER, "User/subpage" );
                $this->setUserPerm( array( "move", "move-rootuserpages" ) );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setUserPerm( "move" );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setUser( 'anon' );
                $check = array( 'edit' => array( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ) ),
-                                                                                array( array( 'badaccess-group0' ) ),
-                                                                                array( ), true ),
-                                               'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ),
-                                                                                       array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ),
-                                                                                       array( array( 'protect-cantedit' ) ), false ),
-                                               '' => array( array( ), array( ), array( ), true ) );
+                       array( array( 'badaccess-group0' ) ),
+                       array(), true ),
+                       'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ),
+                               array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ),
+                               array( array( 'protect-cantedit' ) ), false ),
+                       '' => array( array(), array(), array(), true ) );
 
                foreach ( array( "edit", "protect", "" ) as $action ) {
                        $this->setUserPerm( null );
@@ -325,7 +325,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        function runGroupPermissions( $action, $result, $result2 = null ) {
                global $wgGroupPermissions;
 
-               if ( $result2 === null ) $result2 = $result;
+               if ( $result2 === null ) {
+                       $result2 = $result;
+               }
 
                $wgGroupPermissions['autoconfirmed']['move'] = false;
                $wgGroupPermissions['user']['move'] = false;
@@ -355,50 +357,48 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_SPECIAL );
 
                $this->assertEquals( array( array( 'badaccess-group0' ), array( 'ns-specialprotected' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
-               $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'execute', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( 'bogus' );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( '' );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $wgNamespaceProtection[NS_USER] = array( 'bogus' );
 
                $this->setTitle( NS_USER );
                $this->setUserPerm( '' );
                $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MEDIAWIKI );
                $this->setUserPerm( 'bogus' );
                $this->assertEquals( array( array( 'protectedinterface' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MEDIAWIKI );
                $this->setUserPerm( 'bogus' );
                $this->assertEquals( array( array( 'protectedinterface' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $wgNamespaceProtection = null;
 
                $this->setUserPerm( 'bogus' );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'bogus', $this->user ) );
+                       $this->title->userCan( 'bogus', $this->user ) );
 
                $this->setUserPerm( '' );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'bogus', $this->user ) );
+                       $this->title->userCan( 'bogus', $this->user ) );
        }
 
        function testCssAndJavascriptPermissions() {
@@ -414,7 +414,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->runCSSandJSPermissions(
                        array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ),
                        array( array( 'badaccess-group0' ) ),
-                       array( array( 'badaccess-group0' ),  array( 'customcssprotected' ) ) );
+                       array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ) );
 
                $this->setTitle( NS_USER, $this->altUserName . '/tempo' );
                $this->runCSSandJSPermissions(
@@ -426,28 +426,28 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        function runCSSandJSPermissions( $result0, $result1, $result2 ) {
                $this->setUserPerm( '' );
                $this->assertEquals( $result0,
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( 'editusercss' );
                $this->assertEquals( $result1,
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( 'edituserjs' );
                $this->assertEquals( $result2,
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( 'editusercssjs' );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( array( 'edituserjs', 'editusercss' ) );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
        }
 
        function testPageRestrictions() {
@@ -460,65 +460,65 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setUserPerm( "edit" );
                $this->title->mRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) );
 
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
 
                $this->assertEquals( true,
-                                                        $this->title->quickUserCan( 'edit', $this->user ) );
+                       $this->title->quickUserCan( 'edit', $this->user ) );
                $this->title->mRestrictions = array( "edit" => array( 'bogus', "sysop", "protect", "" ),
-                                                                                  "bogus" => array( 'bogus', "sysop", "protect", "" ) );
+                       "bogus" => array( 'bogus', "sysop", "protect", "" ) );
 
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
                $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
                $this->setUserPerm( "" );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
                $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
                $this->setUserPerm( array( "edit", "editprotected" ) );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
-               $this->assertEquals( array(  ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
                $this->title->mCascadeRestriction = true;
                $this->assertEquals( false,
-                                                        $this->title->quickUserCan( 'bogus', $this->user ) );
+                       $this->title->quickUserCan( 'bogus', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->quickUserCan( 'edit', $this->user ) );
+                       $this->title->quickUserCan( 'edit', $this->user ) );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
                $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
        }
 
        function testCascadingSourcesRestrictions() {
@@ -529,15 +529,15 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->title->mCascadingRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) );
 
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'bogus', $this->user ) );
+                       $this->title->userCan( 'bogus', $this->user ) );
                $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ),
-                                                                       array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                               array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'edit', $this->user ) );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
+                       $this->title->userCan( 'edit', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
 
        }
 
@@ -551,60 +551,60 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->title->mCascadeRestriction = false;
 
                $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'create', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'create', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'create', $this->user ) );
+                       $this->title->userCan( 'create', $this->user ) );
 
                $this->title->mTitleProtection['pt_create_perm'] = 'sysop';
                $this->setUserPerm( array( 'createpage', 'protect' ) );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'create', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'create', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'create', $this->user ) );
+                       $this->title->userCan( 'create', $this->user ) );
 
 
                $this->setUserPerm( array( 'createpage' ) );
                $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'create', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'create', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'create', $this->user ) );
+                       $this->title->userCan( 'create', $this->user ) );
 
                $this->setTitle( NS_MEDIA, "test page" );
                $this->setUserPerm( array( "move" ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move', $this->user ) );
+                       $this->title->userCan( 'move', $this->user ) );
                $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move', $this->user ) );
 
                $this->setTitle( NS_HELP, "test page" );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'move', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'move', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'move', $this->user ) );
+                       $this->title->userCan( 'move', $this->user ) );
 
                $this->title->mInterwiki = "no";
                $this->assertEquals( array( array( 'immobile-source-page' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move', $this->user ) );
+                       $this->title->userCan( 'move', $this->user ) );
 
                $this->setTitle( NS_MEDIA, "test page" );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move-target', $this->user ) );
+                       $this->title->userCan( 'move-target', $this->user ) );
                $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
 
                $this->setTitle( NS_HELP, "test page" );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'move-target', $this->user ) );
+                       $this->title->userCan( 'move-target', $this->user ) );
 
                $this->title->mInterwiki = "no";
                $this->assertEquals( array( array( 'immobile-target-page' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move-target', $this->user ) );
+                       $this->title->userCan( 'move-target', $this->user ) );
 
        }
 
@@ -618,28 +618,28 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
 
                # $short
                $this->assertEquals( array( array( 'confirmedittext' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                $wgEmailConfirmToEdit = false;
                $this->assertEquals( true, $this->title->userCan( 'move-target', $this->user ) );
 
                # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target',
-                       $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'move-target',
+                               $this->user ) );
 
                global $wgLang;
                $prev = time();
                $now = time() + 120;
                $this->user->mBlockedby = $this->user->getId();
                $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(),
-                                                                               'no reason given', $prev + 3600, 1, 0 );
+                       'no reason given', $prev + 3600, 1, 0 );
                $this->user->mBlock->mTimestamp = 0;
                $this->assertEquals( array( array( 'autoblockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, 'infinite', '127.0.8.1',
-                       $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ),
+                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                               'Useruser', null, 'infinite', '127.0.8.1',
+                               $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ),
                        $this->title->getUserPermissionsErrors( 'move-target',
-                       $this->user ) );
+                               $this->user ) );
 
                $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) );
                // quickUserCan should ignore user blocks
@@ -650,9 +650,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->user->mBlockedby = $this->user->getName();
                $this->user->mBlock = new Block( '127.0.8.1', 0, 1, 'no reason given', $now, 0, 10 );
                $this->assertEquals( array( array( 'blockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
-                       $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ),
+                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                               'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                               $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ),
                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
 
                # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
index 8647954..3dc5e82 100644 (file)
@@ -6,7 +6,6 @@
  *        ^--- needed for language cache stuff
  */
 class TitleTest extends MediaWikiTestCase {
-
        protected function setUp() {
                parent::setUp();
 
@@ -55,10 +54,10 @@ class TitleTest extends MediaWikiTestCase {
                        array( 'Special:Version/param', 'param' ),
                );
        }
-       
+
        /**
         * Auth-less test of Title::isValidMoveOperation
-        * 
+        *
         * @group Database
         * @param string $source
         * @param string $target
@@ -78,7 +77,121 @@ class TitleTest extends MediaWikiTestCase {
                        }
                }
        }
-       
+
+       /**
+        * Provides test parameter values for testIsValidMoveOperation()
+        */
+       function dataTestIsValidMoveOperation() {
+               return array(
+                       array( 'Test', 'Test', 'selfmove' ),
+                       array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
+               );
+       }
+
+       /**
+        * Auth-less test of Title::userCan
+        *
+        * @param array $whitelistRegexp
+        * @param string $source
+        * @param string $action
+        * @param array|string|true $expected Required error
+        *
+        * @covers Title::checkReadPermission
+        * @dataProvider dataWgWhitelistReadRegexp
+        */
+       function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) {
+               // $wgWhitelistReadRegexp must be an array. Since the provided test cases
+               // usually have only one regex, it is more concise to write the lonely regex
+               // as a string. Thus we cast to an array() to honor $wgWhitelistReadRegexp
+               // type requisite.
+               if ( is_string( $whitelistRegexp ) ) {
+                       $whitelistRegexp = array( $whitelistRegexp );
+               }
+
+               $title = Title::newFromDBkey( $source );
+
+               global $wgGroupPermissions;
+               $oldPermissions = $wgGroupPermissions;
+               // Disallow all so we can ensure our regex works
+               $wgGroupPermissions = array();
+               $wgGroupPermissions['*']['read'] = false;
+
+               global $wgWhitelistRead;
+               $oldWhitelist = $wgWhitelistRead;
+               // Undo any LocalSettings explicite whitelists so they won't cause a
+               // failing test to succeed. Set it to some random non sense just
+               // to make sure we properly test Title::checkReadPermissions()
+               $wgWhitelistRead = array( 'some random non sense title' );
+
+               global $wgWhitelistReadRegexp;
+               $oldWhitelistRegexp = $wgWhitelistReadRegexp;
+               $wgWhitelistReadRegexp = $whitelistRegexp;
+
+               // Just use $wgUser which in test is a user object for '127.0.0.1'
+               global $wgUser;
+               // Invalidate user rights cache to take in account $wgGroupPermissions
+               // change above.
+               $wgUser->clearInstanceCache();
+               $errors = $title->userCan( $action, $wgUser );
+
+               // Restore globals
+               $wgGroupPermissions = $oldPermissions;
+               $wgWhitelistRead = $oldWhitelist;
+               $wgWhitelistReadRegexp = $oldWhitelistRegexp;
+
+               if ( is_bool( $expected ) ) {
+                       # Forge the assertion message depending on the assertion expectation
+                       $allowableness = $expected
+                               ? " should be allowed"
+                               : " should NOT be allowed";
+                       $this->assertEquals( $expected, $errors, "User action '$action' on [[$source]] $allowableness." );
+               } else {
+                       $errors = $this->flattenErrorsArray( $errors );
+                       foreach ( (array)$expected as $error ) {
+                               $this->assertContains( $error, $errors );
+                       }
+               }
+       }
+
+       /**
+        * Provides test parameter values for testWgWhitelistReadRegexp()
+        */
+       function dataWgWhitelistReadRegexp() {
+               $ALLOWED = true;
+               $DISALLOWED = false;
+
+               return array(
+                       // Everything, if this doesn't work, we're really in trouble
+                       array( '/.*/', 'Main_Page', 'read', $ALLOWED ),
+                       array( '/.*/', 'Main_Page', 'edit', $DISALLOWED ),
+
+                       // We validate against the title name, not the db key
+                       array( '/^Main_Page$/', 'Main_Page', 'read', $DISALLOWED ),
+                       // Main page
+                       array( '/^Main/', 'Main_Page', 'read', $ALLOWED ),
+                       array( '/^Main.*/', 'Main_Page', 'read', $ALLOWED ),
+                       // With spaces
+                       array( '/Mic\sCheck/', 'Mic Check', 'read', $ALLOWED ),
+                       // Unicode multibyte
+                       // ...without unicode modifier
+                       array( '/Unicode Test . Yes/', 'Unicode Test Ñ Yes', 'read', $DISALLOWED ),
+                       // ...with unicode modifier
+                       array( '/Unicode Test . Yes/u', 'Unicode Test Ñ Yes', 'read', $ALLOWED ),
+                       // Case insensitive
+                       array( '/MiC ChEcK/', 'mic check', 'read', $DISALLOWED ),
+                       array( '/MiC ChEcK/i', 'mic check', 'read', $ALLOWED ),
+
+                       // From DefaultSettings.php:
+                       array( "@^UsEr.*@i", 'User is banned', 'read', $ALLOWED ),
+                       array( "@^UsEr.*@i", 'User:John Doe', 'read', $ALLOWED ),
+
+                       // With namespaces:
+                       array( '/^Special:NewPages$/', 'Special:NewPages', 'read', $ALLOWED ),
+                       array( null, 'Special:Newpages', 'read', $DISALLOWED ),
+
+               );
+       }
+
        function flattenErrorsArray( $errors ) {
                $result = array();
                foreach ( $errors as $error ) {
@@ -86,9 +199,9 @@ class TitleTest extends MediaWikiTestCase {
                }
                return $result;
        }
-       
+
        public static function provideTestIsValidMoveOperation() {
-               return array( 
+               return array(
                        array( 'Test', 'Test', 'selfmove' ),
                        array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
                );
@@ -130,28 +243,28 @@ class TitleTest extends MediaWikiTestCase {
                        array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ),
                        array( 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ),
 
-                       array( 'es',    'Help:I_need_somebody',      'es', 'zh-tw', 'zh-cn' ),
-                       array( 'es',    'MediaWiki:About',           'es', 'zh-tw', 'zh-cn' ),
-                       array( 'es',    'MediaWiki:About/',          'es', 'zh-tw', 'zh-cn' ),
-                       array( 'de',    'MediaWiki:About/de',        'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.js',       'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.css',      'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Common.js',    'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ),
-
-                       array( 'zh-cn', 'Help:I_need_somebody',      'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh',    'MediaWiki:About',           'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh',    'MediaWiki:About/',          'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'de',    'MediaWiki:About/de',        'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-cn', 'MediaWiki:About/zh-cn',     'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-tw', 'MediaWiki:About/zh-tw',     'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.js',       'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.css',      'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Common.js',    'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ),
-
-                       array( 'zh-tw', 'Special:NewPages',       'es', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-tw', 'Special:NewPages',       'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ),
+
+                       array( 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ),
+
+                       array( 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ),
 
                );
        }
@@ -159,7 +272,7 @@ class TitleTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideBaseTitleCases
         */
-       function testExtractingBaseTextFromTitle( $title, $expected, $msg='' ) {
+       function testExtractingBaseTextFromTitle( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getBaseText(),
@@ -170,15 +283,15 @@ class TitleTest extends MediaWikiTestCase {
        function provideBaseTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'John Doe/subOne' ),
-                       array('User:Foo/Bar/Baz', 'Foo/Bar' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ),
+                       array( 'User:Foo/Bar/Baz', 'Foo/Bar' ),
                );
        }
 
        /**
         * @dataProvider provideRootTitleCases
         */
-       function testExtractingRootTextFromTitle( $title, $expected, $msg='' ) {
+       function testExtractingRootTextFromTitle( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getRootText(),
@@ -189,8 +302,8 @@ class TitleTest extends MediaWikiTestCase {
        public static function provideRootTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'John Doe' ),
-                       array('User:Foo/Bar/Baz', 'Foo' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'John Doe' ),
+                       array( 'User:Foo/Bar/Baz', 'Foo' ),
                );
        }
 
@@ -198,7 +311,7 @@ class TitleTest extends MediaWikiTestCase {
         * @todo Handle $wgNamespacesWithSubpages cases
         * @dataProvider provideSubpageTitleCases
         */
-       function testExtractingSubpageTextFromTitle( $title, $expected, $msg='' ) {
+       function testExtractingSubpageTextFromTitle( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getSubpageText(),
@@ -209,9 +322,8 @@ class TitleTest extends MediaWikiTestCase {
        function provideSubpageTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'subTwo' ),
-                       array('User:John_Doe/subOne', 'subOne' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'subTwo' ),
+                       array( 'User:John_Doe/subOne', 'subOne' ),
                );
        }
-
 }
diff --git a/tests/phpunit/includes/UIDGeneratorTest.php b/tests/phpunit/includes/UIDGeneratorTest.php
new file mode 100644 (file)
index 0000000..23553ca
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+class UIDGeneratorTest extends MediaWikiTestCase {
+       /**
+        * @dataProvider provider_testTimestampedUID
+        */
+       public function testTimestampedUID( $method, $digitlen, $bits, $tbits, $hostbits ) {
+               $id = call_user_func( array( 'UIDGenerator', $method ) );
+               $this->assertEquals( true, ctype_digit( $id ), "UID made of digit characters" );
+               $this->assertLessThanOrEqual( $digitlen, strlen( $id ),
+                       "UID has the right number of digits" );
+               $this->assertLessThanOrEqual( $bits, strlen( wfBaseConvert( $id, 10, 2 ) ),
+                       "UID has the right number of bits" );
+
+               $ids = array();
+               for ( $i = 0; $i < 300; $i++ ) {
+                       $ids[] = call_user_func( array( 'UIDGenerator', $method ) );
+               }
+
+               $lastId = array_shift( $ids );
+               if ( $hostbits ) {
+                       $lastHost = substr( wfBaseConvert( $lastId, 10, 2, $bits ), -$hostbits );
+               }
+
+               $this->assertArrayEquals( array_unique( $ids ), $ids, "All generated IDs are unique." );
+
+               foreach ( $ids as $id ) {
+                       $id_bin = wfBaseConvert( $id, 10, 2 );
+                       $lastId_bin = wfBaseConvert( $lastId, 10, 2 );
+
+                       $this->assertGreaterThanOrEqual(
+                               substr( $id_bin, 0, $tbits ),
+                               substr( $lastId_bin, 0, $tbits ),
+                               "New ID timestamp ($id_bin) >= prior one ($lastId_bin)." );
+
+                       if ( $hostbits ) {
+                               $this->assertEquals(
+                                       substr( $id_bin, 0, -$hostbits ),
+                                       substr( $lastId_bin, 0, -$hostbits ),
+                                       "Host ID of ($id_bin) is same as prior one ($lastId_bin)." );
+                       }
+
+                       $lastId = $id;
+               }
+       }
+
+       /**
+        * array( method, length, bits, hostbits )
+        */
+       public static function provider_testTimestampedUID() {
+               return array(
+                       array( 'newTimestampedUID128', 39, 128, 46, 48 ),
+                       array( 'newTimestampedUID128', 39, 128, 46, 48 ),
+                       array( 'newTimestampedUID88', 27, 88, 46, 32 ),
+               );
+       }
+
+       public function testUUIDv4() {
+               for ( $i = 0; $i < 100; $i++ ) {
+                       $id = UIDGenerator::newUUIDv4();
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ),
+                               "UID $id has the right format" );
+
+                       $id = UIDGenerator::newRawUUIDv4();
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
+                               "UID $id has the right format" );
+
+                       $id = UIDGenerator::newRawUUIDv4( UIDGenerator::QUICK_RAND );
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
+                               "UID $id has the right format" );
+               }
+       }
+}
index e5a014d..e777179 100644 (file)
@@ -7,7 +7,6 @@ define( 'NS_UNITTEST_TALK', 5601 );
  * @group Database
  */
 class UserTest extends MediaWikiTestCase {
-
        /**
         * @var User
         */
@@ -62,6 +61,7 @@ class UserTest extends MediaWikiTestCase {
                $this->assertContains( 'modifytest', $rights );
                $this->assertNotContains( 'nukeworld', $rights );
        }
+
        public function testRevokePermissions() {
                $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) );
                $this->assertNotContains( 'runtest', $rights );
@@ -122,15 +122,15 @@ class UserTest extends MediaWikiTestCase {
                        array( '', false, 'Empty string' ),
                        array( ' ', false, 'Blank space' ),
                        array( 'abcd', false, 'Starts with small letter' ),
-                       array( 'Ab/cd', false,  'Contains slash' ),
-                       array( 'Ab cd' , true, 'Whitespace' ),
-                       array( '192.168.1.1', false,  'IP' ),
+                       array( 'Ab/cd', false, 'Contains slash' ),
+                       array( 'Ab cd', true, 'Whitespace' ),
+                       array( '192.168.1.1', false, 'IP' ),
                        array( 'User:Abcd', false, 'Reserved Namespace' ),
-                       array( '12abcd232' , true  , 'Starts with Numbers' ),
-                       array( '?abcd' , true,  'Start with ? mark' ),
+                       array( '12abcd232', true, 'Starts with Numbers' ),
+                       array( '?abcd', true, 'Start with ? mark' ),
                        array( '#abcd', false, 'Start with #' ),
-                       array( 'Abcdകഖഗഘ', true,  ' Mixed scripts' ),
-                       array( 'ജോസ്‌തോമസ്',  false, 'ZWNJ- Format control character' ),
+                       array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ),
+                       array( 'ജോസ്‌തോമസ്', false, 'ZWNJ- Format control character' ),
                        array( 'Ab cd', false, ' Ideographic space' ),
                );
        }
@@ -174,8 +174,8 @@ 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->doEdit( (string) $i, 'test', 0, false, $user );
+               for ( $i = 0; $i < 3; $i++ ) {
+                       $page->doEdit( (string)$i, 'test', 0, false, $user );
                }
 
                $user->clearInstanceCache();
index 153ff78..46f8025 100644 (file)
@@ -212,9 +212,9 @@ class WebRequestTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideLanguageData
         */
-       function testAcceptLang($acceptLanguageHeader, $expectedLanguages, $description) {
+       function testAcceptLang( $acceptLanguageHeader, $expectedLanguages, $description ) {
                $_SERVER = array( 'HTTP_ACCEPT_LANGUAGE' => $acceptLanguageHeader );
                $request = new WebRequest();
-               $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description);
+               $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description );
        }
 }
index 9300d4b..2501be3 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 /**
-* @group ContentHandler
-* @group Database
-* ^--- important, causes temporary tables to be used instead of the real database
-* @group medium
-**/
+ * @group ContentHandler
+ * @group Database
+ * ^--- important, causes temporary tables to be used instead of the real database
+ * @group medium
+ **/
 
 class WikiPageTest extends MediaWikiLangTestCase {
 
@@ -13,23 +13,23 @@ class WikiPageTest extends MediaWikiLangTestCase {
        function  __construct( $name = null, array $data = array(), $dataName = '' ) {
                parent::__construct( $name, $data, $dataName );
 
-               $this->tablesUsed = array_merge (
+               $this->tablesUsed = array_merge(
                        $this->tablesUsed,
                        array( 'page',
-                                       'revision',
-                                       'text',
+                               'revision',
+                               'text',
 
-                                       'recentchanges',
-                                       'logging',
+                               'recentchanges',
+                               'logging',
 
-                                       'page_props',
-                                       'pagelinks',
-                                       'categorylinks',
-                                       'langlinks',
-                                       'externallinks',
-                                       'imagelinks',
-                                       'templatelinks',
-                                       'iwlinks' ) );
+                               'page_props',
+                               'pagelinks',
+                               'categorylinks',
+                               'langlinks',
+                               'externallinks',
+                               'imagelinks',
+                               'templatelinks',
+                               'iwlinks' ) );
        }
 
        protected function setUp() {
@@ -72,7 +72,6 @@ class WikiPageTest extends MediaWikiLangTestCase {
                return $p;
        }
 
-
        /**
         * @param String|Title|WikiPage $page
         * @param String $text
@@ -96,8 +95,8 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $title = $page->getTitle();
 
                $content = ContentHandler::makeContent( "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
-                                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
-                                               $title, CONTENT_MODEL_WIKITEXT );
+                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
+                       $title, CONTENT_MODEL_WIKITEXT );
 
                $page->doEditContent( $content, "[[testing]] 1" );
 
@@ -124,8 +123,8 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                # ------------------------
                $content = ContentHandler::makeContent( "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
-                                                                                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
-                                                                                               $title, CONTENT_MODEL_WIKITEXT );
+                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
+                       $title, CONTENT_MODEL_WIKITEXT );
 
                $page->doEditContent( $content, "testing 2" );
 
@@ -155,7 +154,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $page = $this->newPage( $title );
 
                $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
-                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
+                       . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
 
                $page->doEdit( $text, "[[testing]] 1" );
 
@@ -182,7 +181,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                # ------------------------
                $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
-                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
+                       . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
 
                $page->doEdit( $text, "testing 2" );
 
@@ -433,104 +432,104 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                        // any
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '',
-                                       'any',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               '',
+                               'any',
+                               true
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'any',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'any',
+                               true
                        ),
 
                        // comma
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'comma',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'comma',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo, bar',
-                                       'comma',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo, bar',
+                               'comma',
+                               true
                        ),
 
                        // link
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'link',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'link',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo [[bar]]',
-                                       'link',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo [[bar]]',
+                               'link',
+                               true
                        ),
 
                        // redirects
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '#REDIRECT [[bar]]',
-                                       'any',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               '#REDIRECT [[bar]]',
+                               'any',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '#REDIRECT [[bar]]',
-                                       'comma',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               '#REDIRECT [[bar]]',
+                               'comma',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '#REDIRECT [[bar]]',
-                                       'link',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               '#REDIRECT [[bar]]',
+                               'link',
+                               false
                        ),
 
                        // not a content namespace
                        array( 'Talk:WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'any',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'any',
+                               false
                        ),
                        array( 'Talk:WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo, bar',
-                                       'comma',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo, bar',
+                               'comma',
+                               false
                        ),
                        array( 'Talk:WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo [[bar]]',
-                                       'link',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo [[bar]]',
+                               'link',
+                               false
                        ),
 
                        // not a content namespace, different model
                        array( 'MediaWiki:WikiPageTest_testIsCountable.js',
-                                       null,
-                                       'Foo',
-                                       'any',
-                                       false
+                               null,
+                               'Foo',
+                               'any',
+                               false
                        ),
                        array( 'MediaWiki:WikiPageTest_testIsCountable.js',
-                                       null,
-                                       'Foo, bar',
-                                       'comma',
-                                       false
+                               null,
+                               'Foo, bar',
+                               'comma',
+                               false
                        ),
                        array( 'MediaWiki:WikiPageTest_testIsCountable.js',
-                                       null,
-                                       'Foo [[bar]]',
-                                       'link',
-                                       false
+                               null,
+                               'Foo [[bar]]',
+                               'link',
+                               false
                        ),
                );
        }
@@ -553,7 +552,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                $page = $this->createPage( $title, $text, $model );
                $hasLinks = wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1,
-                                       array( 'pl_from' => $page->getId() ), __METHOD__ );
+                       array( 'pl_from' => $page->getId() ), __METHOD__ );
 
                $editInfo = $page->prepareContentForEdit( $page->getContent() );
 
@@ -561,15 +560,15 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $w = $page->isCountable( $editInfo );
 
                $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true )
-                                                                                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
+                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
 
                $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
-                                                                                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
+                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
        }
 
        public static function provideGetParserOutput() {
                return array(
-                       array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>"),
+                       array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ),
                        // @todo: more...?
                );
        }
@@ -591,9 +590,9 @@ class WikiPageTest extends MediaWikiLangTestCase {
                return $po;
        }
 
-       public function testGetParserOutput_nonexisting( ) {
+       public function testGetParserOutput_nonexisting() {
                static $count = 0;
-               $count ++;
+               $count++;
 
                $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) );
 
@@ -603,7 +602,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
        }
 
-       public function testGetParserOutput_badrev( ) {
+       public function testGetParserOutput_badrev() {
                $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT );
 
                $opt = new ParserOptions();
@@ -633,46 +632,46 @@ more stuff
                //NOTE: assume the Help namespace to contain wikitext
                return array(
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "0",
-                                       "No more",
-                                       null,
-                                       trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "0",
+                               "No more",
+                               null,
+                               trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "",
-                                       "No more",
-                                       null,
-                                       "No more"
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "",
+                               "No more",
+                               null,
+                               "No more"
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "2",
-                                       "== TEST ==\nmore fun",
-                                       null,
-                                       trim( preg_replace( '/^== test ==.*== foo ==/sm',
-                                                                               "== TEST ==\nmore fun\n\n== foo ==",
-                                                                               WikiPageTest::$sections ) )
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "2",
+                               "== TEST ==\nmore fun",
+                               null,
+                               trim( preg_replace( '/^== test ==.*== foo ==/sm',
+                                       "== TEST ==\nmore fun\n\n== foo ==",
+                                       WikiPageTest::$sections ) )
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "8",
-                                       "No more",
-                                       null,
-                                       trim( WikiPageTest::$sections )
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "8",
+                               "No more",
+                               null,
+                               trim( WikiPageTest::$sections )
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "new",
-                                       "No more",
-                                       "New",
-                                       trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "new",
+                               "No more",
+                               "New",
+                               trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
                        ),
                );
        }
@@ -704,71 +703,71 @@ more stuff
 
        /* @todo FIXME: fix this!
        public function testGetUndoText() {
-               $this->checkHasDiff3();
+       $this->checkHasDiff3();
 
-               $text = "one";
-               $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
-               $rev1 = $page->getRevision();
+       $text = "one";
+       $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
+       $rev1 = $page->getRevision();
 
-               $text .= "\n\ntwo";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
-               $rev2 = $page->getRevision();
+       $text .= "\n\ntwo";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
+       $rev2 = $page->getRevision();
 
-               $text .= "\n\nthree";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
-               $rev3 = $page->getRevision();
+       $text .= "\n\nthree";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
+       $rev3 = $page->getRevision();
 
-               $text .= "\n\nfour";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
-               $rev4 = $page->getRevision();
+       $text .= "\n\nfour";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
+       $rev4 = $page->getRevision();
 
-               $text .= "\n\nfive";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
-               $rev5 = $page->getRevision();
+       $text .= "\n\nfive";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
+       $rev5 = $page->getRevision();
 
-               $text .= "\n\nsix";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
-               $rev6 = $page->getRevision();
+       $text .= "\n\nsix";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
+       $rev6 = $page->getRevision();
 
-               $undo6 = $page->getUndoText( $rev6 );
-               if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
-               $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
+       $undo6 = $page->getUndoText( $rev6 );
+       if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
+       $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
 
-               $undo3 = $page->getUndoText( $rev4, $rev2 );
-               if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
-               $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
+       $undo3 = $page->getUndoText( $rev4, $rev2 );
+       if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
+       $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
 
-               $undo2 = $page->getUndoText( $rev2 );
-               if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
-               $this->assertEquals( "one\n\nfive", $undo2 );
+       $undo2 = $page->getUndoText( $rev2 );
+       if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
+       $this->assertEquals( "one\n\nfive", $undo2 );
        }
-       */
+        */
 
        /**
         * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason.
         */
        public function broken_testDoRollback() {
                $admin = new User();
-               $admin->setName("Admin");
+               $admin->setName( "Admin" );
 
                $text = "one";
                $page = $this->newPage( "WikiPageTest_testDoRollback" );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
-                                                               "section one", EDIT_NEW, false, $admin );
+                       "section one", EDIT_NEW, false, $admin );
 
                $user1 = new User();
                $user1->setName( "127.0.1.11" );
                $text .= "\n\ntwo";
                $page = new WikiPage( $page->getTitle() );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
-                                                               "adding section two", 0, false, $user1 );
+                       "adding section two", 0, false, $user1 );
 
                $user2 = new User();
                $user2->setName( "127.0.2.13" );
                $text .= "\n\nthree";
                $page = new WikiPage( $page->getTitle() );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
-                                                               "adding section three", 0, false, $user2 );
+                       "adding section three", 0, false, $user2 );
 
                # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing
                # or not committed under some circumstances. so, make sure the last revision has the right user name.
@@ -796,7 +795,7 @@ more stuff
 
                $page = new WikiPage( $page->getTitle() );
                $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
-                                                               "rollback did not revert to the correct revision" );
+                       "rollback did not revert to the correct revision" );
                $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
        }
 
@@ -805,12 +804,12 @@ more stuff
         */
        public function testDoRollback() {
                $admin = new User();
-               $admin->setName("Admin");
+               $admin->setName( "Admin" );
 
                $text = "one";
                $page = $this->newPage( "WikiPageTest_testDoRollback" );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               "section one", EDIT_NEW, false, $admin );
+                       "section one", EDIT_NEW, false, $admin );
                $rev1 = $page->getRevision();
 
                $user1 = new User();
@@ -818,7 +817,7 @@ more stuff
                $text .= "\n\ntwo";
                $page = new WikiPage( $page->getTitle() );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               "adding section two", 0, false, $user1 );
+                       "adding section two", 0, false, $user1 );
 
                # now, try the rollback
                $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
@@ -831,11 +830,11 @@ more stuff
 
                $page = new WikiPage( $page->getTitle() );
                $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
-                                                       "rollback did not revert to the correct revision" );
+                       "rollback did not revert to the correct revision" );
                $this->assertEquals( "one", $page->getContent()->getNativeData() );
        }
 
-       public static function provideGetAutosummary( ) {
+       public static function provideGetAutosummary() {
                return array(
                        array(
                                'Hello there, world!',
@@ -887,10 +886,10 @@ more stuff
                $summary = $page->getAutosummary( $old, $new, $flags );
 
                $this->assertTrue( (bool)preg_match( $expected, $summary ),
-                                                       "Autosummary didn't match expected pattern $expected: $summary" );
+                       "Autosummary didn't match expected pattern $expected: $summary" );
        }
 
-       public static function provideGetAutoDeleteReason( ) {
+       public static function provideGetAutoDeleteReason() {
                return array(
                        array(
                                array(),
@@ -927,10 +926,10 @@ more stuff
                        array(
                                array(
                                        array( "first edit: "
-                                                . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
-                                                . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
-                                                . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
-                                                . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
+                                               . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
+                                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
+                                               . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
+                                               . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
                                ),
                                '/first edit:.*\.\.\."/',
                                false
@@ -962,8 +961,11 @@ more stuff
                foreach ( $edits as $edit ) {
                        $user = new User();
 
-                       if ( !empty( $edit[1] ) ) $user->setName( $edit[1] );
-                       else $user = $wgUser;
+                       if ( !empty( $edit[1] ) ) {
+                               $user->setName( $edit[1] );
+                       } else {
+                               $user = $wgUser;
+                       }
 
                        $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
 
@@ -974,12 +976,15 @@ more stuff
 
                $reason = $page->getAutoDeleteReason( $hasHistory );
 
-               if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) $this->assertEquals( $expectedResult, $reason );
-               else $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
-                                                               "Autosummary didn't match expected pattern $expectedResult: $reason" );
+               if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) {
+                       $this->assertEquals( $expectedResult, $reason );
+               } else {
+                       $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
+                               "Autosummary didn't match expected pattern $expectedResult: $reason" );
+               }
 
                $this->assertEquals( $expectedHistory, $hasHistory,
-                                                       "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
+                       "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
 
                $page->doDeleteArticle( "done" );
        }
@@ -987,10 +992,10 @@ more stuff
        public static function providePreSaveTransform() {
                return array(
                        array( 'hello this is ~~~',
-                                       "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
+                               "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
                        ),
                        array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
-                                       'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
+                               'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
                        ),
                );
        }
@@ -1001,7 +1006,7 @@ more stuff
        public function testPreSaveTransform( $text, $expected ) {
                $this->hideDeprecated( 'WikiPage::preSaveTransform' );
                $user = new User();
-               $user->setName("127.0.0.1");
+               $user->setName( "127.0.0.1" );
 
                //NOTE: assume Help namespace to contain wikitext
                $page = $this->newPage( "Help:WikiPageTest_testPreloadTransform" );
@@ -1011,4 +1016,3 @@ more stuff
        }
 
 }
-
index 7c9cbe3..d7227b4 100644 (file)
@@ -9,9 +9,10 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->setMwGlobals( array(
                        'wgHtml5' => true,
                        'wgWellFormedXml' => true,
-               ));
+               ) );
                $this->select = new XmlSelect();
        }
+
        protected function tearDown() {
                parent::tearDown();
                $this->select = null;
@@ -49,14 +50,14 @@ class XmlSelectTest extends MediaWikiTestCase {
                         * See http://en.wikipedia.org/wiki/Gray_code
                         */
                        #      $name   $id    $default
-                       array( false , false, false,  '<select></select>' ),
-                       array( false , false, 'foo',  '<select></select>' ),
-                       array( false , 'id' , 'foo',  '<select id="id"></select>' ),
-                       array( false , 'id' , false,  '<select id="id"></select>' ),
-                       array( 'name', 'id' , false,  '<select name="name" id="id"></select>' ),
-                       array( 'name', 'id' , 'foo',  '<select name="name" id="id"></select>' ),
-                       array( 'name', false, 'foo',  '<select name="name"></select>' ),
-                       array( 'name', false, false,  '<select name="name"></select>' ),
+                       array( false, false, false, '<select></select>' ),
+                       array( false, false, 'foo', '<select></select>' ),
+                       array( false, 'id', 'foo', '<select id="id"></select>' ),
+                       array( false, 'id', false, '<select id="id"></select>' ),
+                       array( 'name', 'id', false, '<select name="name" id="id"></select>' ),
+                       array( 'name', 'id', 'foo', '<select name="name" id="id"></select>' ),
+                       array( 'name', false, 'foo', '<select name="name"></select>' ),
+                       array( 'name', false, false, '<select name="name"></select>' ),
                );
        }
 
@@ -65,18 +66,22 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->select->addOption( 'foo' );
                $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() );
        }
+
        public function testAddOptionWithDefault() {
                $this->select->addOption( 'foo', true );
                $this->assertEquals( '<select><option value="1">foo</option></select>', $this->select->getHTML() );
        }
+
        public function testAddOptionWithFalse() {
                $this->select->addOption( 'foo', false );
                $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() );
        }
+
        public function testAddOptionWithValueZero() {
                $this->select->addOption( 'foo', 0 );
                $this->assertEquals( '<select><option value="0">foo</option></select>', $this->select->getHTML() );
        }
+
        # End XmlSelect::addOption() similar to Xml::option
 
        public function testSetDefault() {
@@ -85,9 +90,9 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->select->addOption( 'bar1' );
                $this->select->addOption( 'foo2' );
                $this->assertEquals(
-'<select><option value="foo1">foo1</option>' . "\n" .
-'<option value="bar1" selected="">bar1</option>' . "\n" .
-'<option value="foo2">foo2</option></select>', $this->select->getHTML() );
+                       '<select><option value="foo1">foo1</option>' . "\n" .
+                               '<option value="bar1" selected="">bar1</option>' . "\n" .
+                               '<option value="foo2">foo2</option></select>', $this->select->getHTML() );
        }
 
        /**
@@ -101,9 +106,9 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->select->addOption( 'foo2' );
                $this->select->setDefault( 'bar1' ); # setting default after adding options
                $this->assertEquals(
-'<select><option value="foo1">foo1</option>' . "\n" .
-'<option value="bar1" selected="">bar1</option>' . "\n" .
-'<option value="foo2">foo2</option></select>', $this->select->getHTML() );
+                       '<select><option value="foo1">foo1</option>' . "\n" .
+                               '<option value="bar1" selected="">bar1</option>' . "\n" .
+                               '<option value="foo2">foo2</option></select>', $this->select->getHTML() );
        }
 
        public function testGetAttributes() {
@@ -135,7 +140,7 @@ class XmlSelectTest extends MediaWikiTestCase {
                # verify string / integer
                $this->assertEquals(
                        $this->select->getAttribute( '1911' ),
-                       'razor' 
+                       'razor'
                );
                $this->assertEquals(
                        $this->select->getAttribute( 'dummy' ),
index b54731b..f482328 100644 (file)
@@ -11,20 +11,20 @@ class XmlTest extends MediaWikiTestCase {
                $langObj->setNamespaces( array(
                        -2 => 'Media',
                        -1 => 'Special',
-                       0  => '',
-                       1  => 'Talk',
-                       2  => 'User',
-                       3  => 'User_talk',
-                       4  => 'MyWiki',
-                       5  => 'MyWiki_Talk',
-                       6  => 'File',
-                       7  => 'File_talk',
-                       8  => 'MediaWiki',
-                       9  => 'MediaWiki_talk',
-                       10  => 'Template',
-                       11  => 'Template_talk',
-                       100  => 'Custom',
-                       101  => 'Custom_talk',
+                       0 => '',
+                       1 => 'Talk',
+                       2 => 'User',
+                       3 => 'User_talk',
+                       4 => 'MyWiki',
+                       5 => 'MyWiki_Talk',
+                       6 => 'File',
+                       7 => 'File_talk',
+                       8 => 'MediaWiki',
+                       9 => 'MediaWiki_talk',
+                       10 => 'Template',
+                       11 => 'Template_talk',
+                       100 => 'Custom',
+                       101 => 'Custom_talk',
                ) );
 
                $this->setMwGlobals( array(
@@ -35,7 +35,7 @@ class XmlTest extends MediaWikiTestCase {
        }
 
        public function testExpandAttributes() {
-               $this->assertNull( Xml::expandAttributes(null),
+               $this->assertNull( Xml::expandAttributes( null ),
                        'Converting a null list of attributes'
                );
                $this->assertEquals( '', Xml::expandAttributes( array() ),
@@ -44,8 +44,8 @@ class XmlTest extends MediaWikiTestCase {
        }
 
        public function testExpandAttributesException() {
-               $this->setExpectedException('MWException');
-               Xml::expandAttributes('string');
+               $this->setExpectedException( 'MWException' );
+               Xml::expandAttributes( 'string' );
        }
 
        function testElementOpen() {
@@ -71,6 +71,7 @@ class XmlTest extends MediaWikiTestCase {
                        'Input with a value of 0 (bug 23797)'
                );
        }
+
        function testElementEscaping() {
                $this->assertEquals(
                        '<element>hello &lt;there&gt; you &amp; you</element>',
@@ -105,53 +106,57 @@ class XmlTest extends MediaWikiTestCase {
                $this->assertEquals( '</element>', Xml::closeElement( 'element' ), 'closeElement() shortcut' );
        }
 
-       public function testDateMenu( ) {
-               $curYear   = intval(gmdate('Y'));
-               $prevYear  = $curYear - 1;
+       public function testDateMenu() {
+               $curYear = intval( gmdate( 'Y' ) );
+               $prevYear = $curYear - 1;
 
-               $curMonth  = intval(gmdate('n'));
+               $curMonth = intval( gmdate( 'n' ) );
                $prevMonth = $curMonth - 1;
-               if( $prevMonth == 0 ) { $prevMonth = 12; }
+               if ( $prevMonth == 0 ) {
+                       $prevMonth = 12;
+               }
                $nextMonth = $curMonth + 1;
-               if( $nextMonth == 13 ) { $nextMonth = 1; }
+               if ( $nextMonth == 13 ) {
+                       $nextMonth = 1;
+               }
 
                $this->assertEquals(
                        '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" .
-'<option value="1">January</option>' . "\n" .
-'<option value="2" selected="">February</option>' . "\n" .
-'<option value="3">March</option>' . "\n" .
-'<option value="4">April</option>' . "\n" .
-'<option value="5">May</option>' . "\n" .
-'<option value="6">June</option>' . "\n" .
-'<option value="7">July</option>' . "\n" .
-'<option value="8">August</option>' . "\n" .
-'<option value="9">September</option>' . "\n" .
-'<option value="10">October</option>' . "\n" .
-'<option value="11">November</option>' . "\n" .
-'<option value="12">December</option></select>',
+                               '<option value="1">January</option>' . "\n" .
+                               '<option value="2" selected="">February</option>' . "\n" .
+                               '<option value="3">March</option>' . "\n" .
+                               '<option value="4">April</option>' . "\n" .
+                               '<option value="5">May</option>' . "\n" .
+                               '<option value="6">June</option>' . "\n" .
+                               '<option value="7">July</option>' . "\n" .
+                               '<option value="8">August</option>' . "\n" .
+                               '<option value="9">September</option>' . "\n" .
+                               '<option value="10">October</option>' . "\n" .
+                               '<option value="11">November</option>' . "\n" .
+                               '<option value="12">December</option></select>',
                        Xml::dateMenu( 2011, 02 ),
                        "Date menu for february 2011"
                );
                $this->assertEquals(
                        '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" .
-'<option value="1">January</option>' . "\n" .
-'<option value="2">February</option>' . "\n" .
-'<option value="3">March</option>' . "\n" .
-'<option value="4">April</option>' . "\n" .
-'<option value="5">May</option>' . "\n" .
-'<option value="6">June</option>' . "\n" .
-'<option value="7">July</option>' . "\n" .
-'<option value="8">August</option>' . "\n" .
-'<option value="9">September</option>' . "\n" .
-'<option value="10">October</option>' . "\n" .
-'<option value="11">November</option>' . "\n" .
-'<option value="12">December</option></select>',
-                       Xml::dateMenu( 2011, -1),
+                               '<option value="1">January</option>' . "\n" .
+                               '<option value="2">February</option>' . "\n" .
+                               '<option value="3">March</option>' . "\n" .
+                               '<option value="4">April</option>' . "\n" .
+                               '<option value="5">May</option>' . "\n" .
+                               '<option value="6">June</option>' . "\n" .
+                               '<option value="7">July</option>' . "\n" .
+                               '<option value="8">August</option>' . "\n" .
+                               '<option value="9">September</option>' . "\n" .
+                               '<option value="10">October</option>' . "\n" .
+                               '<option value="11">November</option>' . "\n" .
+                               '<option value="12">December</option></select>',
+                       Xml::dateMenu( 2011, -1 ),
                        "Date menu with negative month for 'All'"
                );
                $this->assertEquals(
                        Xml::dateMenu( $curYear, $curMonth ),
-                       Xml::dateMenu( ''      , $curMonth ),
+                       Xml::dateMenu( '', $curMonth ),
                        "Date menu year is the current one when not specified"
                );
 
@@ -164,18 +169,18 @@ class XmlTest extends MediaWikiTestCase {
 
                $this->assertEquals(
                        '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" .
-'<option value="1">January</option>' . "\n" .
-'<option value="2">February</option>' . "\n" .
-'<option value="3">March</option>' . "\n" .
-'<option value="4">April</option>' . "\n" .
-'<option value="5">May</option>' . "\n" .
-'<option value="6">June</option>' . "\n" .
-'<option value="7">July</option>' . "\n" .
-'<option value="8">August</option>' . "\n" .
-'<option value="9">September</option>' . "\n" .
-'<option value="10">October</option>' . "\n" .
-'<option value="11">November</option>' . "\n" .
-'<option value="12">December</option></select>',
+                               '<option value="1">January</option>' . "\n" .
+                               '<option value="2">February</option>' . "\n" .
+                               '<option value="3">March</option>' . "\n" .
+                               '<option value="4">April</option>' . "\n" .
+                               '<option value="5">May</option>' . "\n" .
+                               '<option value="6">June</option>' . "\n" .
+                               '<option value="7">July</option>' . "\n" .
+                               '<option value="8">August</option>' . "\n" .
+                               '<option value="9">September</option>' . "\n" .
+                               '<option value="10">October</option>' . "\n" .
+                               '<option value="11">November</option>' . "\n" .
+                               '<option value="12">December</option></select>',
                        Xml::dateMenu( '', '' ),
                        "Date menu with neither year or month"
                );
@@ -210,6 +215,7 @@ class XmlTest extends MediaWikiTestCase {
                        'label() with no attribs'
                );
        }
+
        function testLabelAttributeCanOnlyBeClassOrTitle() {
                $this->assertEquals(
                        '<label for="id">name</label>',
@@ -229,10 +235,10 @@ class XmlTest extends MediaWikiTestCase {
                $this->assertEquals(
                        '<label for="id" class="nice" title="nice tooltip">name</label>',
                        Xml::label( 'name', 'id', array(
-                               'generated' => true,
-                               'class' => 'nice',
-                               'title' => 'nice tooltip',
-                               'anotherattr' => 'value',
+                                       'generated' => true,
+                                       'class' => 'nice',
+                                       'title' => 'nice tooltip',
+                                       'anotherattr' => 'value',
                                )
                        ),
                        'label() skip all attributes but "class" and "title"'
index 9a03d5c..3fea57a 100644 (file)
@@ -29,12 +29,12 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase {
        }
 
        function testMultiDisk0() {
-               $this->readZipAssertError( 'split.zip', 'zip-unsupported', 
+               $this->readZipAssertError( 'split.zip', 'zip-unsupported',
                        'Split zip error' );
        }
 
        function testNoSignature() {
-               $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format', 
+               $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format',
                        'No signature should give "wrong format" error' );
        }
 
@@ -58,7 +58,7 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase {
        }
 
        function testWrongCDStart() {
-               $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported', 
+               $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported',
                        'Wrong CD start disk error' );
        }
 
index 60f6537..af499d1 100644 (file)
@@ -7,8 +7,14 @@
  */
 class ApiCreateAccountTest extends ApiTestCase {
        function setUp() {
+               global $wgHooks;
                parent::setUp();
                LoginForm::setCreateaccountToken();
+
+               $hooks = $wgHooks;
+               Hooks::clear( 'AlternateUserMailer' );
+               $hooks['AlternateUserMailer'] = array( function () { return false; } );
+               $this->setMwGlobals( array( 'wgHooks' => $hooks ) );
        }
 
        /**
@@ -142,7 +148,7 @@ class ApiCreateAccountTest extends ApiTestCase {
         */
        function testInvalidEmail() {
                global $wgEnableEmail;
-               if( !$wgEnableEmail ) {
+               if ( !$wgEnableEmail ) {
                        $this->markTestSkipped( 'email is not enabled, so createaccount does not check it' );
                }
                $this->doApiRequest( array(
index dd4d598..8f6b935 100644 (file)
@@ -45,7 +45,7 @@ class ApiBlockTest extends ApiTestCase {
                        $this->markTestIncomplete( "The user UTApiBlockee does not exist" );
                }
 
-               if( !isset( $data[0]['query']['pages'] ) ) {
+               if ( !isset( $data[0]['query']['pages'] ) ) {
                        $this->markTestIncomplete( "No block token found" );
                }
 
@@ -59,7 +59,7 @@ class ApiBlockTest extends ApiTestCase {
                        'reason' => 'Some reason',
                        'token' => $pageinfo['blocktoken'] ), null, false, self::$users['sysop']->user );
 
-               $block = Block::newFromTarget('UTApiBlockee');
+               $block = Block::newFromTarget( 'UTApiBlockee' );
 
                $this->assertTrue( !is_null( $block ), 'Block is valid' );
 
@@ -99,7 +99,7 @@ class ApiBlockTest extends ApiTestCase {
                                'action' => $action,
                                'user' => 'UTApiBlockee',
                                'reason' => 'Some reason',
-                               ),
+                       ),
                        null,
                        false,
                        self::$users['sysop']->user
@@ -111,7 +111,7 @@ class ApiBlockTest extends ApiTestCase {
         */
        function provideBlockUnblockAction() {
                return array(
-                       array( 'block'   ),
+                       array( 'block' ),
                        array( 'unblock' ),
                );
        }
index eaab300..da5eb33 100644 (file)
@@ -43,14 +43,15 @@ class ApiEditPageTest extends ApiTestCase {
                parent::teardown();
        }
 
-       function testEdit( ) {
+       function testEdit() {
                $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext
 
                // -- test new page --------------------------------------------
                $apiResult = $this->doApiRequestWithToken( array(
-                               'action' => 'edit',
-                               'title' => $name,
-                               'text' => 'some text', ) );
+                       'action' => 'edit',
+                       'title' => $name,
+                       'text' => 'some text',
+               ) );
                $apiResult = $apiResult[0];
 
                // Validate API result data
@@ -65,9 +66,10 @@ class ApiEditPageTest extends ApiTestCase {
 
                // -- test existing page, no change ----------------------------
                $data = $this->doApiRequestWithToken( array(
-                               'action' => 'edit',
-                               'title' => $name,
-                               'text' => 'some text', ) );
+                       'action' => 'edit',
+                       'title' => $name,
+                       'text' => 'some text',
+               ) );
 
                $this->assertEquals( 'Success', $data[0]['edit']['result'] );
 
@@ -76,9 +78,10 @@ class ApiEditPageTest extends ApiTestCase {
 
                // -- test existing page, with change --------------------------
                $data = $this->doApiRequestWithToken( array(
-                               'action' => 'edit',
-                               'title' => $name,
-                               'text' => 'different text' ) );
+                       'action' => 'edit',
+                       'title' => $name,
+                       'text' => 'different text'
+               ) );
 
                $this->assertEquals( 'Success', $data[0]['edit']['result'] );
 
@@ -94,7 +97,7 @@ class ApiEditPageTest extends ApiTestCase {
                );
        }
 
-       function testNonTextEdit( ) {
+       function testNonTextEdit() {
                $name = 'Dummy:ApiEditPageTest_testNonTextEdit';
                $data = serialize( 'some bla bla text' );
 
@@ -158,13 +161,13 @@ class ApiEditPageTest extends ApiTestCase {
                if ( $text !== null ) {
                        if ( $text === '' ) {
                                // can't create an empty page, so create it with some content
-                               list( $re,, ) = $this->doApiRequestWithToken( array(
+                               list( $re, , ) = $this->doApiRequestWithToken( array(
                                        'action' => 'edit',
                                        'title' => $name,
                                        'text' => '(dummy)', ) );
                        }
 
-                       list( $re,, ) = $this->doApiRequestWithToken( array(
+                       list( $re, , ) = $this->doApiRequestWithToken( array(
                                'action' => 'edit',
                                'title' => $name,
                                'text' => $text, ) );
@@ -173,7 +176,7 @@ class ApiEditPageTest extends ApiTestCase {
                }
 
                // -- try append/prepend --------------------------------------------
-               list( $re,, ) = $this->doApiRequestWithToken( array(
+               list( $re, , ) = $this->doApiRequestWithToken( array(
                        'action' => 'edit',
                        'title' => $name,
                        $op . 'text' => $append, ) );
@@ -221,12 +224,12 @@ class ApiEditPageTest extends ApiTestCase {
 
                // try to save edit, expect conflict
                try {
-                       list( $re,, ) = $this->doApiRequestWithToken( array(
+                       list( $re, , ) = $this->doApiRequestWithToken( array(
                                'action' => 'edit',
                                'title' => $name,
                                'text' => 'nix bar!',
                                'basetimestamp' => $baseTime,
-                               ), null, self::$users['sysop']->user );
+                       ), null, self::$users['sysop']->user );
 
                        $this->fail( 'edit conflict expected' );
                } catch ( UsageException $ex ) {
@@ -264,7 +267,7 @@ class ApiEditPageTest extends ApiTestCase {
                $this->forceRevisionDate( $rpage, '20120101020202' );
 
                // try to save edit; should work, because we follow the redirect
-               list( $re,, ) = $this->doApiRequestWithToken( array(
+               list( $re, , ) = $this->doApiRequestWithToken( array(
                        'action' => 'edit',
                        'title' => $rname,
                        'text' => 'nix bar!',
@@ -277,7 +280,7 @@ class ApiEditPageTest extends ApiTestCase {
 
                // try again, without following the redirect. Should fail.
                try {
-                       list( $re,, ) = $this->doApiRequestWithToken( array(
+                       list( $re, , ) = $this->doApiRequestWithToken( array(
                                'action' => 'edit',
                                'title' => $rname,
                                'text' => 'nix bar!',
@@ -326,7 +329,7 @@ class ApiEditPageTest extends ApiTestCase {
                $this->forceRevisionDate( $rpage, '20120101020202' );
 
                // try to save edit; should work, following the redirect.
-               list( $re,, ) = $this->doApiRequestWithToken( array(
+               list( $re, , ) = $this->doApiRequestWithToken( array(
                        'action' => 'edit',
                        'title' => $rname,
                        'text' => 'nix bar!',
diff --git a/tests/phpunit/includes/api/ApiGeneratorTest.php b/tests/phpunit/includes/api/ApiGeneratorTest.php
deleted file mode 100644 (file)
index e5a8717..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-/**
- * @group API
- */
-class ApiGeneratorTest extends MediaWikiTestCase {
-
-       /**
-        * Helper to easily get an ApiQuery object instance
-        */
-       function getApiQuery() {
-               // Initialize an ApiQuery object to play with
-               $main = new ApiMain( new FauxRequest() );
-               return new ApiQuery( $main, 'foo', 'bar' );
-       }
-
-       /**
-        * Test whether all registered query modules which are subclasses of
-        * ApiQueryGeneratorBase are listed as being a generator. Registration is
-        * done:
-        *  - for core: add it to ApiQuery::$mQueryGenerators
-        *  - for extension: by adding to $wgAPIGeneratorModules
-        *
-        * @dataProvider provideApiquerygeneratorbaseChilds
-        */
-       public function testApiquerygeneatorbaseModulesListedAsGenerators(
-               $moduleName, $moduleClass
-       ) {
-               $generators = $this->getApiQuery()->getGenerators();
-               $this->assertArrayHasKey( $moduleName, $generators,
-                       "API module '$moduleName' of class '$moduleClass' (an ApiQueryGeneratorBase subclass) must be listed in ApiQuery::\$mQueryGenerators or added to \$wgAPIGeneratorModules."
-               );
-       }
-
-       /**
-        * Returns API modules which are subclassing ApiQueryGeneratorBase.
-        * Case format is:
-        *      (moduleName, moduleClass)
-        */
-       public function provideApiquerygeneratorbaseChilds() {
-               $cases = array();
-               $modules = $this->getApiQuery()->getModules();
-               foreach( $modules as $moduleName => $moduleClass ) {
-                       if( !is_subclass_of( $moduleClass, 'ApiQueryGeneratorBase' ) ) {
-                               continue;
-                       }
-                       $cases[] = array( $moduleName, $moduleClass );
-               }
-               return $cases;
-       }
-
-       /**
-        * @dataProvider provideListedApiqueryGenerators
-        */
-       public function testGeneratorsAreApiquerygeneratorbaseSubclasses(
-               $generatorName, $generatorClass
-       ) {
-               $modules = $this->getApiQuery()->getModules();
-               $this->assertArrayHasKey( $generatorName, $modules,
-                       "Class '$generatorClass' of generator '$generatorName' must be a subclass of 'ApiQueryGeneratorBase'. Listed either in ApiQuery::\$mQueryGenerators or in \$wgAPIGeneratorModules."
-               );
-
-       }
-
-       /**
-        * Return ApiQuery generators, either listed in ApiQuery or registered
-        * via wgAPIGeneratorModules.
-        * Case format is:
-        *  (moduleName, $moduleClass).
-        */
-       public function provideListedApiqueryGenerators() {
-               $cases = array();
-               $generators = $this->getApiQuery()->getGenerators();
-               foreach( $generators as $generatorName => $generatorClass ) {
-                       $cases[] = array( $generatorName, $generatorClass );
-               }
-               return $cases;
-       }
-
-}
index 93ff24a..a42e5aa 100644 (file)
@@ -21,7 +21,7 @@ class ApiParseTest extends ApiTestCase {
                                'page' => $somePage ) );
 
                        $this->fail( "API did not return an error when parsing a nonexistent page" );
-               } catch(UsageException $ex){
+               } catch ( UsageException $ex ) {
                        $this->assertEquals( 'missingtitle', $ex->getCodeString(),
                                "Parse request for nonexistent page must give 'missingtitle' error: " . var_export( $ex->getMessageArray(), true ) );
                }
index 3ab77fd..a7f9229 100644 (file)
@@ -33,7 +33,7 @@ class ApiPurgeTest extends ApiTestCase {
                        "Purge request for three articles should give back three results received: " . var_export( $data[0]['purge'], true ) );
 
                $pages = array( 'UTPage' => 'purged', $somePage => 'missing', '%5D' => 'invalid' );
-               foreach( $data[0]['purge'] as $v ) {
+               foreach ( $data[0]['purge'] as $v ) {
                        $this->assertArrayHasKey( $pages[$v['title']], $v );
                }
        }
diff --git a/tests/phpunit/includes/api/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/ApiQueryRevisionsTest.php
deleted file mode 100644 (file)
index 19da81c..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @group API
- * @group Database
- * @group medium
- */
-class ApiQueryRevisionsTest extends ApiTestCase {
-
-       /**
-        * @group medium
-        */
-       function testContentComesWithContentModelAndFormat() {
-
-               $pageName = 'Help:' . __METHOD__ ;
-               $title = Title::newFromText( $pageName );
-               $page = WikiPage::factory( $title );
-               $page->doEdit( 'Some text', 'inserting content' );
-
-               $apiResult = $this->doApiRequest( array(
-                       'action' => 'query',
-                       'prop' => 'revisions',
-                       'titles' => $pageName,
-                       'rvprop' => 'content',
-               ) );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'pages', $apiResult[0]['query'] );
-               foreach( $apiResult[0]['query']['pages'] as $page ) {
-                       $this->assertArrayHasKey( 'revisions', $page );
-                       foreach( $page['revisions'] as $revision ) {
-                               $this->assertArrayHasKey( 'contentformat', $revision,
-                                       'contentformat should be included when asking content so'
-                                       . ' client knows how to interpretate it'
-                               );
-                               $this->assertArrayHasKey( 'contentmodel', $revision,
-                                       'contentmodel should be included when asking content so'
-                                       . ' client knows how to interpretate it'
-                               );
-                       }
-               }
-       }
-}
diff --git a/tests/phpunit/includes/api/ApiQueryTest.php b/tests/phpunit/includes/api/ApiQueryTest.php
deleted file mode 100644 (file)
index 1b1886e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-/**
- * @group API
- * @group Database
- * @group medium
- */
-class ApiQueryTest extends ApiTestCase {
-
-       protected function setUp() {
-               parent::setUp();
-               $this->doLogin();
-       }
-
-       function testTitlesGetNormalized() {
-
-               global $wgMetaNamespace;
-
-               $data = $this->doApiRequest( array(
-                       'action' => 'query',
-                       'titles' => 'Project:articleA|article_B' ) );
-
-
-               $this->assertArrayHasKey( 'query', $data[0] );
-               $this->assertArrayHasKey( 'normalized', $data[0]['query'] );
-
-               // Forge a normalized title
-               $to = Title::newFromText( $wgMetaNamespace.':ArticleA' );
-
-               $this->assertEquals(
-                       array(
-                               'from' => 'Project:articleA',
-                               'to' => $to->getPrefixedText(),
-                       ),
-                       $data[0]['query']['normalized'][0]
-               );
-
-               $this->assertEquals(
-                       array(
-                               'from' => 'article_B',
-                               'to' => 'Article B'
-                       ),
-                       $data[0]['query']['normalized'][1]
-               );
-
-       }
-
-       function testTitlesAreRejectedIfInvalid() {
-               $title = false;
-               while( !$title || Title::newFromText( $title )->exists() ) {
-                       $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) );
-               }
-
-               $data = $this->doApiRequest( array(
-                       'action' => 'query',
-                       'titles' => $title . '|Talk:' ) );
-
-               $this->assertArrayHasKey( 'query', $data[0] );
-               $this->assertArrayHasKey( 'pages', $data[0]['query'] );
-               $this->assertEquals( 2, count( $data[0]['query']['pages'] ) );
-
-               $this->assertArrayHasKey( -2, $data[0]['query']['pages'] );
-               $this->assertArrayHasKey( -1, $data[0]['query']['pages'] );
-
-               $this->assertArrayHasKey( 'missing', $data[0]['query']['pages'][-2] );
-               $this->assertArrayHasKey( 'invalid', $data[0]['query']['pages'][-1] );
-       }
-
-}
index 2f2f5f9..2277028 100644 (file)
@@ -12,7 +12,7 @@ class ApiTest extends ApiTestCase {
 
                $this->assertEquals(
                        null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt",
-                               "enablechunks" => false ), "filename", "enablechunks" ) );
+                       "enablechunks" => false ), "filename", "enablechunks" ) );
        }
 
        /**
@@ -23,7 +23,7 @@ class ApiTest extends ApiTestCase {
 
                $this->assertEquals(
                        null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt",
-                               "enablechunks" => 0 ), "filename", "enablechunks" ) );
+                       "enablechunks" => 0 ), "filename", "enablechunks" ) );
        }
 
        /**
@@ -34,7 +34,7 @@ class ApiTest extends ApiTestCase {
 
                $this->assertEquals(
                        null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt",
-                               "enablechunks" => true ), "filename", "enablechunks" ) );
+                       "enablechunks" => true ), "filename", "enablechunks" ) );
        }
 
        /**
@@ -92,12 +92,14 @@ class ApiTest extends ApiTestCase {
 
                $token = $result["login"]["token"];
 
-               $ret = $this->doApiRequest( array(
-                       "action" => "login",
-                       "lgtoken" => $token,
-                       "lgname" => $user->username,
-                       "lgpassword" => "badnowayinhell",
-                       ), $ret[2]
+               $ret = $this->doApiRequest(
+                       array(
+                               "action" => "login",
+                               "lgtoken" => $token,
+                               "lgname" => $user->username,
+                               "lgpassword" => "badnowayinhell",
+                       ),
+                       $ret[2]
                );
 
                $result = $ret[0];
@@ -119,9 +121,9 @@ class ApiTest extends ApiTestCase {
                $user->user->logOut();
 
                $ret = $this->doApiRequest( array(
-                       "action" => "login",
-                       "lgname" => $user->username,
-                       "lgpassword" => $user->password,
+                               "action" => "login",
+                               "lgname" => $user->username,
+                               "lgpassword" => $user->password,
                        )
                );
 
@@ -133,12 +135,14 @@ class ApiTest extends ApiTestCase {
                $this->assertEquals( "NeedToken", $a );
                $token = $result["login"]["token"];
 
-               $ret = $this->doApiRequest( array(
-                       "action" => "login",
-                       "lgtoken" => $token,
-                       "lgname" => $user->username,
-                       "lgpassword" => $user->password,
-                       ), $ret[2]
+               $ret = $this->doApiRequest(
+                       array(
+                               "action" => "login",
+                               "lgtoken" => $token,
+                               "lgname" => $user->username,
+                               "lgpassword" => $user->password,
+                       ),
+                       $ret[2]
                );
 
                $result = $ret[0];
@@ -153,7 +157,7 @@ class ApiTest extends ApiTestCase {
         * @group Broken
         */
        function testApiGotCookie() {
-               $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies"  );
+               $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies" );
 
                global $wgServer, $wgScriptPath;
 
@@ -165,8 +169,11 @@ class ApiTest extends ApiTestCase {
                $req = MWHttpRequest::factory( self::$apiUrl . "?action=login&format=xml",
                        array( "method" => "POST",
                                "postData" => array(
-                               "lgname" => $user->username,
-                               "lgpassword" => $user->password ) ) );
+                                       "lgname" => $user->username,
+                                       "lgpassword" => $user->password
+                               )
+                       )
+               );
                $req->execute();
 
                libxml_use_internal_errors( true );
index fcd581a..552fbfb 100644 (file)
@@ -1,4 +1,4 @@
-<?php 
+<?php
 
 abstract class ApiTestCase extends MediaWikiLangTestCase {
        protected static $apiUrl;
@@ -9,14 +9,10 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
        protected $apiContext;
 
        protected function setUp() {
-               global $wgContLang, $wgAuth, $wgMemc, $wgRequest, $wgUser, $wgServer;
+               global $wgServer;
 
                parent::setUp();
                self::$apiUrl = $wgServer . wfScript( 'api' );
-               $wgMemc = new EmptyBagOStuff();
-               $wgContLang = Language::factory( 'en' );
-               $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
-               $wgRequest = new FauxRequest( array() );
 
                ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session
 
@@ -35,10 +31,28 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                        )
                );
 
-               $wgUser = self::$users['sysop']->user;
+               $this->setMwGlobals( array(
+                       'wgMemc' => new EmptyBagOStuff(),
+                       'wgAuth' => new StubObject( 'wgAuth', 'AuthPlugin' ),
+                       'wgRequest' => new FauxRequest( array() ),
+                       'wgUser' => self::$users['sysop']->user,
+               ) );
 
                $this->apiContext = new ApiTestContext();
+       }
 
+       /**
+        * Edits or creates a page/revision
+        * @param $pageName string page title
+        * @param $text string content of the page
+        * @param $summary string optional summary string for the revision
+        * @param $defaultNs int optional namespace id
+        * @return array as returned by WikiPage::doEditContent()
+        */
+       protected function editPage( $pageName, $text, $summary = '', $defaultNs = NS_MAIN ) {
+               $title = Title::newFromText( $pageName, $defaultNs );
+               $page = WikiPage::factory( $title );
+               return $page->doEditContent( ContentHandler::makeContent( $text, $title ), $summary );
        }
 
        /**
@@ -102,6 +116,8 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
         * @param $params Array: key-value API params
         * @param $session Array|null: session array
         * @param $user User|null A User object for the context
+        * @return result of the API call
+        * @throws Exception in case wsToken is not set in the session
         */
        protected function doApiRequestWithToken( array $params, array $session = null, User $user = null ) {
                global $wgRequest;
@@ -129,12 +145,15 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
 
                $token = $data[0]['login']['token'];
 
-               $data = $this->doApiRequest( array(
-                       'action' => 'login',
-                       'lgtoken' => $token,
-                       'lgname' => self::$users['sysop']->username,
-                       'lgpassword' => self::$users['sysop']->password
-                       ), $data[2] );
+               $data = $this->doApiRequest(
+                       array(
+                               'action' => 'login',
+                               'lgtoken' => $token,
+                               'lgname' => self::$users['sysop']->username,
+                               'lgpassword' => self::$users['sysop']->password,
+                       ),
+                       $data[2]
+               );
 
                return $data;
        }
@@ -161,7 +180,9 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
 }
 
 class UserWrapper {
-       public $userName, $password, $user;
+       public $userName;
+       public $password;
+       public $user;
 
        public function __construct( $userName, $password, $group = '' ) {
                $this->userName = $userName;
@@ -183,10 +204,11 @@ class UserWrapper {
 }
 
 class MockApi extends ApiBase {
-       public function execute() { }
-       public function getVersion() { }
+       public function execute() {}
+
+       public function getVersion() {}
 
-       public function __construct() { }
+       public function __construct() {}
 
        public function getAllowedParams() {
                return array(
index 9f281bd..8028491 100644 (file)
@@ -47,7 +47,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                        // see if it now doesn't exist; reload
                        $title = Title::newFromText( $title->getText(), NS_FILE );
                }
-               return ! ( $title && $title instanceof Title && $title->exists() );
+               return !( $title && $title instanceof Title && $title->exists() );
        }
 
        /**
@@ -84,7 +84,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                $tmpName = tempnam( wfTempDir(), "" );
                if ( !file_exists( $filePath ) ) {
                        throw new Exception( "$filePath doesn't exist!" );
-               };
+               }
 
                if ( !copy( $filePath, $tmpName ) ) {
                        throw new Exception( "couldn't copy $filePath to $tmpName" );
@@ -96,44 +96,44 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                        throw new Exception( "couldn't stat $tmpName" );
                }
 
-               $_FILES[ $fieldName ] = array(
-                       'name'          => $fileName,
-                       'type'          => $type,
-                       'tmp_name'      => $tmpName,
-                       'size'          => $size,
-                       'error'         => null
+               $_FILES[$fieldName] = array(
+                       'name' => $fileName,
+                       'type' => $type,
+                       'tmp_name' => $tmpName,
+                       'size' => $size,
+                       'error' => null
                );
 
                return true;
 
        }
 
-       function fakeUploadChunk(  $fieldName, $fileName, $type, & $chunkData ){
+       function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) {
                $tmpName = tempnam( wfTempDir(), "" );
-               // copy the chunk data to temp location: 
+               // copy the chunk data to temp location:
                if ( !file_put_contents( $tmpName, $chunkData ) ) {
                        throw new Exception( "couldn't copy chunk data to $tmpName" );
                }
-               
+
                clearstatcache();
                $size = filesize( $tmpName );
                if ( $size === false ) {
                        throw new Exception( "couldn't stat $tmpName" );
                }
-               
-               $_FILES[ $fieldName ] = array(
-                       'name'          => $fileName,
-                       'type'          => $type,
-                       'tmp_name'      => $tmpName,
-                       'size'          => $size,
-                       'error'         => null
+
+               $_FILES[$fieldName] = array(
+                       'name' => $fileName,
+                       'type' => $type,
+                       'tmp_name' => $tmpName,
+                       'size' => $size,
+                       'error' => null
                );
        }
 
        function clearTempUpload() {
-               if( isset( $_FILES['file']['tmp_name'] ) ) {
+               if ( isset( $_FILES['file']['tmp_name'] ) ) {
                        $tmp = $_FILES['file']['tmp_name'];
-                       if( file_exists( $tmp ) ) {
+                       if ( file_exists( $tmp ) ) {
                                unlink( $tmp );
                        }
                }
index 642fed0..0d98b04 100644 (file)
@@ -107,8 +107,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -120,7 +119,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $this->deleteFileByContent( $filePath );
 
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -129,7 +128,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                $exception = false;
@@ -162,7 +161,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                $this->deleteFileByFileName( $fileName );
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -171,7 +170,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                $exception = false;
@@ -199,8 +198,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 2, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -216,12 +214,12 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                // first upload .... should succeed
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[0] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[0] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -238,7 +236,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // second upload with the same name (but different content)
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[1] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[1] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -272,8 +270,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -292,10 +289,10 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileNames[0],
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for " . $fileNames[0],
+                       'text' => "This is the page text for " . $fileNames[0],
                );
 
-               if ($this->fakeUploadFile( 'file', $fileNames[0], $mimeType, $filePaths[0] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileNames[0], $mimeType, $filePaths[0] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -313,7 +310,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // second upload with the same content (but different name)
 
-               if ($this->fakeUploadFile( 'file', $fileNames[1], $mimeType, $filePaths[0] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileNames[1], $mimeType, $filePaths[0] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -322,7 +319,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileNames[1],
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for " . $fileNames[1],
+                       'text' => "This is the page text for " . $fileNames[1],
                );
 
                $exception = false;
@@ -349,8 +346,9 @@ class ApiUploadTest extends ApiTestCaseUpload {
         * @depends testLogin
         */
        public function testUploadStash( $session ) {
-               global $wgUser;
-               $wgUser = self::$users['uploader']->user; // @todo FIXME: still used somewhere
+               $this->setMwGlobals( array(
+                       'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere
+               ) );
 
                $extension = 'png';
                $mimeType = 'image/png';
@@ -358,8 +356,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -370,17 +367,17 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $this->deleteFileByFileName( $fileName );
                $this->deleteFileByContent( $filePath );
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
                $params = array(
                        'action' => 'upload',
-                       'stash' => 1,
+                       'stash' => 1,
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                $exception = false;
@@ -408,7 +405,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filekey' => $filekey,
                        'filename' => $fileName,
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName, altered",
+                       'text' => "This is the page text for $fileName, altered",
                );
 
                $this->clearFakeUploads();
@@ -427,15 +424,15 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $this->deleteFileByFilename( $fileName );
                unlink( $filePath );
        }
-       
-       
+
        /**
         * @depends testLogin
         */
        public function testUploadChunks( $session ) {
-               global $wgUser;
-               $wgUser = self::$users['uploader']->user; // @todo FIXME: still used somewhere
-               
+               $this->setMwGlobals( array(
+                       'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere
+               ) );
+
                $chunkSize = 1048576;
                // Download a large image file
                // ( using RandomImageGenerator for large files is not stable )
@@ -444,11 +441,10 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $filePath = wfTempDir() . '/Oberaargletscher_from_Oberaar.jpg';
                try {
                        // Only download if the file is not avaliable in the temp location:
-                       if( !is_file( $filePath ) ){
-                               copy($url, $filePath); 
+                       if ( !is_file( $filePath ) ) {
+                               copy( $url, $filePath );
                        }
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -461,29 +457,29 @@ class ApiUploadTest extends ApiTestCaseUpload {
                // Base upload params: 
                $params = array(
                        'action' => 'upload',
-                       'stash' => 1,
+                       'stash' => 1,
                        'filename' => $fileName,
                        'filesize' => $fileSize,
                        'offset' => 0,
                );
-               
+
                // Upload chunks
                $chunkSessionKey = false;
                $resultOffset = 0;
                // Open the file: 
-               $handle = @fopen ($filePath, "r");
-               if( $handle === false ){
+               $handle = @fopen( $filePath, "r" );
+               if ( $handle === false ) {
                        $this->markTestIncomplete( "could not open file: $filePath" );
                }
-               while (!feof ($handle)) {
+               while ( !feof( $handle ) ) {
                        // Get the current chunk
                        $chunkData = @fread( $handle, $chunkSize );
 
                        // Upload the current chunk into the $_FILE object:
                        $this->fakeUploadChunk( 'chunk', 'blob', $mimeType, $chunkData );
-                       
+
                        // Check for chunkSessionKey
-                       if( !$chunkSessionKey ){
+                       if ( !$chunkSessionKey ) {
                                // Upload fist chunk ( and get the session key )
                                try {
                                        list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session,
@@ -495,7 +491,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                                $this->assertTrue( isset( $result['upload'] ) );
                                $this->assertTrue( isset( $result['upload']['filekey'] ) );
                                // If we don't get a session key mark test incomplete. 
-                               if( ! isset( $result['upload']['filekey'] ) ){
+                               if ( !isset( $result['upload']['filekey'] ) ) {
                                        $this->markTestIncomplete( "no filekey provided" );
                                }
                                $chunkSessionKey = $result['upload']['filekey'];
@@ -521,9 +517,9 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        // Make sure we got a valid chunk continue: 
                        $this->assertTrue( isset( $result['upload'] ) );
                        $this->assertTrue( isset( $result['upload']['filekey'] ) );
-                       
+
                        // Check if we were on the last chunk: 
-                       if( $params['offset'] + $chunkSize >=  $fileSize ){
+                       if ( $params['offset'] + $chunkSize >= $fileSize ) {
                                $this->assertEquals( 'Success', $result['upload']['result'] );
                                break;
                        } else {
@@ -531,11 +527,11 @@ class ApiUploadTest extends ApiTestCaseUpload {
                                // update $resultOffset
                                $resultOffset = $result['upload']['offset'];
                        }
-               } 
-               fclose ($handle); 
-        
+               }
+               fclose( $handle );
+
                // Check that we got a valid file result:
-               wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n");
+               wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n" );
                $this->assertEquals( $fileSize, $result['upload']['imageinfo']['size'] );
                $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] );
                $this->assertTrue( isset( $result['upload']['filekey'] ) );
@@ -547,7 +543,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filekey' => $filekey,
                        'filename' => $fileName,
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName, altered",
+                       'text' => "This is the page text for $fileName, altered",
                );
                $this->clearFakeUploads();
                $exception = false;
index 4fecec0..aefd939 100644 (file)
@@ -147,8 +147,8 @@ class ApiWatchTest extends ApiTestCase {
 
                        $this->assertArrayHasKey( 'rollback', $data[0] );
                        $this->assertArrayHasKey( 'title', $data[0]['rollback'] );
-               } catch( UsageException $ue ) {
-                       if( $ue->getCodeString() == 'onlyauthor' ) {
+               } catch ( UsageException $ue ) {
+                       if ( $ue->getCodeString() == 'onlyauthor' ) {
                                $this->markTestIncomplete( "Only one author to 'Help:UTPage', cannot test rollback" );
                        } else {
                                $this->fail( "Received error '" . $ue->getCodeString() . "'" );
index 3bacb05..d9be85e 100644 (file)
@@ -9,7 +9,7 @@ class PrefixUniquenessTest extends MediaWikiTestCase {
        public function testPrefixes() {
                $main = new ApiMain( new FauxRequest() );
                $query = new ApiQuery( $main, 'foo', 'bar' );
-               $modules = $query->getModules();
+               $modules = $query->getModuleManager()->getNamesWithClasses();
                $prefixes = array();
 
                foreach ( $modules as $name => $class ) {
index 8b6a384..3040758 100644 (file)
 class RandomImageGenerator {
 
        private $dictionaryFile;
-       private $minWidth     = 400 ;
-       private $maxWidth     = 800 ;
-       private $minHeight    = 400 ;
-       private $maxHeight    = 800 ;
-       private $shapesToDraw =   5 ;
+       private $minWidth = 400;
+       private $maxWidth = 800;
+       private $minHeight = 400;
+       private $maxHeight = 800;
+       private $shapesToDraw = 5;
 
        /**
         * Orientations: 0th row, 0th column, EXIF orientation code, rotation 2x2 matrix that is opposite of orientation
@@ -76,11 +76,13 @@ class RandomImageGenerator {
 
                // find the dictionary file, to generate random names
                if ( !isset( $this->dictionaryFile ) ) {
-                       foreach ( array(
+                       foreach (
+                               array(
                                        '/usr/share/dict/words',
                                        '/usr/dict/words',
-                                       __DIR__ . '/words.txt' )
-                                       as $dictionaryFile ) {
+                                       __DIR__ . '/words.txt'
+                               ) as $dictionaryFile
+                       ) {
                                if ( is_file( $dictionaryFile ) and is_readable( $dictionaryFile ) ) {
                                        $this->dictionaryFile = $dictionaryFile;
                                        break;
@@ -103,7 +105,7 @@ class RandomImageGenerator {
        function writeImages( $number, $format = 'jpg', $dir = null ) {
                $filenames = $this->getRandomFilenames( $number, $format, $dir );
                $imageWriteMethod = $this->getImageWriteMethod( $format );
-               foreach( $filenames as $filename ) {
+               foreach ( $filenames as $filename ) {
                        $this->{$imageWriteMethod}( $this->getImageSpec(), $format, $filename );
                }
                return $filenames;
@@ -144,7 +146,7 @@ class RandomImageGenerator {
                        $dir = getcwd();
                }
                $filenames = array();
-               foreach( $this->getRandomWordPairs( $number ) as $pair ) {
+               foreach ( $this->getRandomWordPairs( $number ) as $pair ) {
                        $basename = $pair[0] . '_' . $pair[1];
                        if ( !is_null( $extension ) ) {
                                $basename .= '.' . $extension;
@@ -181,17 +183,17 @@ class RandomImageGenerator {
                        }
                        $originX = mt_rand( -1 * $radius, $spec['width'] + $radius );
                        $originY = mt_rand( -1 * $radius, $spec['height'] + $radius );
-                       $angle = mt_rand( 0, ( 3.141592/2 ) * $radius ) / $radius;
+                       $angle = mt_rand( 0, ( 3.141592 / 2 ) * $radius ) / $radius;
                        $legDeltaX = round( $radius * sin( $angle ) );
                        $legDeltaY = round( $radius * cos( $angle ) );
 
                        $draw = array();
                        $draw['fill'] = $this->getRandomColor();
                        $draw['shape'] = array(
-                               array( 'x' => $originX,                 'y' => $originY - $radius ),
-                               array( 'x' => $originX + $legDeltaX,    'y' => $originY + $legDeltaY ),
-                               array( 'x' => $originX - $legDeltaX,    'y' => $originY + $legDeltaY ),
-                               array( 'x' => $originX,                 'y' => $originY - $radius )
+                               array( 'x' => $originX, 'y' => $originY - $radius ),
+                               array( 'x' => $originX + $legDeltaX, 'y' => $originY + $legDeltaY ),
+                               array( 'x' => $originX - $legDeltaX, 'y' => $originY + $legDeltaY ),
+                               array( 'x' => $originX, 'y' => $originY - $radius )
                        );
                        $draws[] = $draw;
 
@@ -235,12 +237,13 @@ class RandomImageGenerator {
                        $shape = $g->addChild( 'polygon' );
                        $shape->addAttribute( 'fill', $drawSpec['fill'] );
                        $shape->addAttribute( 'points', self::shapePointsToString( $drawSpec['shape'] ) );
-               };
-               if ( ! $fh = fopen( $filename, 'w' ) ) {
+               }
+
+               if ( !$fh = fopen( $filename, 'w' ) ) {
                        throw new Exception( "couldn't open $filename for writing" );
                }
                fwrite( $fh, $svg->asXML() );
-               if ( !fclose($fh) ) {
+               if ( !fclose( $fh ) ) {
                        throw new Exception( "couldn't close $filename" );
                }
        }
@@ -262,7 +265,7 @@ class RandomImageGenerator {
                 */
                $orientation = self::$orientations[0]; // default is normal orientation
                if ( $format == 'jpg' ) {
-                       $orientation = self::$orientations[ array_rand( self::$orientations ) ];
+                       $orientation = self::$orientations[array_rand( self::$orientations )];
                        $spec = self::rotateImageSpec( $spec, $orientation['counterRotation'] );
                }
 
@@ -321,12 +324,12 @@ class RandomImageGenerator {
                $tSpec['height'] = abs( $dims['y'] );
                $tSpec['fill'] = $spec['fill'];
                $tSpec['draws'] = array();
-               foreach( $spec['draws'] as $draw ) {
+               foreach ( $spec['draws'] as $draw ) {
                        $tDraw = array(
                                'fill' => $draw['fill'],
                                'shape' => array()
                        );
-                       foreach( $draw['shape'] as $point ) {
+                       foreach ( $draw['shape'] as $point ) {
                                $tPoint = self::matrixMultiply2x2( $matrix, $point['x'], $point['y'] );
                                $tPoint['x'] += $correctionX;
                                $tPoint['y'] += $correctionY;
@@ -357,7 +360,7 @@ class RandomImageGenerator {
         *
         * Sample command line:
         *  $ convert -size 100x60 xc:rgb(90,87,45) \
-        *       -draw 'fill rgb(12,34,56)   polygon 41,39 44,57 50,57 41,39' \
+        *      -draw 'fill rgb(12,34,56)   polygon 41,39 44,57 50,57 41,39' \
         *   -draw 'fill rgb(99,123,231) circle 59,39 56,57' \
         *   -draw 'fill rgb(240,12,32)  circle 50,21 50,3'  filename.png
         *
@@ -370,7 +373,7 @@ class RandomImageGenerator {
                $args = array();
                $args[] = "-size " . wfEscapeShellArg( $spec['width'] . 'x' . $spec['height'] );
                $args[] = wfEscapeShellArg( "xc:" . $spec['fill'] );
-               foreach( $spec['draws'] as $draw ) {
+               foreach ( $spec['draws'] as $draw ) {
                        $fill = $draw['fill'];
                        $polygon = self::shapePointsToString( $draw['shape'] );
                        $drawCommand = "fill $fill  polygon $polygon";
@@ -391,10 +394,10 @@ class RandomImageGenerator {
         */
        public function getRandomColor() {
                $components = array();
-               for ($i = 0; $i <= 2; $i++ ) {
+               for ( $i = 0; $i <= 2; $i++ ) {
                        $components[] = mt_rand( 0, 255 );
                }
-               return 'rgb(' . join(', ', $components) . ')';
+               return 'rgb(' . join( ', ', $components ) . ')';
        }
 
        /**
@@ -408,13 +411,12 @@ class RandomImageGenerator {
                // construct pairs of words
                $pairs = array();
                $count = count( $lines );
-               for( $i = 0; $i < $count; $i += 2 )  {
-                       $pairs[] = array( $lines[$i], $lines[$i+1] );
+               for ( $i = 0; $i < $count; $i += 2 ) {
+                       $pairs[] = array( $lines[$i], $lines[$i + 1] );
                }
                return $pairs;
        }
 
-
        /**
         * Return N random lines from a file
         *
@@ -438,17 +440,17 @@ class RandomImageGenerator {
                 */
                $fh = fopen( $filepath, "r" );
                if ( !$fh ) {
-                        throw new Exception( "couldn't open $filepath" );
+                       throw new Exception( "couldn't open $filepath" );
                }
                $line_number = 0;
                $max_index = $number_desired - 1;
-               while( !feof( $fh ) ) {
+               while ( !feof( $fh ) ) {
                        $line = fgets( $fh );
                        if ( $line !== false ) {
                                $line_number++;
                                $line = trim( $line );
                                if ( mt_rand( 0, $line_number ) <= $max_index ) {
-                                       $lines[ mt_rand( 0, $max_index ) ] = $line;
+                                       $lines[mt_rand( 0, $max_index )] = $line;
                                }
                        }
                }
index d34e799..a59983d 100644 (file)
@@ -8,13 +8,12 @@
 class ApiFormatPhpTest extends ApiFormatTestBase {
 
        function testValidPhpSyntax() {
-               
+
                $data = $this->apiRequest( 'php', array( 'action' => 'query', 'meta' => 'siteinfo' ) );
-               
+
                $this->assertInternalType( 'array', unserialize( $data ) );
-               $this->assertGreaterThan( 0, count( (array) $data ) );
-               
-               
+               $this->assertGreaterThan( 0, count( (array)$data ) );
+
        }
 
 }
index a0b7b02..153f2cf 100644 (file)
@@ -5,7 +5,7 @@ abstract class ApiFormatTestBase extends ApiTestCase {
                $data = parent::doApiRequest( $params, $data, true );
 
                $module = $data[3];
-               
+
                $printer = $module->createPrinterByName( $format );
                $printer->setUnescapeAmps( false );
 
@@ -14,7 +14,7 @@ abstract class ApiFormatTestBase extends ApiTestCase {
                ob_start();
                $printer->execute();
                $out = ob_get_clean();
-               
+
                $printer->closePrinter();
 
                return $out;
index ee34562..cba8312 100644 (file)
@@ -10,7 +10,7 @@ $IP = dirname( dirname( dirname( dirname( __DIR__ ) ) ) );
 
 // Start up MediaWiki in command-line mode
 require_once( "$IP/maintenance/Maintenance.php" );
-require(  __DIR__ . "/RandomImageGenerator.php" );
+require( __DIR__ . "/RandomImageGenerator.php" );
 
 class GenerateRandomImages extends Maintenance {
 
@@ -47,5 +47,3 @@ class GenerateRandomImages extends Maintenance {
 
 $maintClass = 'GenerateRandomImages';
 require( RUN_MAINTENANCE_IF_MAIN );
-
-
diff --git a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php
new file mode 100644 (file)
index 0000000..a5ca256
--- /dev/null
@@ -0,0 +1,391 @@
+<?php
+/**
+ *
+ *
+ * Created on Feb 6, 2013
+ *
+ * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ *
+ * 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
+ *
+ * These tests validate basic functionality of the api query module
+ *
+ * @group API
+ * @group Database
+ * @group medium
+ */
+class ApiQueryBasicTest extends ApiTestCase {
+       /**
+        * Create a set of pages. These must not change, otherwise the tests might give wrong results.
+        * @see MediaWikiTestCase::addDBData()
+        */
+       function addDBData() {
+               try {
+                       if ( Title::newFromText( 'AQBT-All' )->exists() ) {
+                               return;
+                       }
+
+                       // Ordering is important, as it will be returned in the same order as stored in the index
+                       $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' );
+                       $this->editPage( 'AQBT-Categories', '[[Category:AQBT-Cat]]' );
+                       $this->editPage( 'AQBT-Links', '[[AQBT-All]] [[AQBT-Categories]] [[AQBT-Templates]]' );
+                       $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' );
+                       $this->editPage( 'AQBT-T', 'Content', '', NS_TEMPLATE );
+
+                       // Refresh due to the bug with listing transclusions as links if they don't exist
+                       $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' );
+                       $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' );
+               } catch ( Exception $e ) {
+                       $this->exceptionFromAddDBData = $e;
+               }
+       }
+
+       private static $links = array(
+               array( 'prop' => 'links', 'titles' => 'AQBT-All' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All',
+                               'links' => array(
+                                       array( 'ns' => 0, 'title' => 'AQBT-Links' ),
+       ) ) ) ) );
+
+       private static $templates = array(
+               array( 'prop' => 'templates', 'titles' => 'AQBT-All' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All',
+                               'templates' => array(
+                                       array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
+       ) ) ) ) );
+
+       private static $categories = array(
+               array( 'prop' => 'categories', 'titles' => 'AQBT-All' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All',
+                               'categories' => array(
+                                       array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ),
+       ) ) ) ) );
+
+       private static $allpages = array(
+               array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ),
+               array( 'allpages' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
+                       array( 'pageid' => 3, 'ns' => 0, 'title' => 'AQBT-Links' ),
+                       array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $alllinks = array(
+               array( 'list' => 'alllinks', 'alprefix' => 'AQBT-' ),
+               array( 'alllinks' => array(
+                       array( 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'ns' => 0, 'title' => 'AQBT-Categories' ),
+                       array( 'ns' => 0, 'title' => 'AQBT-Links' ),
+                       array( 'ns' => 0, 'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $alltransclusions = array(
+               array( 'list' => 'alltransclusions', 'atprefix' => 'AQBT-' ),
+               array( 'alltransclusions' => array(
+                       array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
+                       array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
+       ) ) );
+
+       private static $allcategories = array(
+               array( 'list' => 'allcategories', 'acprefix' => 'AQBT-' ),
+               array( 'allcategories' => array(
+                       array( '*' => 'AQBT-Cat' ),
+       ) ) );
+
+       private static $backlinks = array(
+               array( 'list' => 'backlinks', 'bltitle' => 'AQBT-Links' ),
+               array( 'backlinks' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+       ) ) );
+
+       private static $embeddedin = array(
+               array( 'list' => 'embeddedin', 'eititle' => 'Template:AQBT-T' ),
+               array( 'embeddedin' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $categorymembers = array(
+               array( 'list' => 'categorymembers', 'cmtitle' => 'Category:AQBT-Cat' ),
+               array( 'categorymembers' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
+       ) ) );
+
+       private static $generatorAllpages = array(
+               array( 'generator' => 'allpages', 'gapprefix' => 'AQBT-' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All' ),
+                       '2' => array(
+                               'pageid' => 2,
+                               'ns' => 0,
+                               'title' => 'AQBT-Categories' ),
+                       '3' => array(
+                               'pageid' => 3,
+                               'ns' => 0,
+                               'title' => 'AQBT-Links' ),
+                       '4' => array(
+                               'pageid' => 4,
+                               'ns' => 0,
+                               'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $generatorLinks = array(
+               array( 'generator' => 'links', 'titles' => 'AQBT-Links' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All' ),
+                       '2' => array(
+                               'pageid' => 2,
+                               'ns' => 0,
+                               'title' => 'AQBT-Categories' ),
+                       '4' => array(
+                               'pageid' => 4,
+                               'ns' => 0,
+                               'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $generatorLinksPropLinks = array(
+               array( 'prop' => 'links' ),
+               array( 'pages' => array(
+                       '1' => array( 'links' => array(
+                               array( 'ns' => 0, 'title' => 'AQBT-Links' ),
+       ) ) ) ) );
+
+       private static $generatorLinksPropTemplates = array(
+               array( 'prop' => 'templates' ),
+               array( 'pages' => array(
+                       '1' => array( 'templates' => array(
+                               array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
+                       '4' => array( 'templates' => array(
+                               array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
+               ) ) );
+
+       /**
+        * Test basic props
+        */
+       public function testProps() {
+               $this->check( self::$links );
+               $this->check( self::$templates );
+               $this->check( self::$categories );
+       }
+
+       /**
+        * Test basic lists
+        */
+       public function testLists() {
+               $this->check( self::$allpages );
+               $this->check( self::$alllinks );
+               $this->check( self::$alltransclusions );
+               // This test is temporarily disabled until a sqlite bug is fixed
+               // $this->check( self::$allcategories );
+               $this->check( self::$backlinks );
+               $this->check( self::$embeddedin );
+               $this->check( self::$categorymembers );
+       }
+
+       /**
+        * Test basic lists
+        */
+       public function testAllTogether() {
+
+               // All props together
+               $this->check( $this->merge(
+                       self::$links,
+                       self::$templates,
+                       self::$categories
+               ) );
+
+               // All lists together
+               $this->check( $this->merge(
+                       self::$allpages,
+                       self::$alllinks,
+                       self::$alltransclusions,
+                       // This test is temporarily disabled until a sqlite bug is fixed
+                       // self::$allcategories,
+                       self::$backlinks,
+                       self::$embeddedin,
+                       self::$categorymembers
+               ) );
+
+               // All props+lists together
+               $this->check( $this->merge(
+                       self::$links,
+                       self::$templates,
+                       self::$categories,
+                       self::$allpages,
+                       self::$alllinks,
+                       self::$alltransclusions,
+                       // This test is temporarily disabled until a sqlite bug is fixed
+                       // self::$allcategories,
+                       self::$backlinks,
+                       self::$embeddedin,
+                       self::$categorymembers
+               ) );
+       }
+
+       /**
+        * Test basic lists
+        */
+       public function testGenerator() {
+               // generator=allpages
+               $this->check( self::$generatorAllpages );
+               // generator=allpages & list=allpages
+               $this->check( $this->merge(
+                       self::$generatorAllpages,
+                       self::$allpages ) );
+               // generator=links
+               $this->check( self::$generatorLinks );
+               // generator=links & prop=links
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropLinks ) );
+               // generator=links & prop=templates
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropTemplates ) );
+               // generator=links & prop=links|templates
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropLinks,
+                       self::$generatorLinksPropTemplates ) );
+               // generator=links & prop=links|templates & list=allpages|...
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropLinks,
+                       self::$generatorLinksPropTemplates,
+                       self::$allpages,
+                       self::$alllinks,
+                       self::$alltransclusions,
+                       // This test is temporarily disabled until a sqlite bug is fixed
+                       // self::$allcategories,
+                       self::$backlinks,
+                       self::$embeddedin,
+                       self::$categorymembers ) );
+       }
+
+       /**
+        * Merges all requests (parameter arrays) into one
+        * @return array
+        */
+       private function merge( /*...*/ ) {
+               $request = array();
+               $expected = array();
+               foreach ( func_get_args() as $v ) {
+                       $request = array_merge_recursive( $request, $v[0] );
+                       $this->mergeExpected( $expected, $v[1] );
+               }
+               return array( $request, $expected );
+       }
+
+       /**
+        * Recursively merges the expected values in the $item into the $all
+        */
+       private function mergeExpected( &$all, $item ) {
+               foreach ( $item as $k => $v ) {
+                       if ( array_key_exists( $k, $all ) ) {
+                               if ( is_array( $all[$k] ) ) {
+                                       $this->mergeExpected( $all[$k], $v );
+                               } else {
+                                       $this->assertEquals( $all[$k], $v );
+                               }
+                       } else {
+                               $all[$k] = $v;
+                       }
+               }
+       }
+
+       /**
+        * Checks that the request's result matches the expected results.
+        * @param $values array is a two element array( request, expected_results )
+        * @throws Exception
+        */
+       private function check( $values ) {
+               $request = $values[0];
+               $expected = $values[1];
+               if ( !array_key_exists( 'action', $request ) ) {
+                       $request['action'] = 'query';
+               }
+               foreach ( $request as &$val ) {
+                       if ( is_array( $val ) ) {
+                               $val = implode( '|', array_unique( $val ) );
+                       }
+               }
+               $result = $this->doApiRequest( $request );
+               $result = $result[0];
+               $expected = array( 'query' => $expected );
+               try {
+                       $this->assertQueryResults( $expected, $result );
+               } catch ( Exception $e ) {
+                       print( "\nRequest:\n" );
+                       print_r( $request );
+                       print( "\nExpected:\n" );
+                       print_r( $expected );
+                       print( "\nResult:\n" );
+                       print_r( $result );
+                       throw $e; // rethrow it
+               }
+       }
+
+       /**
+        * Recursively compare arrays, ignoring mismatches in numeric key and pageids.
+        * @param $expected array expected values
+        * @param $result array returned values
+        */
+       private function assertQueryResults( $expected, $result ) {
+               reset( $expected );
+               reset( $result );
+               while ( true ) {
+                       $e = each( $expected );
+                       $r = each( $result );
+                       // If either of the arrays is shorter, abort. If both are done, success.
+                       $this->assertEquals( (bool)$e, (bool)$r );
+                       if ( !$e ) {
+                               break; // done
+                       }
+                       // continue only if keys are identical or both keys are numeric
+                       $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) );
+                       // don't compare pageids
+                       if ( $e['key'] !== 'pageid' ) {
+                               // If values are arrays, compare recursively, otherwise compare with ===
+                               if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) {
+                                       $this->assertQueryResults( $e['value'], $r['value'] );
+                               } else {
+                                       $this->assertEquals( $e['value'], $r['value'] );
+                               }
+                       }
+               }
+       }
+}
diff --git a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php
new file mode 100644 (file)
index 0000000..7f5fe91
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ */
+class ApiQueryRevisionsTest extends ApiTestCase {
+
+       /**
+        * @group medium
+        */
+       function testContentComesWithContentModelAndFormat() {
+               $pageName = 'Help:' . __METHOD__;
+               $title = Title::newFromText( $pageName );
+               $page = WikiPage::factory( $title );
+               $page->doEdit( 'Some text', 'inserting content' );
+
+               $apiResult = $this->doApiRequest( array(
+                       'action' => 'query',
+                       'prop' => 'revisions',
+                       'titles' => $pageName,
+                       'rvprop' => 'content',
+               ) );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'pages', $apiResult[0]['query'] );
+               foreach ( $apiResult[0]['query']['pages'] as $page ) {
+                       $this->assertArrayHasKey( 'revisions', $page );
+                       foreach ( $page['revisions'] as $revision ) {
+                               $this->assertArrayHasKey( 'contentformat', $revision,
+                                       'contentformat should be included when asking content so client knows how to interpret it'
+                               );
+                               $this->assertArrayHasKey( 'contentmodel', $revision,
+                                       'contentmodel should be included when asking content so client knows how to interpret it'
+                               );
+                       }
+               }
+       }
+}
diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php
new file mode 100644 (file)
index 0000000..7fb5307
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ */
+class ApiQueryTest extends ApiTestCase {
+
+       protected function setUp() {
+               parent::setUp();
+               $this->doLogin();
+       }
+
+       function testTitlesGetNormalized() {
+
+               global $wgMetaNamespace;
+
+               $data = $this->doApiRequest( array(
+                       'action' => 'query',
+                       'titles' => 'Project:articleA|article_B' ) );
+
+
+               $this->assertArrayHasKey( 'query', $data[0] );
+               $this->assertArrayHasKey( 'normalized', $data[0]['query'] );
+
+               // Forge a normalized title
+               $to = Title::newFromText( $wgMetaNamespace . ':ArticleA' );
+
+               $this->assertEquals(
+                       array(
+                               'from' => 'Project:articleA',
+                               'to' => $to->getPrefixedText(),
+                       ),
+                       $data[0]['query']['normalized'][0]
+               );
+
+               $this->assertEquals(
+                       array(
+                               'from' => 'article_B',
+                               'to' => 'Article B'
+                       ),
+                       $data[0]['query']['normalized'][1]
+               );
+
+       }
+
+       function testTitlesAreRejectedIfInvalid() {
+               $title = false;
+               while ( !$title || Title::newFromText( $title )->exists() ) {
+                       $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) );
+               }
+
+               $data = $this->doApiRequest( array(
+                       'action' => 'query',
+                       'titles' => $title . '|Talk:' ) );
+
+               $this->assertArrayHasKey( 'query', $data[0] );
+               $this->assertArrayHasKey( 'pages', $data[0]['query'] );
+               $this->assertEquals( 2, count( $data[0]['query']['pages'] ) );
+
+               $this->assertArrayHasKey( -2, $data[0]['query']['pages'] );
+               $this->assertArrayHasKey( -1, $data[0]['query']['pages'] );
+
+               $this->assertArrayHasKey( 'missing', $data[0]['query']['pages'][-2] );
+               $this->assertArrayHasKey( 'invalid', $data[0]['query']['pages'][-1] );
+       }
+
+}
index 52cdc78..ee3db3e 100644 (file)
@@ -15,7 +15,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
 
        function addDBData() {
                $user = User::newFromName( 'UTMale' );
-               if( $user->getID() == 0 ) {
+               if ( $user->getID() == 0 ) {
                        $user->addToDatabase();
                        $user->setPassword( 'UTMalePassword' );
                }
@@ -24,7 +24,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
                $user->saveSettings();
 
                $user = User::newFromName( 'UTFemale' );
-               if( $user->getID() == 0 ) {
+               if ( $user->getID() == 0 ) {
                        $user->addToDatabase();
                        $user->setPassword( 'UTFemalePassword' );
                }
@@ -33,7 +33,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
                $user->saveSettings();
 
                $user = User::newFromName( 'UTDefaultGender' );
-               if( $user->getID() == 0 ) {
+               if ( $user->getID() == 0 ) {
                        $user->addToDatabase();
                        $user->setPassword( 'UTDefaultGenderPassword' );
                }
index 1c081b8..c7e75d9 100644 (file)
@@ -24,7 +24,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
         */
        function fillCache( &$cache, $numEntries ) {
                // Fill cache with three values
-               for( $i=1; $i<=$numEntries; $i++) {
+               for ( $i = 1; $i <= $numEntries; $i++ ) {
                        $cache->set( "cache-key-$i", "prop-$i", "value-$i" );
                }
        }
@@ -36,10 +36,10 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
        function getExpectedCache( $cacheMaxEntries, $entryToFill ) {
                $expected = array();
 
-               if( $entryToFill === 0 ) {
+               if ( $entryToFill === 0 ) {
                        # The cache is empty!
                        return array();
-               } elseif( $entryToFill <= $cacheMaxEntries ) {
+               } elseif ( $entryToFill <= $cacheMaxEntries ) {
                        # Cache is not fully filled
                        $firstKey = 1;
                } else {
@@ -47,9 +47,9 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
                        $firstKey = 1 + $entryToFill - $cacheMaxEntries;
                }
 
-               $lastKey  = $entryToFill;
+               $lastKey = $entryToFill;
 
-               for( $i=$firstKey; $i<=$lastKey; $i++ ) {
+               for ( $i = $firstKey; $i <= $lastKey; $i++ ) {
                        $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" );
                }
                return $expected;
@@ -61,7 +61,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
        function testPhpUnitArrayEquality() {
                $one = array( 'A' => 1, 'B' => 2 );
                $two = array( 'B' => 2, 'A' => 1 );
-               $this->assertEquals( $one, $two );  // ==
+               $this->assertEquals( $one, $two ); // ==
                $this->assertNotSame( $one, $two ); // ===
        }
 
@@ -118,7 +118,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
         */
        function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) {
                $cache = new ProcessCacheLRUTestable( $cacheMaxEntries );
-               $this->fillCache( $cache, $entryToFill);
+               $this->fillCache( $cache, $entryToFill );
 
                $this->assertSame(
                        $this->getExpectedCache( $cacheMaxEntries, $entryToFill ),
@@ -134,12 +134,11 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
        public static function provideCacheFilling() {
                // ($cacheMaxEntries, $entryToFill, $msg='')
                return array(
-                       array( 1,  0 ),
-                       array( 1,  1 ),
-                       array( 1,  2 ), # overflow
+                       array( 1, 0 ),
+                       array( 1, 1 ),
+                       array( 1, 2 ), # overflow
                        array( 5, 33 ), # overflow
                );
-
        }
 
        /**
@@ -167,7 +166,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
 
        function testRecentlyAccessedKeyStickIn() {
                $cache = new ProcessCacheLRUTestable( 2 );
-               $cache->set( 'first' , 'prop1', 'value1' );
+               $cache->set( 'first', 'prop1', 'value1' );
                $cache->set( 'second', 'prop2', 'value2' );
 
                // Get first
@@ -233,6 +232,7 @@ class ProcessCacheLRUTestable extends ProcessCacheLRU {
        public function getCache() {
                return $this->cache;
        }
+
        public function getEntriesCount() {
                return count( $this->cache );
        }
index 73d0012..19ceadd 100644 (file)
@@ -103,7 +103,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
 
                if ( $expected ) {
                        $this->assertNotNull( $name, "no name found for content model $id" );
-                       $this->assertTrue( preg_match( $expected, $name ) > 0 ,
+                       $this->assertTrue( preg_match( $expected, $name ) > 0,
                                "content model name for #$id did not match pattern $expected"
                        );
                } else {
@@ -145,7 +145,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertEquals( $expected->getCode(), $lang->getCode() );
        }
 
-       public function testGetContentText_Null( ) {
+       public function testGetContentText_Null() {
                global $wgContentHandlerTextFallback;
 
                $content = null;
@@ -163,7 +163,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertEquals( '', $text );
        }
 
-       public function testGetContentText_TextContent( ) {
+       public function testGetContentText_TextContent() {
                global $wgContentHandlerTextFallback;
 
                $content = new WikitextContent( "hello world" );
@@ -181,7 +181,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertEquals( $content->getNativeData(), $text );
        }
 
-       public function testGetContentText_NonTextContent( ) {
+       public function testGetContentText_NonTextContent() {
                global $wgContentHandlerTextFallback;
 
                $content = new DummyContentForTesting( "hello world" );
@@ -213,15 +213,15 @@ class ContentHandlerTest extends MediaWikiTestCase {
                return array(
                        array( 'hallo', 'Help:Test', null, null, CONTENT_MODEL_WIKITEXT, 'hallo', false ),
                        array( 'hallo', 'MediaWiki:Test.js', null, null, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ),
-                       array( serialize('hallo'), 'Dummy:Test', null, null, "testing", 'hallo', false ),
+                       array( serialize( 'hallo' ), 'Dummy:Test', null, null, "testing", 'hallo', false ),
 
                        array( 'hallo', 'Help:Test', null, CONTENT_FORMAT_WIKITEXT, CONTENT_MODEL_WIKITEXT, 'hallo', false ),
                        array( 'hallo', 'MediaWiki:Test.js', null, CONTENT_FORMAT_JAVASCRIPT, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ),
-                       array( serialize('hallo'), 'Dummy:Test', null, "testing", "testing", 'hallo', false ),
+                       array( serialize( 'hallo' ), 'Dummy:Test', null, "testing", "testing", 'hallo', false ),
 
                        array( 'hallo', 'Help:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ),
                        array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ),
-                       array( serialize('hallo'), 'Dummy:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, serialize('hallo'), false ),
+                       array( serialize( 'hallo' ), 'Dummy:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, serialize( 'hallo' ), false ),
 
                        array( 'hallo', 'Help:Test', CONTENT_MODEL_WIKITEXT, "testing", null, null, true ),
                        array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, "testing", null, null, true ),
@@ -245,10 +245,14 @@ class ContentHandlerTest extends MediaWikiTestCase {
                        $this->assertEquals( $expectedModelId, $content->getModel(), 'bad model id' );
                        $this->assertEquals( $expectedNativeData, $content->getNativeData(), 'bads native data' );
                } catch ( MWException $ex ) {
-                       if ( !$shouldFail ) $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() );
-                       else $this->assertTrue( true ); // dummy, so we don't get the "test did not perform any assertions" message.
+                       if ( !$shouldFail ) {
+                               $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() );
+                       }
+                       else {
+                               // dummy, so we don't get the "test did not perform any assertions" message.
+                               $this->assertTrue( true );
+                       }
                }
-
        }
 
        /*
@@ -292,7 +296,7 @@ class DummyContentHandlerForTesting extends ContentHandler {
         * @return String serialized form of the content
         */
        public function serializeContent( Content $content, $format = null ) {
-          return $content->serialize();
+               return $content->serialize();
        }
 
        /**
@@ -361,8 +365,7 @@ class DummyContentForTesting extends AbstractContent {
         * @return mixed the native representation of the content. Could be a string, a nested array
         *  structure, an object, a binary blob... anything, really.
         */
-       public function getNativeData()
-       {
+       public function getNativeData() {
                return $this->data;
        }
 
@@ -415,7 +418,7 @@ class DummyContentForTesting extends AbstractContent {
         *
         * @return ParserOutput
         */
-       public function getParserOutput( Title $title, $revId = null, ParserOptions $options = NULL, $generateHtml = true ) {
+       public function getParserOutput( Title $title, $revId = null, ParserOptions $options = null, $generateHtml = true ) {
                return new ParserOutput( $this->getNativeData() );
        }
 }
index b08a468..8f53dd3 100644 (file)
@@ -62,7 +62,7 @@ class CssContentTest extends MediaWikiTestCase {
                $this->assertEquals( CONTENT_MODEL_CSS, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new CssContent( 'hallo' ), null, false ),
                        array( new CssContent( 'hallo' ), new CssContent( 'hallo' ), true ),
index 18df53f..2d693fe 100644 (file)
@@ -39,16 +39,16 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataGetSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                              '0',
-                              null
+                               '0',
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '2',
-                              null
+                               '2',
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '8',
-                              null
+                               '8',
+                               null
                        ),
                );
        }
@@ -57,39 +57,39 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataReplaceSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                              '0',
-                              'No more',
-                              null,
-                              null
+                               '0',
+                               'No more',
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '',
-                              'No more',
-                              null,
-                              null
+                               '',
+                               'No more',
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '2',
-                              "== TEST ==\nmore fun",
-                              null,
-                              null
+                               '2',
+                               "== TEST ==\nmore fun",
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '8',
-                              'No more',
-                              null,
-                              null
+                               '8',
+                               'No more',
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              'new',
-                              'No more',
-                              'New',
-                              null
+                               'new',
+                               'No more',
+                               'New',
+                               null
                        ),
                );
        }
 
-       public function testAddSectionHeader( ) {
+       public function testAddSectionHeader() {
                $content = $this->newContent( 'hello world' );
                $c = $content->addSectionHeader( 'test' );
 
@@ -114,10 +114,10 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataPreloadTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              'hello this is ~~~',
+                               'hello this is ~~~',
                        ),
                        array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
-                              'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
+                               'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
                        ),
                );
        }
@@ -125,13 +125,13 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataGetRedirectTarget() {
                return array(
                        array( '#REDIRECT [[Test]]',
-                              null,
+                               null,
                        ),
                        array( '#REDIRECT Test',
-                              null,
+                               null,
                        ),
                        array( '* #REDIRECT [[Test]]',
-                              null,
+                               null,
                        ),
                );
        }
@@ -159,59 +159,59 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataIsCountable() {
                return array(
                        array( '',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo, bar',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo',
-                              null,
-                              'link',
-                              false
+                               null,
+                               'link',
+                               false
                        ),
                        array( 'Foo [[bar]]',
-                              null,
-                              'link',
-                              false
+                               null,
+                               'link',
+                               false
                        ),
                        array( 'Foo',
-                              true,
-                              'link',
-                              false
+                               true,
+                               'link',
+                               false
                        ),
                        array( 'Foo [[bar]]',
-                              false,
-                              'link',
-                              false
+                               false,
+                               'link',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'any',
-                              true
+                               true,
+                               'any',
+                               true
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'comma',
-                              false
+                               true,
+                               'comma',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'link',
-                              false
+                               true,
+                               'link',
+                               false
                        ),
                );
        }
@@ -219,28 +219,28 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataGetTextForSummary() {
                return array(
                        array( "hello\nworld.",
-                              16,
-                              'hello world.',
+                               16,
+                               'hello world.',
                        ),
                        array( 'hello world.',
-                              8,
-                              'hello...',
+                               8,
+                               'hello...',
                        ),
                        array( '[[hello world]].',
-                              8,
-                              '[[hel...',
+                               8,
+                               '[[hel...',
                        ),
                );
        }
 
-       public function testMatchMagicWord( ) {
+       public function testMatchMagicWord() {
                $mw = MagicWord::get( "staticredirect" );
 
                $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
                $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word, since it's not wikitext" );
        }
 
-       public function testUpdateRedirect( ) {
+       public function testUpdateRedirect() {
                $target = Title::newFromText( "testUpdateRedirect_target" );
 
                $content = $this->newContent( "#REDIRECT [[Someplace]]" );
@@ -261,7 +261,7 @@ class JavaScriptContentTest extends TextContentTest {
                $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new JavaScriptContent( "hallo" ), null, false ),
                        array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "hallo" ), true ),
index 3501aec..382f71a 100644 (file)
@@ -22,6 +22,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                                CONTENT_MODEL_CSS,
                                CONTENT_MODEL_JAVASCRIPT,
                        ),
+                       'wgUseTidy' => false,
                        'wgAlwaysUseTidy' => false,
                ) );
 
@@ -142,7 +143,7 @@ class TextContentTest extends MediaWikiLangTestCase {
         */
        public function testGetRedirectTarget( $text, $expected ) {
                $content = $this->newContent( $text );
-               $t = $content->getRedirectTarget( );
+               $t = $content->getRedirectTarget();
 
                if ( is_null( $expected ) ) {
                        $this->assertNull( $t, "text should not have generated a redirect target: $text" );
@@ -157,7 +158,7 @@ class TextContentTest extends MediaWikiLangTestCase {
        public function testIsRedirect( $text, $expected ) {
                $content = $this->newContent( $text );
 
-               $this->assertEquals( !is_null($expected), $content->isRedirect() );
+               $this->assertEquals( !is_null( $expected ), $content->isRedirect() );
        }
 
        /**
@@ -183,29 +184,28 @@ class TextContentTest extends MediaWikiLangTestCase {
        public static function dataIsCountable() {
                return array(
                        array( '',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo, bar',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                );
        }
 
-
        /**
         * @dataProvider dataIsCountable
         * @group Database
@@ -222,22 +222,22 @@ class TextContentTest extends MediaWikiLangTestCase {
                $wgArticleCountMethod = $old;
 
                $this->assertEquals( $expected, $v, 'isCountable() returned unexpected value ' . var_export( $v, true )
-                                                   . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
+                       . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
        }
 
        public static function dataGetTextForSummary() {
                return array(
                        array( "hello\nworld.",
-                              16,
-                              'hello world.',
+                               16,
+                               'hello world.',
                        ),
                        array( 'hello world.',
-                              8,
-                              'hello...',
+                               8,
+                               'hello...',
                        ),
                        array( '[[hello world]].',
-                              8,
-                              '[[hel...',
+                               8,
+                               '[[hel...',
                        ),
                );
        }
@@ -251,8 +251,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
        }
 
-
-       public function testGetTextForSearchIndex( ) {
+       public function testGetTextForSearchIndex() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() );
@@ -266,19 +265,19 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( 'hello world.', $copy->getNativeData() );
        }
 
-       public function testGetSize( ) {
+       public function testGetSize() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 12, $content->getSize() );
        }
 
-       public function testGetNativeData( ) {
+       public function testGetNativeData() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 'hello world.', $content->getNativeData() );
        }
 
-       public function testGetWikitextForTransclusion( ) {
+       public function testGetWikitextForTransclusion() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() );
@@ -296,7 +295,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataIsEmpty( ) {
+       public static function dataIsEmpty() {
                return array(
                        array( '', true ),
                        array( '  ', false ),
@@ -314,7 +313,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( $empty, $content->isEmpty() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new TextContent( "hallo" ), null, false ),
                        array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ),
@@ -333,13 +332,13 @@ class TextContentTest extends MediaWikiLangTestCase {
 
        public static function dataGetDeletionUpdates() {
                return array(
-                       array("TextContentTest_testGetSecondaryDataUpdates_1",
+                       array( "TextContentTest_testGetSecondaryDataUpdates_1",
                                CONTENT_MODEL_TEXT, "hello ''world''\n",
-                               array( )
+                               array()
                        ),
-                       array("TextContentTest_testGetSecondaryDataUpdates_2",
+                       array( "TextContentTest_testGetSecondaryDataUpdates_2",
                                CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n",
-                               array( )
+                               array()
                        ),
                        // TODO: more...?
                );
@@ -349,17 +348,20 @@ class TextContentTest extends MediaWikiLangTestCase {
         * @dataProvider dataGetDeletionUpdates
         */
        public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) {
-               $title = Title::newFromText( $title );
-               $title->resetArticleID( 2342 ); //dummy id. fine as long as we don't try to execute the updates!
+               $ns = $this->getDefaultWikitextNS();
+               $title = Title::newFromText( $title, $ns );
 
                $content = ContentHandler::makeContent( $text, $title, $model );
 
-               $updates = $content->getDeletionUpdates( WikiPage::factory( $title ) );
+               $page = WikiPage::factory( $title );
+               $page->doEditContent( $content, '' );
+
+               $updates = $content->getDeletionUpdates( $page );
 
                // make updates accessible by class name
                foreach ( $updates as $update ) {
                        $class = get_class( $update );
-                       $updates[ $class ] = $update;
+                       $updates[$class] = $update;
                }
 
                if ( !$expectedStuff ) {
@@ -370,13 +372,15 @@ class TextContentTest extends MediaWikiLangTestCase {
                foreach ( $expectedStuff as $class => $fieldValues ) {
                        $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
 
-                       $update = $updates[ $class ];
+                       $update = $updates[$class];
 
                        foreach ( $fieldValues as $field => $value ) {
                                $v = $update->$field; #if the field doesn't exist, just crash and burn
                                $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
                        }
                }
+
+               $page->doDeleteArticle( '' );
        }
 
        public static function provideConvert() {
index 8121099..0f6a968 100644 (file)
@@ -16,7 +16,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT );
        }
 
-       public function testSerializeContent( ) {
+       public function testSerializeContent() {
                $content = new WikitextContent( 'hello world' );
 
                $this->assertEquals( 'hello world', $this->handler->serializeContent( $content ) );
@@ -30,7 +30,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                }
        }
 
-       public function testUnserializeContent( ) {
+       public function testUnserializeContent() {
                $content = $this->handler->unserializeContent( 'hello world' );
                $this->assertEquals( 'hello world', $content->getNativeData() );
 
@@ -52,7 +52,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->assertEquals( '', $content->getNativeData() );
        }
 
-       public static function dataIsSupportedFormat( ) {
+       public static function dataIsSupportedFormat() {
                return array(
                        array( null, true ),
                        array( CONTENT_FORMAT_WIKITEXT, true ),
@@ -67,21 +67,22 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->assertEquals( $supported, $this->handler->isSupportedFormat( $format ) );
        }
 
-       public static function dataMerge3( ) {
+       public static function dataMerge3() {
                return array(
-                       array( "first paragraph
+                       array(
+                               "first paragraph
 
                                        second paragraph\n",
 
-                                       "FIRST paragraph
+                               "FIRST paragraph
 
                                        second paragraph\n",
 
-                                       "first paragraph
+                               "first paragraph
 
                                        SECOND paragraph\n",
 
-                                       "FIRST paragraph
+                               "FIRST paragraph
 
                                        SECOND paragraph\n",
                        ),
@@ -89,13 +90,12 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                        array( "first paragraph
                                        second paragraph\n",
 
-                                  "Bla bla\n",
+                               "Bla bla\n",
 
-                                  "Blubberdibla\n",
+                               "Blubberdibla\n",
 
-                                  false,
+                               false,
                        ),
-
                );
        }
 
@@ -115,7 +115,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->assertEquals( $expected, $merged ? $merged->getNativeData() : $merged );
        }
 
-       public static function dataGetAutosummary( ) {
+       public static function dataGetAutosummary() {
                return array(
                        array(
                                'Hello there, world!',
index b76e9aa..c9eecf7 100644 (file)
@@ -7,10 +7,7 @@
  *        ^--- needed, because we do need the database to test link updates
  */
 class WikitextContentTest extends TextContentTest {
-
-       static $sections =
-
-"Intro
+       static $sections = "Intro
 
 == stuff ==
 hello world
@@ -69,11 +66,14 @@ more stuff
         * @group Database
         */
        public function testGetSecondaryDataUpdates( $title, $model, $text, $expectedStuff ) {
-               $title = Title::newFromText( $title );
-               $title->resetArticleID( 2342 ); //dummy id. fine as long as we don't try to execute the updates!
+               $ns = $this->getDefaultWikitextNS();
+               $title = Title::newFromText( $title, $ns );
 
                $content = ContentHandler::makeContent( $text, $title, $model );
 
+               $page = WikiPage::factory( $title );
+               $page->doEditContent( $content, '' );
+
                $updates = $content->getSecondaryDataUpdates( $title );
 
                // make updates accessible by class name
@@ -92,22 +92,24 @@ more stuff
                                $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
                        }
                }
+
+               $page->doDeleteArticle( '' );
        }
 
        public static function dataGetSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                                       "0",
-                                       "Intro"
+                               "0",
+                               "Intro"
                        ),
                        array( WikitextContentTest::$sections,
-                                       "2",
-"== test ==
+                               "2",
+                               "== test ==
 just a test"
                        ),
                        array( WikitextContentTest::$sections,
-                                       "8",
-                                       false
+                               "8",
+                               false
                        ),
                );
        }
@@ -131,34 +133,34 @@ just a test"
        public static function dataReplaceSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                              "0",
-                              "No more",
-                              null,
-                              trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) )
+                               "0",
+                               "No more",
+                               null,
+                               trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) )
                        ),
                        array( WikitextContentTest::$sections,
-                              "",
-                              "No more",
-                              null,
-                              "No more"
+                               "",
+                               "No more",
+                               null,
+                               "No more"
                        ),
                        array( WikitextContentTest::$sections,
-                              "2",
-                              "== TEST ==\nmore fun",
-                              null,
-                              trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikitextContentTest::$sections ) )
+                               "2",
+                               "== TEST ==\nmore fun",
+                               null,
+                               trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikitextContentTest::$sections ) )
                        ),
                        array( WikitextContentTest::$sections,
-                              "8",
-                              "No more",
-                              null,
-                              WikitextContentTest::$sections
+                               "8",
+                               "No more",
+                               null,
+                               WikitextContentTest::$sections
                        ),
                        array( WikitextContentTest::$sections,
-                              "new",
-                              "No more",
-                              "New",
-                              trim( WikitextContentTest::$sections ) . "\n\n\n== New ==\n\nNo more"
+                               "new",
+                               "No more",
+                               "New",
+                               trim( WikitextContentTest::$sections ) . "\n\n\n== New ==\n\nNo more"
                        ),
                );
        }
@@ -173,7 +175,7 @@ just a test"
                $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() );
        }
 
-       public function testAddSectionHeader( ) {
+       public function testAddSectionHeader() {
                $content = $this->newContent( 'hello world' );
                $content = $content->addSectionHeader( 'test' );
 
@@ -183,10 +185,10 @@ just a test"
        public static function dataPreSaveTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
+                               "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
                        ),
                        array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
-                              'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
+                               'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
                        ),
                        array( // rtrim
                                " Foo \n ",
@@ -198,10 +200,10 @@ just a test"
        public static function dataPreloadTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              "hello this is ~~~",
+                               "hello this is ~~~",
                        ),
                        array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
-                              'hello \'\'this\'\' is bar',
+                               'hello \'\'this\'\' is bar',
                        ),
                );
        }
@@ -209,13 +211,13 @@ just a test"
        public static function dataGetRedirectTarget() {
                return array(
                        array( '#REDIRECT [[Test]]',
-                              'Test',
+                               'Test',
                        ),
                        array( '#REDIRECT Test',
-                              null,
+                               null,
                        ),
                        array( '* #REDIRECT [[Test]]',
-                              null,
+                               null,
                        ),
                );
        }
@@ -260,64 +262,64 @@ just a test"
        public static function dataIsCountable() {
                return array(
                        array( '',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo, bar',
-                              null,
-                              'comma',
-                              true
+                               null,
+                               'comma',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'link',
-                              false
+                               null,
+                               'link',
+                               false
                        ),
                        array( 'Foo [[bar]]',
-                              null,
-                              'link',
-                              true
+                               null,
+                               'link',
+                               true
                        ),
                        array( 'Foo',
-                              true,
-                              'link',
-                              true
+                               true,
+                               'link',
+                               true
                        ),
                        array( 'Foo [[bar]]',
-                              false,
-                              'link',
-                              false
+                               false,
+                               'link',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'any',
-                              false
+                               true,
+                               'any',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'comma',
-                              false
+                               true,
+                               'comma',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'link',
-                              false
+                               true,
+                               'link',
+                               false
                        ),
                );
        }
 
-       public function testMatchMagicWord( ) {
+       public function testMatchMagicWord() {
                $mw = MagicWord::get( "staticredirect" );
 
                $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
@@ -327,7 +329,7 @@ just a test"
                $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" );
        }
 
-       public function testUpdateRedirect( ) {
+       public function testUpdateRedirect() {
                $target = Title::newFromText( "testUpdateRedirect_target" );
 
                // test with non-redirect page
@@ -358,7 +360,7 @@ just a test"
                $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new WikitextContent( "hallo" ), null, false ),
                        array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ),
@@ -370,16 +372,15 @@ just a test"
 
        public static function dataGetDeletionUpdates() {
                return array(
-                       array("WikitextContentTest_testGetSecondaryDataUpdates_1",
+                       array( "WikitextContentTest_testGetSecondaryDataUpdates_1",
                                CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
-                               array( 'LinksDeletionUpdate' => array( ) )
+                               array( 'LinksDeletionUpdate' => array() )
                        ),
-                       array("WikitextContentTest_testGetSecondaryDataUpdates_2",
+                       array( "WikitextContentTest_testGetSecondaryDataUpdates_2",
                                CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
-                               array( 'LinksDeletionUpdate' => array( ) )
+                               array( 'LinksDeletionUpdate' => array() )
                        ),
                        // @todo: more...?
                );
        }
-
 }
index 51127f8..0979243 100644 (file)
@@ -39,8 +39,8 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'conds' => array( 'alias' => 'text' ),
                                ),
                                "SELECT  field,field2 AS alias  " .
-                               "FROM `unittest_table`  " .
-                               "WHERE alias = 'text'"
+                                       "FROM `unittest_table`  " .
+                                       "WHERE alias = 'text'"
                        ),
                        array(
                                array(
@@ -50,10 +50,10 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
                                ),
                                "SELECT  field,field2 AS alias  " .
-                               "FROM `unittest_table`  " .
-                               "WHERE alias = 'text'  " .
-                               "ORDER BY field " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table`  " .
+                                       "WHERE alias = 'text'  " .
+                                       "ORDER BY field " .
+                                       "LIMIT 1"
                        ),
                        array(
                                array(
@@ -63,13 +63,13 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
                                        'join_conds' => array( 't2' => array(
                                                'LEFT JOIN', 'tid = t2.id'
-                                       )),
+                                       ) ),
                                ),
                                "SELECT  tid,field,field2 AS alias,t2.id  " .
-                               "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
-                               "WHERE alias = 'text'  " .
-                               "ORDER BY field " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
+                                       "WHERE alias = 'text'  " .
+                                       "ORDER BY field " .
+                                       "LIMIT 1"
                        ),
                        array(
                                array(
@@ -79,13 +79,13 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'GROUP BY' => 'field', 'HAVING' => 'COUNT(*) > 1' ),
                                        'join_conds' => array( 't2' => array(
                                                'LEFT JOIN', 'tid = t2.id'
-                                       )),
+                                       ) ),
                                ),
                                "SELECT  tid,field,field2 AS alias,t2.id  " .
-                               "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
-                               "WHERE alias = 'text'  " .
-                               "GROUP BY field HAVING COUNT(*) > 1 " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
+                                       "WHERE alias = 'text'  " .
+                                       "GROUP BY field HAVING COUNT(*) > 1 " .
+                                       "LIMIT 1"
                        ),
                        array(
                                array(
@@ -95,13 +95,13 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'GROUP BY' => array( 'field', 'field2' ), 'HAVING' => array( 'COUNT(*) > 1', 'field' => 1 ) ),
                                        'join_conds' => array( 't2' => array(
                                                'LEFT JOIN', 'tid = t2.id'
-                                       )),
+                                       ) ),
                                ),
                                "SELECT  tid,field,field2 AS alias,t2.id  " .
-                               "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
-                               "WHERE alias = 'text'  " .
-                               "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
+                                       "WHERE alias = 'text'  " .
+                                       "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " .
+                                       "LIMIT 1"
                        ),
                );
        }
@@ -145,4 +145,4 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                        ),
                );
        }
-}
\ No newline at end of file
+}
index a391fc5..7b84d47 100644 (file)
@@ -3,7 +3,7 @@
 class MockDatabaseSqlite extends DatabaseSqliteStandalone {
        var $lastQuery;
 
-       function __construct( ) {
+       function __construct() {
                parent::__construct( ':memory:' );
        }
 
@@ -12,7 +12,10 @@ class MockDatabaseSqlite extends DatabaseSqliteStandalone {
                return true;
        }
 
-       function replaceVars( $s ) {
+       /**
+        * Override parent visibility to public
+        */
+       public function replaceVars( $s ) {
                return parent::replaceVars( $s );
        }
 }
@@ -45,8 +48,8 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
        private function assertResultIs( $expected, $res ) {
                $this->assertNotNull( $res );
                $i = 0;
-               foreach( $res as $row ) {
-                       foreach( $expected[$i] as $key => $value ) {
+               foreach ( $res as $row ) {
+                       foreach ( $expected[$i] as $key => $value ) {
                                $this->assertTrue( isset( $row->$key ) );
                                $this->assertEquals( $value, $row->$key );
                        }
@@ -105,38 +108,38 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" );
 
                $this->assertEquals( "CREATE TABLE /**/foo (foo_key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-                       . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );",
+                               . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );",
                        $this->replaceVars( "CREATE TABLE /**/foo (foo_key int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
                        foo_bar char(13), foo_name varchar(255) binary NOT NULL DEFAULT '', foo_int tinyint ( 8 ), foo_int2 int(16) ) ENGINE=MyISAM;" )
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE foo ( foo1 REAL, foo2 REAL, foo3 REAL );",
                        $this->replaceVars( "CREATE TABLE foo ( foo1 FLOAT, foo2 DOUBLE( 1,10), foo3 DOUBLE PRECISION );" )
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE foo ( foo_binary1 BLOB, foo_binary2 BLOB );",
                        $this->replaceVars( "CREATE TABLE foo ( foo_binary1 binary(16), foo_binary2 varbinary(32) );" )
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE text ( text_foo TEXT );",
                        $this->replaceVars( "CREATE TABLE text ( text_foo tinytext );" ),
                        'Table name changed'
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );",
-                       $this->replaceVars("CREATE TABLE foo ( foobar INT PRIMARY KEY NOT NULL AUTO_INCREMENT );" )
-                       );
+                       $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY NOT NULL AUTO_INCREMENT );" )
+               );
                $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );",
-                       $this->replaceVars("CREATE TABLE foo ( foobar INT PRIMARY KEY AUTO_INCREMENT NOT NULL );" )
-                       );
+                       $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY AUTO_INCREMENT NOT NULL );" )
+               );
 
                $this->assertEquals( "CREATE TABLE enums( enum1 TEXT, myenum TEXT)",
                        $this->replaceVars( "CREATE TABLE enums( enum1 ENUM('A', 'B'), myenum ENUM ('X', 'Y'))" )
-                       );
+               );
 
                $this->assertEquals( "ALTER TABLE foo ADD COLUMN foo_bar INTEGER DEFAULT 42",
                        $this->replaceVars( "ALTER TABLE foo\nADD COLUMN foo_bar int(10) unsigned DEFAULT 42" )
-                       );
+               );
        }
 
        public function testTableName() {
@@ -375,4 +378,12 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                ksort( $indexes );
                return $indexes;
        }
+
+       function testCaseInsensitiveLike() {
+               // TODO: Test this for all databases
+               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $res = $db->query( 'SELECT "a" LIKE "A" AS a' );
+               $row = $res->fetchRow();
+               $this->assertFalse( (bool)$row['a'] );
+       }
 }
index cbbdc1f..65c80d1 100644 (file)
@@ -206,9 +206,7 @@ class DatabaseTest extends MediaWikiTestCase {
 
        private function dropFunctions() {
                $this->db->query( 'DROP FUNCTION IF EXISTS mw_test_function'
-                       . ( $this->db->getType() == 'postgres'  ? '()' : '' )
+                               . ( $this->db->getType() == 'postgres' ? '()' : '' )
                );
        }
 }
-
-
index 8516241..596d0bd 100644 (file)
@@ -43,19 +43,19 @@ abstract class ORMRowTest extends \MediaWikiTestCase {
         * @since 1.20
         * @return string
         */
-       protected abstract function getRowClass();
+       abstract protected function getRowClass();
 
        /**
         * @since 1.20
         * @return IORMTable
         */
-       protected abstract function getTableInstance();
+       abstract protected function getTableInstance();
 
        /**
         * @since 1.20
         * @return array
         */
-       public abstract function constructorTestProvider();
+       abstract public function constructorTestProvider();
 
        /**
         * @since 1.20
@@ -222,4 +222,4 @@ abstract class ORMRowTest extends \MediaWikiTestCase {
 
        // TODO: test all of the methods!
 
-}
\ No newline at end of file
+}
index bd2c388..9026cb9 100644 (file)
@@ -7,7 +7,7 @@ class MWDebugTest extends MediaWikiTestCase {
                parent::setUp();
                // Make sure MWDebug class is enabled
                static $MWDebugEnabled = false;
-               if( !$MWDebugEnabled ) {
+               if ( !$MWDebugEnabled ) {
                        MWDebug::init();
                        $MWDebugEnabled = true;
                }
@@ -23,10 +23,11 @@ class MWDebugTest extends MediaWikiTestCase {
 
        function testAddLog() {
                MWDebug::log( 'logging a string' );
-               $this->assertEquals( array( array(
-                       'msg' => 'logging a string',
-                       'type' => 'log',
-                       'caller' => __METHOD__ ,
+               $this->assertEquals(
+                       array( array(
+                               'msg' => 'logging a string',
+                               'type' => 'log',
+                               'caller' => __METHOD__,
                        ) ),
                        MWDebug::getLog()
                );
@@ -34,10 +35,11 @@ class MWDebugTest extends MediaWikiTestCase {
 
        function testAddWarning() {
                MWDebug::warning( 'Warning message' );
-               $this->assertEquals( array( array(
-                       'msg' => 'Warning message',
-                       'type' => 'warn',
-                       'caller' => 'MWDebugTest::testAddWarning',
+               $this->assertEquals(
+                       array( array(
+                               'msg' => 'Warning message',
+                               'type' => 'warn',
+                               'caller' => 'MWDebugTest::testAddWarning',
                        ) ),
                        MWDebug::getLog()
                );
index 7beb4fe..dac5edb 100644 (file)
@@ -143,14 +143,14 @@ class FileBackendTest extends MediaWikiTestCase {
                        array( 'mwstore://backend/container/path', 'mwstore://backend/container/path' ),
                        array( 'mwstore://backend/container//path', 'mwstore://backend/container/path' ),
                        array( 'mwstore://backend/container///path', 'mwstore://backend/container/path' ),
-                       array( 'mwstore://backend/container///path//to///obj', 'mwstore://backend/container/path/to/obj',
+                       array( 'mwstore://backend/container///path//to///obj', 'mwstore://backend/container/path/to/obj' ),
                        array( 'mwstore://', null ),
                        array( 'mwstore://backend', null ),
                        array( 'mwstore://backend//container/path', null ),
                        array( 'mwstore://backend//container//path', null ),
                        array( 'mwstore:///', null ),
                        array( 'mwstore:/', null ),
-                       array( 'mwstore:', null ), )
+                       array( 'mwstore:', null ),
                );
        }
 
@@ -799,7 +799,7 @@ class FileBackendTest extends MediaWikiTestCase {
                        $status = $this->prepare( array( 'dir' => dirname( $path ) ) );
                        $this->assertGoodStatus( $status,
                                "Preparing $path succeeded without warnings ($backendName)." );
-                       $ops[] = array( 'op' => 'create', 'dst' => $path, 'content' => mt_rand(0,50000) );
+                       $ops[] = array( 'op' => 'create', 'dst' => $path, 'content' => mt_rand(0, 50000) );
                        $purgeOps[] = array( 'op' => 'delete', 'src' => $path );
                }
                $purgeOps[] = array( 'op' => 'null' );
@@ -1080,7 +1080,7 @@ class FileBackendTest extends MediaWikiTestCase {
                $cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "more file contents" );
                $cases[] = array(
                        array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt",
-                                "$base/unittest-cont1/e/a/z.txt" ),
+                               "$base/unittest-cont1/e/a/z.txt" ),
                        array( "contents xx", "contents xy", "contents xz" )
                );
 
@@ -1149,7 +1149,7 @@ class FileBackendTest extends MediaWikiTestCase {
                $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" );
                $cases[] = array(
                        array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt",
-                                "$base/unittest-cont1/e/a/z.txt" ),
+                               "$base/unittest-cont1/e/a/z.txt" ),
                        array( "contents xx", "contents xy", "contents xz" )
                );
 
@@ -1215,7 +1215,7 @@ class FileBackendTest extends MediaWikiTestCase {
                $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" );
                $cases[] = array(
                        array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt",
-                                "$base/unittest-cont1/e/a/z.txt" ),
+                               "$base/unittest-cont1/e/a/z.txt" ),
                        array( "contents xx", "contents xy", "contents xz" )
                );
 
@@ -1998,12 +1998,22 @@ class FileBackendTest extends MediaWikiTestCase {
 
                $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." );
 
+               $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) );
+               $items = is_array( $iter ) ? $iter : iterator_to_array( $iter );
+               $this->assertEquals( array(), $items, "Directory listing is empty." );
+
                foreach ( $files as $file ) { // clean up
                        $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) );
                }
 
                $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/not/exists" ) );
-               foreach ( $iter as $iter ) {} // no errors
+               foreach ( $iter as $file ) {} // no errors
+               $items = is_array( $iter ) ? $iter : iterator_to_array( $iter );
+               $this->assertEquals( array(), $items, "Directory listing is empty." );
+
+               $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/not/exists" ) );
+               $items = is_array( $iter ) ? $iter : iterator_to_array( $iter );
+               $this->assertEquals( array(), $items, "Directory listing is empty." );
        }
 
        public function testLockCalls() {
index 8f92c12..7cc25b1 100644 (file)
@@ -8,12 +8,14 @@ class FileRepoTest extends MediaWikiTestCase {
        function testFileRepoConstructionOptionCanNotBeNull() {
                $f = new FileRepo();
        }
+
        /**
         * @expectedException MWException
         */
        function testFileRepoConstructionOptionCanNotBeAnEmptyArray() {
                $f = new FileRepo( array() );
        }
+
        /**
         * @expectedException MWException
         */
@@ -22,6 +24,7 @@ class FileRepoTest extends MediaWikiTestCase {
                        'backend' => 'foobar'
                ) );
        }
+
        /**
         * @expectedException MWException
         */
@@ -33,10 +36,10 @@ class FileRepoTest extends MediaWikiTestCase {
 
        function testFileRepoConstructionWithRequiredOptions() {
                $f = new FileRepo( array(
-                       'name'    => 'FileRepoTestRepository',
+                       'name' => 'FileRepoTestRepository',
                        'backend' => new FSFileBackend( array(
-                               'name'           => 'local-testing',
-                               'lockManager'    => 'nullLockManager',
+                               'name' => 'local-testing',
+                               'lockManager' => 'nullLockManager',
                                'containerPaths' => array()
                        ) )
                ) );
index 7d815e9..a89ef98 100644 (file)
@@ -24,18 +24,18 @@ class StoreBatchTest extends MediaWikiTestCase {
                        $backend = new $class( $useConfig );
                } else {
                        $backend = new FSFileBackend( array(
-                               'name'        => 'local-testing',
+                               'name' => 'local-testing',
                                'lockManager' => 'nullLockManager',
                                'containerPaths' => array(
-                                       'unittests-public'  => "{$tmpPrefix}-public",
-                                       'unittests-thumb'   => "{$tmpPrefix}-thumb",
-                                       'unittests-temp'    => "{$tmpPrefix}-temp",
+                                       'unittests-public' => "{$tmpPrefix}-public",
+                                       'unittests-thumb' => "{$tmpPrefix}-thumb",
+                                       'unittests-temp' => "{$tmpPrefix}-temp",
                                        'unittests-deleted' => "{$tmpPrefix}-deleted",
                                )
                        ) );
                }
                $this->repo = new FileRepo( array(
-                       'name'    => 'unittests',
+                       'name' => 'unittests',
                        'backend' => $backend
                ) );
 
@@ -61,7 +61,7 @@ class StoreBatchTest extends MediaWikiTestCase {
         * @param $srcPath string The filepath or virtual URL
         * @param $flags integer Flags to pass into repo::store().
         */
-       private function storeit($originalName, $srcPath, $flags) {
+       private function storeit( $originalName, $srcPath, $flags ) {
                $hashPath = $this->repo->getHashPath( $originalName );
                $dstRel = "$hashPath{$this->date}!$originalName";
                $dstUrlRel = $hashPath . $this->date . '!' . rawurlencode( $originalName );
@@ -80,39 +80,39 @@ class StoreBatchTest extends MediaWikiTestCase {
         * @param $otherfn string The name of the different file (in the filesystem)
         * @param $fromrepo logical 'true' if we want to copy from a virtual URL out of the Repo.
         */
-       private function storecohort($fn, $infn, $otherfn, $fromrepo) {
+       private function storecohort( $fn, $infn, $otherfn, $fromrepo ) {
                $f = $this->storeit( $fn, $infn, 0 );
                $this->assertTrue( $f->isOK(), 'failed to store a new file' );
                $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
-               $this->assertEquals( $f->successCount, 1 , "counts wrong {$f->successCount} {$f->failCount}" );
+               $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
                if ( $fromrepo ) {
-                       $f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE);
+                       $f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE );
                        $infn = $f->value;
                }
                // This should work because we're allowed to overwrite
                $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE );
                $this->assertTrue( $f->isOK(), 'We should be allowed to overwrite' );
                $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
-               $this->assertEquals( $f->successCount, 1 , "counts wrong {$f->successCount} {$f->failCount}" );
+               $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
                // This should fail because we're overwriting.
                $f = $this->storeit( $fn, $infn, 0 );
                $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite' );
                $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
-               $this->assertEquals( $f->successCount, 0 , "counts wrong {$f->successCount} {$f->failCount}" );
+               $this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
                // This should succeed because we're overwriting the same content.
                $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE_SAME );
                $this->assertTrue( $f->isOK(), 'We should be able to overwrite the same content' );
                $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
-               $this->assertEquals( $f->successCount, 1 , "counts wrong {$f->successCount} {$f->failCount}" );
+               $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
                // This should fail because we're overwriting different content.
                if ( $fromrepo ) {
-                       $f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE);
+                       $f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE );
                        $otherfn = $f->value;
                }
                $f = $this->storeit( $fn, $otherfn, FileRepo::OVERWRITE_SAME );
                $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite different content' );
                $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
-               $this->assertEquals( $f->successCount, 0 , "counts wrong {$f->successCount} {$f->failCount}" );
+               $this->assertEquals( $f->successCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
        }
 
        public function teststore() {
index 56485d3..74b921a 100644 (file)
@@ -24,17 +24,17 @@ class InstallDocFormatterTest extends MediaWikiTestCase {
                # Format: (expected string, unformattedText string, optional message)
                return array(
                        # Escape some wikitext
-                       array( 'Install &lt;tag>' , 'Install <tag>', 'Escaping <' ),
-                       array( 'Install &#123;&#123;template}}' , 'Install {{template}}', 'Escaping [[' ),
-                       array( 'Install &#91;&#91;page]]' , 'Install [[page]]', 'Escaping {{' ),
-                       array( 'Install ' , "Install \r", 'Removing \r' ),
+                       array( 'Install &lt;tag>', 'Install <tag>', 'Escaping <' ),
+                       array( 'Install &#123;&#123;template}}', 'Install {{template}}', 'Escaping [[' ),
+                       array( 'Install &#91;&#91;page]]', 'Install [[page]]', 'Escaping {{' ),
+                       array( 'Install ', "Install \r", 'Removing \r' ),
 
                        # Transform \t{1,2} into :{1,2}
                        array( ':One indentation', "\tOne indentation", 'Replacing a single \t' ),
                        array( '::Two indentations', "\t\tTwo indentations", 'Replacing 2 x \t' ),
 
                        # Transform 'bug 123' links
-                       array( 
+                       array(
                                '<span class="config-plainlink">[https://bugzilla.wikimedia.org/123 bug 123]</span>',
                                'bug 123', 'Testing bug 123 links' ),
                        array(
@@ -55,7 +55,7 @@ class InstallDocFormatterTest extends MediaWikiTestCase {
                        array(
                                '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFoo_Bar $wgFoo_Bar]</span>',
                                '$wgFoo_Bar', 'Testing $wgFoo_Bar (with underscore)' ),
-                       
+
                        # Icky variables that shouldn't link
                        array( '$myAwesomeVariable', '$myAwesomeVariable', 'Testing $myAwesomeVariable (not starting with $wg)' ),
                        array( '$()not!a&Var', '$()not!a&Var', 'Testing $()not!a&Var (obviously not a variable)' ),
diff --git a/tests/phpunit/includes/jobqueue/JobQueueTest.php b/tests/phpunit/includes/jobqueue/JobQueueTest.php
new file mode 100644 (file)
index 0000000..453cec3
--- /dev/null
@@ -0,0 +1,292 @@
+<?php
+
+/**
+ * @group JobQueue
+ * @group medium
+ * @group Database
+ */
+class JobQueueTest extends MediaWikiTestCase {
+       protected $key;
+       protected $queueRand, $queueRandTTL, $queueFifo, $queueFifoTTL;
+       protected $old = array();
+
+       function  __construct( $name = null, array $data = array(), $dataName = '' ) {
+               parent::__construct( $name, $data, $dataName );
+
+               $this->tablesUsed[] = 'job';
+       }
+
+       protected function setUp() {
+               global $wgMemc, $wgJobTypeConf;
+               parent::setUp();
+               $this->old['wgMemc'] = $wgMemc;
+               $wgMemc = new HashBagOStuff();
+               if ( $this->getCliArg( 'use-jobqueue=' ) ) {
+                       $name = $this->getCliArg( 'use-jobqueue=' );
+                       if ( !isset( $wgJobTypeConf[$name] ) ) {
+                               throw new MWException( "No \$wgJobTypeConf entry for '$name'." );
+                       }
+                       $baseConfig = $wgJobTypeConf[$name];
+               } else {
+                       $baseConfig = array( 'class' => 'JobQueueDB' );
+               }
+               $baseConfig['type'] = 'null';
+               $baseConfig['wiki'] = wfWikiID();
+               $this->queueRand = JobQueue::factory(
+                       array( 'order' => 'random', 'claimTTL' => 0 ) + $baseConfig );
+               $this->queueRandTTL = JobQueue::factory(
+                       array( 'order' => 'random', 'claimTTL' => 10 ) + $baseConfig );
+               $this->queueFifo = JobQueue::factory(
+                       array( 'order' => 'fifo', 'claimTTL' => 0 ) + $baseConfig );
+               $this->queueFifoTTL = JobQueue::factory(
+                       array( 'order' => 'fifo', 'claimTTL' => 10 ) + $baseConfig );
+               if ( $baseConfig['class'] !== 'JobQueueDB' ) { // DB namespace with prefix or temp tables
+                       foreach ( array( 'queueRand', 'queueRandTTL', 'queueFifo', 'queueFifoTTL' ) as $q ) {
+                               $this->$q->setTestingPrefix( 'unittests-' . wfRandomString( 32 ) );
+                       }
+               }
+       }
+
+       protected function tearDown() {
+               global $wgMemc;
+               parent::tearDown();
+               foreach ( array( 'queueRand', 'queueRandTTL', 'queueFifo', 'queueFifoTTL' ) as $q ) {
+                       do {
+                               $job = $this->$q->pop();
+                               if ( $job ) {
+                                       $this->$q->ack( $job );
+                               }
+                       } while ( $job );
+               }
+               $this->queueRand = null;
+               $this->queueRandTTL = null;
+               $this->queueFifo = null;
+               $this->queueFifoTTL = null;
+               $wgMemc = $this->old['wgMemc'];
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testProperties( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertEquals( wfWikiID(), $queue->getWiki(), "Proper wiki ID ($desc)" );
+               $this->assertEquals( 'null', $queue->getType(), "Proper job type ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testBasicOperations( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               $this->assertTrue( $queue->push( $this->newJob() ), "Push worked ($desc)" );
+               $this->assertTrue( $queue->batchPush( array( $this->newJob() ) ), "Push worked ($desc)" );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 2, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $job1 = $queue->pop();
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
+
+               $queue->flushCaches();
+               if ( $recycles ) {
+                       $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $job2 = $queue->pop();
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               if ( $recycles ) {
+                       $this->assertEquals( 2, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $queue->ack( $job1 );
+
+               $queue->flushCaches();
+               if ( $recycles ) {
+                       $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $queue->ack( $job2 );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testBasicDeduplication( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               $this->assertTrue( $queue->batchPush(
+                               array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ),
+                       "Push worked ($desc)" );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $this->assertTrue( $queue->batchPush(
+                               array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ),
+                       "Push worked ($desc)" );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $job1 = $queue->pop();
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               if ( $recycles ) {
+                       $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $queue->ack( $job1 );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testRootDeduplication( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               $id = wfRandomString( 32 );
+               $root1 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp
+               for ( $i = 0; $i < 5; ++$i ) {
+                       $this->assertTrue( $queue->push( $this->newJob( 0, $root1 ) ), "Push worked ($desc)" );
+               }
+               $queue->deduplicateRootJob( $this->newJob( 0, $root1 ) );
+               sleep( 1 ); // roo job timestamp will increase
+               $root2 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp
+               $this->assertNotEquals( $root1['rootJobTimestamp'], $root2['rootJobTimestamp'],
+                       "Root job signatures have different timestamps." );
+               for ( $i = 0; $i < 5; ++$i ) {
+                       $this->assertTrue( $queue->push( $this->newJob( 0, $root2 ) ), "Push worked ($desc)" );
+               }
+               $queue->deduplicateRootJob( $this->newJob( 0, $root2 ) );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 10, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $dupcount = 0;
+               $jobs = array();
+               do {
+                       $job = $queue->pop();
+                       if ( $job ) {
+                               $jobs[] = $job;
+                               $queue->ack( $job );
+                       }
+                       if ( $job instanceof DuplicateJob ) {
+                               ++$dupcount;
+                       }
+               } while ( $job );
+
+               $this->assertEquals( 10, count( $jobs ), "Correct number of jobs popped ($desc)" );
+               $this->assertEquals( 5, $dupcount, "Correct number of duplicate jobs popped ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_fifoQueueLists
+        */
+       function testJobOrder( $queue, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               for ( $i = 0; $i < 10; ++$i ) {
+                       $this->assertTrue( $queue->push( $this->newJob( $i ) ), "Push worked ($desc)" );
+               }
+
+               for ( $i = 0; $i < 10; ++$i ) {
+                       $job = $queue->pop();
+                       $this->assertTrue( $job instanceof Job, "Jobs popped from queue ($desc)" );
+                       $params = $job->getParams();
+                       $this->assertEquals( $i, $params['i'], "Job popped from queue is FIFO ($desc)" );
+                       $queue->ack( $job );
+               }
+
+               $this->assertFalse( $queue->pop(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+       }
+
+       function provider_queueLists() {
+               return array(
+                       array( 'queueRand', 'rand', false, 'Random queue without ack()' ),
+                       array( 'queueRandTTL', 'rand', true, 'Random queue with ack()' ),
+                       array( 'queueFifo', 'fifo', false, 'Ordered queue without ack()' ),
+                       array( 'queueFifoTTL', 'fifo', true, 'Ordered queue with ack()' )
+               );
+       }
+
+       function provider_fifoQueueLists() {
+               return array(
+                       array( 'queueFifo', false, 'Ordered queue without ack()' ),
+                       array( 'queueFifoTTL', true, 'Ordered queue with ack()' )
+               );
+       }
+
+       function newJob( $i = 0, $rootJob = array() ) {
+               return new NullJob( Title::newMainPage(),
+                       array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 0, 'i' => $i ) + $rootJob );
+       }
+
+       function newDedupedJob( $i = 0, $rootJob = array() ) {
+               return new NullJob( Title::newMainPage(),
+                       array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 1, 'i' => $i ) + $rootJob );
+       }
+}
index 8f2421a..56dc648 100644 (file)
@@ -14,7 +14,7 @@ class ServicesJsonTest extends MediaWikiTestCase {
                if ( !function_exists( 'json_encode' ) ) {
                        $this->markTestIncomplete( 'No PHP json support, unable to test' );
                        return;
-               } elseif( strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '"\ud840\udc00"' ) {
+               } elseif ( strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '"\ud840\udc00"' ) {
                        $this->markTestIncomplete( 'Have buggy PHP json support, unable to test' );
                        return;
                } else {
index 54f6607..26747b9 100644 (file)
@@ -17,10 +17,9 @@ class CSSJanusTest extends MediaWikiTestCase {
 
                        $transformedB = CSSJanus::transform( $cssB );
                        $this->assertEquals( $transformedB, $cssA, 'Test B-A transformation' );
-
-               // If no B version is provided, it means
-               // the output should equal the input.
                } else {
+                       // If no B version is provided, it means
+                       // the output should equal the input.
                        $transformedA = CSSJanus::transform( $cssA );
                        $this->assertEquals( $transformedA, $cssA, 'Nothing was flipped' );
                }
@@ -36,10 +35,11 @@ class CSSJanusTest extends MediaWikiTestCase {
                $flipped = CSSJanus::transform( $code, $swapLtrRtlInURL, $swapLeftRightInURL );
 
                $this->assertEquals( $expectedOutput, $flipped,
-                       'Test flipping, options: url-ltr-rtl=' . ($swapLtrRtlInURL ? 'true' : 'false')
-                               . ' url-left-right=' . ($swapLeftRightInURL ? 'true' : 'false')
+                       'Test flipping, options: url-ltr-rtl=' . ( $swapLtrRtlInURL ? 'true' : 'false' )
+                               . ' url-left-right=' . ( $swapLeftRightInURL ? 'true' : 'false' )
                );
        }
+
        /**
         * @dataProvider provideTransformBrokenCases
         * @group Broken
@@ -458,6 +458,16 @@ class CSSJanusTest extends MediaWikiTestCase {
                                ".foo\t{\tleft\t:\t0;}",
                                ".foo\t{\tright\t:\t0;}"
                        ),
+
+                       // Guard against partial keys
+                       array(
+                               '.foo { leftxx: 0; }',
+                               '.foo { leftxx: 0; }'
+                       ),
+                       array(
+                               '.foo { rightxx: 0; }',
+                               '.foo { rightxx: 0; }'
+                       ),
                );
        }
 
@@ -534,16 +544,6 @@ class CSSJanusTest extends MediaWikiTestCase {
         */
        function provideTransformBrokenCases() {
                return array(
-                       // Guard against partial keys
-                       array(
-                               '.foo { leftxx: 0; }',
-                               '.foo { leftxx: 0; }'
-                       ),
-                       array(
-                               '.foo { rightxx: 0; }',
-                               '.foo { rightxx: 0; }'
-                       ),
-
                        // Guard against selectors that look flippable
                        array(
                                # <foo-left-x attr="x">
index c0f8a96..37a9b34 100644 (file)
@@ -36,7 +36,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
         *
         * @return array
         */
-       public abstract function elementInstancesProvider();
+       abstract public function elementInstancesProvider();
 
        /**
         * Returns the name of the concrete class being tested.
@@ -45,7 +45,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
         *
         * @return string
         */
-       public abstract function getInstanceClass();
+       abstract public function getInstanceClass();
 
        /**
         * Provides instances of the concrete class being tested.
@@ -112,8 +112,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
        public function testUnset( GenericArrayObject $list ) {
                if ( $list->isEmpty() ) {
                        $this->assertTrue( true ); // We cannot test unset if there are no elements
-               }
-               else {
+               } else {
                        $offset = $list->getIterator()->key();
                        $count = $list->count();
                        $list->offsetUnset( $offset );
@@ -154,7 +153,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
 
                $this->assertEquals( $listSize, $list->count() );
 
-               $this->checkTypeChecks( function( GenericArrayObject $list, $element ) {
+               $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) {
                        $list->append( $element );
                } );
        }
@@ -173,11 +172,10 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
                foreach ( array( 42, 'foo', array(), new stdClass(), 4.2 ) as $element ) {
                        $validValid = $element instanceof $elementClass;
 
-                       try{
+                       try {
                                call_user_func( $function, $list, $element );
                                $valid = true;
-                       }
-                       catch ( InvalidArgumentException $exception ) {
+                       } catch ( InvalidArgumentException $exception ) {
                                $valid = false;
                        }
 
@@ -236,7 +234,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
 
                $this->assertEquals( count( $elements ), $list->count() );
 
-               $this->checkTypeChecks( function( GenericArrayObject $list, $element ) {
+               $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) {
                        $list->offsetSet( mt_rand(), $element );
                } );
        }
index c6270e9..984907b 100644 (file)
@@ -5,7 +5,7 @@
  */
 class IEUrlExtensionTest extends MediaWikiTestCase {
        function testSimple() {
-               $this->assertEquals( 
+               $this->assertEquals(
                        'y',
                        IEUrlExtension::findIE6Extension( 'x.y' ),
                        'Simple extension'
index f121b01..1f55079 100644 (file)
@@ -14,7 +14,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                         * At some point there was a bug that caused this comment to be ended at '* /',
                         * causing /M... to be left as the beginning of a regex.
                         */
-                       array( "/**\n * Foo\n * {\n * 'bar' : {\n * //Multiple rules with configurable operators\n * 'baz' : false\n * }\n */", ""),
+                       array( "/**\n * Foo\n * {\n * 'bar' : {\n * //Multiple rules with configurable operators\n * 'baz' : false\n * }\n */", "" ),
 
                        /**
                         * '  Foo \' bar \
@@ -80,7 +80,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                        array( "switch(x){case y?z:{}/  x/g:{}/  x/g;}", "switch(x){case y?z:{}/x/g:{}/  x/g;}" ),
                        array( "function x(){}/  x/g", "function x(){}/  x/g" ),
                        array( "+function x(){}/  x/g", "+function x(){}/x/g" ),
-                       
+
                        // Multiline quoted string
                        array( "var foo=\"\\\nblah\\\n\";", "var foo=\"\\\nblah\\\n\";" ),
 
@@ -96,16 +96,16 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                        // Division vs. regex nastiness
                        array( "alert( (10+10) / '/'.charCodeAt( 0 ) + '//' );", "alert((10+10)/'/'.charCodeAt(0)+'//');" ),
                        array( "if(1)/a /g.exec('Pa ss');", "if(1)/a /g.exec('Pa ss');" ),
-                       
+
                        // newline insertion after 1000 chars: break after the "++", not before
                        array( str_repeat( ';', 996 ) . "if(x++);", str_repeat( ';', 996 ) . "if(x++\n);" ),
 
                        // Unicode letter characters should pass through ok in identifiers (bug 31187)
-                       array( "var KaŝSkatolVal = {}", 'var KaŝSkatolVal={}'),
+                       array( "var KaŝSkatolVal = {}", 'var KaŝSkatolVal={}' ),
 
                        // Per spec unicode char escape values should work in identifiers,
                        // as long as it's a valid char. In future it might get normalized.
-                       array( "var Ka\\u015dSkatolVal = {}", 'var Ka\\u015dSkatolVal={}'),
+                       array( "var Ka\\u015dSkatolVal = {}", 'var Ka\\u015dSkatolVal={}' ),
 
                        // Some structures that might look invalid at first sight
                        array( "var a = 5.;", "var a=5.;" ),
@@ -137,7 +137,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                        array(
                                // This one gets interpreted all together by the prior code;
                                // no break at the 'E' happens.
-                               '1.23456789E55',                                
+                               '1.23456789E55',
                        ),
                        array(
                                // This one breaks under the bad code; splits between 'E' and '+'
@@ -165,6 +165,6 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
 
                $minified = JavaScriptMinifier::minify( $input );
 
-               $this->assertEquals( $expected, $minified, "Line breaks must not occur in middle of exponent");
+               $this->assertEquals( $expected, $minified, "Line breaks must not occur in middle of exponent" );
        }
 }
index 2fa2cc0..e8ccf43 100755 (executable)
@@ -29,7 +29,7 @@ class LogFormatterTest extends MediaWikiLangTestCase {
                        'wgLogActionsHandlers' => array( 'phpunit/test' => 'LogFormatter',
                                'phpunit/param' => 'LogFormatter' ),
                        'wgUser' => User::newFromName( 'Testuser' ),
-                       'wgExtensionMessagesFiles' => array( 'LogTests' => __DIR__.'/LogTests.i18n.php' ),
+                       'wgExtensionMessagesFiles' => array( 'LogTests' => __DIR__ . '/LogTests.i18n.php' ),
                ) );
 
                $wgLang->getLocalisationCache()->recache( $wgLang->getCode() );
index 8a0a421..78787ba 100755 (executable)
@@ -8,8 +8,8 @@
 $messages = array();
 
 $messages['en'] = array(
-       'log-name-phpunit'        => 'PHPUnit-log',
+       'log-name-phpunit' => 'PHPUnit-log',
        'log-description-phpunit' => 'Log for PHPUnit-tests',
-       'logentry-phpunit-test'   => '$1 {{GENDER:$2|tests}} with page $3',
-       'logentry-phpunit-param'  => '$4',
-);
\ No newline at end of file
+       'logentry-phpunit-test' => '$1 {{GENDER:$2|tests}} with page $3',
+       'logentry-phpunit-param' => '$4',
+);
index cfd75d8..b221b83 100644 (file)
@@ -34,10 +34,10 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase {
 
                $expected = array(
                        'x-default' => 'right(iptc)',
-                       'en'        => 'right translation',
-                       '_type'     => 'lang'
+                       'en' => 'right translation',
+                       '_type' => 'lang'
                );
-               
+
                $this->assertArrayHasKey( 'ImageDescription', $meta,
                        'Did not extract any ImageDescription info?!' );
 
@@ -122,25 +122,25 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase {
                }
                $handler = new BitmapMetadataHandler();
                $result = $handler->png( $this->filePath . 'xmp.png' );
-               $expected = array (
+               $expected = array(
                        'frameCount' => 0,
                        'loopCount' => 1,
                        'duration' => 0,
                        'bitDepth' => 1,
                        'colorType' => 'index-coloured',
-                       'metadata' => array (
+                       'metadata' => array(
                                'SerialNumber' => '123456789',
                                '_MW_PNG_VERSION' => 1,
                        ),
                );
-               $this->assertEquals( $expected, $result ); 
+               $this->assertEquals( $expected, $result );
        }
 
        public function testPNGNative() {
                $handler = new BitmapMetadataHandler();
                $result = $handler->png( $this->filePath . 'Png-native-test.png' );
                $expected = 'http://example.com/url';
-               $this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] ); 
+               $this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] );
        }
 
        public function testTiffByteOrder() {
index eb1a536..3de60b7 100644 (file)
@@ -21,14 +21,14 @@ class BitmapScalingTest extends MediaWikiTestCase {
                $this->assertTrue( $valid );
                $this->assertEquals( $expectedParams, $params, $msg );
        }
-       
+
        function provideNormaliseParams() {
                return array(
-                       /* Regular resize operations */ 
+                       /* Regular resize operations */
                        array(
                                array( 1024, 768 ),
-                               array( 
-                                       'width' => 512, 'height' => 384, 
+                               array(
+                                       'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
                                        'page' => 1,
                                ),
@@ -37,53 +37,53 @@ class BitmapScalingTest extends MediaWikiTestCase {
                        ),
                        array(
                                array( 1024, 768 ),
-                               array( 
-                                       'width' => 512, 'height' => 384, 
+                               array(
+                                       'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 512, 'height' => 768 ),
                                'Resizing with height set too high',
                        ),
                        array(
                                array( 1024, 768 ),
-                               array( 
-                                       'width' => 512, 'height' => 384, 
+                               array(
+                                       'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 1024, 'height' => 384 ),
                                'Resizing with height set',
                        ),
-                       
+
                        /* Very tall images */
                        array(
                                array( 1000, 100 ),
-                               array( 
+                               array(
                                        'width' => 5, 'height' => 1,
                                        'physicalWidth' => 5, 'physicalHeight' => 1,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 5 ),
                                'Very wide image',
                        ),
-                       
+
                        array(
                                array( 100, 1000 ),
-                               array( 
+                               array(
                                        'width' => 1, 'height' => 10,
                                        'physicalWidth' => 1, 'physicalHeight' => 10,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 1 ),
                                'Very high image',
                        ),
                        array(
                                array( 100, 1000 ),
-                               array( 
+                               array(
                                        'width' => 1, 'height' => 5,
                                        'physicalWidth' => 1, 'physicalHeight' => 10,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 10, 'height' => 5 ),
                                'Very high image with height set',
@@ -91,10 +91,10 @@ class BitmapScalingTest extends MediaWikiTestCase {
                        /* Max image area */
                        array(
                                array( 4000, 4000 ),
-                               array( 
+                               array(
                                        'width' => 5000, 'height' => 5000,
                                        'physicalWidth' => 4000, 'physicalHeight' => 4000,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 5000 ),
                                'Bigger than max image size but doesn\'t need scaling',
@@ -106,7 +106,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                $file = new FakeDimensionFile( array( 4000, 4000 ) );
                $handler = new BitmapHandler;
                $params = array( 'width' => '3700' ); // Still bigger than max size.
-               $this->assertEquals( 'TransformParameterError', 
+               $this->assertEquals( 'TransformParameterError',
                        get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
        }
 
@@ -115,10 +115,10 @@ class BitmapScalingTest extends MediaWikiTestCase {
                $file->mustRender = true;
                $handler = new BitmapHandler;
                $params = array( 'width' => '5000' ); // Still bigger than max size.
-               $this->assertEquals( 'TransformParameterError', 
+               $this->assertEquals( 'TransformParameterError',
                        get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
        }
-       
+
        function testImageArea() {
                $file = new FakeDimensionFile( array( 7, 9 ) );
                $handler = new BitmapHandler;
@@ -130,20 +130,24 @@ class FakeDimensionFile extends File {
        public $mustRender = false;
 
        public function __construct( $dimensions ) {
-               parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), 
+               parent::__construct( Title::makeTitle( NS_FILE, 'Test' ),
                        new NullRepo( null ) );
-               
+
                $this->dimensions = $dimensions;
        }
+
        public function getWidth( $page = 1 ) {
                return $this->dimensions[0];
        }
+
        public function getHeight( $page = 1 ) {
                return $this->dimensions[1];
        }
+
        public function mustRender() {
                return $this->mustRender;
        }
+
        public function getPath() {
                return '';
        }
index dd22321..1109c47 100644 (file)
@@ -50,9 +50,9 @@ class ExifBitmapTest extends MediaWikiTestCase {
 
        function testConvertMetadataLatest() {
                $metadata = array(
-                               'foo' => array( 'First', 'Second', '_type' => 'ol' ),
-                               'MEDIAWIKI_EXIF_VERSION' => 2
-                        );
+                       'foo' => array( 'First', 'Second', '_type' => 'ol' ),
+                       'MEDIAWIKI_EXIF_VERSION' => 2
+               );
                $res = $this->handler->convertMetadataVersion( $metadata, 2 );
                $this->assertEquals( $metadata, $res );
        }
@@ -78,7 +78,7 @@ class ExifBitmapTest extends MediaWikiTestCase {
 
        function testConvertMetadataSoftware() {
                $metadata = array(
-                       'Software' => array( array('GIMP', '1.1' ) ),
+                       'Software' => array( array( 'GIMP', '1.1' ) ),
                        'MEDIAWIKI_EXIF_VERSION' => 2,
                );
                $expected = array(
index d52fecc..db29d17 100644 (file)
@@ -14,11 +14,11 @@ class ExifRotationTest extends MediaWikiTestCase {
                $tmpDir = $this->getNewTempDirectory();
 
                $this->repo = new FSRepo( array(
-                       'name'            => 'temp',
-                       'url'             => 'http://localhost/thumbtest',
-                       'backend'         => new FSFileBackend( array(
-                               'name'           => 'localtesting',
-                               'lockManager'    => 'nullLockManager',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'localtesting',
+                               'lockManager' => 'nullLockManager',
                                'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath )
                        ) )
                ) );
@@ -63,8 +63,8 @@ class ExifRotationTest extends MediaWikiTestCase {
                if ( !BitmapHandler::canRotate() ) {
                        $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
                }
-               foreach( $thumbs as $size => $out ) {
-                       if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
+               foreach ( $thumbs as $size => $out ) {
+                       if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) {
                                $params = array(
                                        'width' => $matches[1],
                                );
@@ -74,7 +74,7 @@ class ExifRotationTest extends MediaWikiTestCase {
                                        'height' => $matches[2]
                                );
                        } else {
-                               throw new MWException('bogus test data format ' . $size);
+                               throw new MWException( 'bogus test data format ' . $size );
                        }
 
                        $file = $this->dataFile( $name, $type );
@@ -84,13 +84,13 @@ class ExifRotationTest extends MediaWikiTestCase {
                        $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
 
                        $gis = getimagesize( $thumb->getLocalCopyPath() );
-                       if ($out[0] > $info['width']) {
+                       if ( $out[0] > $info['width'] ) {
                                // Physical image won't be scaled bigger than the original.
-                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" );
                        } else {
-                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" );
                        }
                }
        }
@@ -157,8 +157,8 @@ class ExifRotationTest extends MediaWikiTestCase {
                global $wgEnableAutoRotation;
                $wgEnableAutoRotation = false;
 
-               foreach( $thumbs as $size => $out ) {
-                       if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
+               foreach ( $thumbs as $size => $out ) {
+                       if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) {
                                $params = array(
                                        'width' => $matches[1],
                                );
@@ -168,7 +168,7 @@ class ExifRotationTest extends MediaWikiTestCase {
                                        'height' => $matches[2]
                                );
                        } else {
-                               throw new MWException('bogus test data format ' . $size);
+                               throw new MWException( 'bogus test data format ' . $size );
                        }
 
                        $file = $this->dataFile( $name, $type );
@@ -178,13 +178,13 @@ class ExifRotationTest extends MediaWikiTestCase {
                        $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
 
                        $gis = getimagesize( $thumb->getLocalCopyPath() );
-                       if ($out[0] > $info['width']) {
+                       if ( $out[0] > $info['width'] ) {
                                // Physical image won't be scaled bigger than the original.
-                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" );
                        } else {
-                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" );
                        }
                }
                $wgEnableAutoRotation = true;
@@ -222,41 +222,40 @@ class ExifRotationTest extends MediaWikiTestCase {
                        )
                );
        }
-       
-       
+
+
        const TEST_WIDTH = 100;
        const TEST_HEIGHT = 200;
-       
+
        /**
         * @dataProvider provideBitmapExtractPreRotationDimensions
         */
        function testBitmapExtractPreRotationDimensions( $rotation, $expected ) {
                $result = $this->handler->extractPreRotationDimensions( array(
-                               'physicalWidth' => self::TEST_WIDTH, 
-                               'physicalHeight' => self::TEST_HEIGHT,
-                       ), $rotation );
+                       'physicalWidth' => self::TEST_WIDTH,
+                       'physicalHeight' => self::TEST_HEIGHT,
+               ), $rotation );
                $this->assertEquals( $expected, $result );
        }
-       
+
        function provideBitmapExtractPreRotationDimensions() {
                return array(
                        array(
                                0,
-                               array( self::TEST_WIDTH, self::TEST_HEIGHT ) 
+                               array( self::TEST_WIDTH, self::TEST_HEIGHT )
                        ),
                        array(
                                90,
-                               array( self::TEST_HEIGHT, self::TEST_WIDTH ) 
+                               array( self::TEST_HEIGHT, self::TEST_WIDTH )
                        ),
                        array(
                                180,
-                               array( self::TEST_WIDTH, self::TEST_HEIGHT ) 
+                               array( self::TEST_WIDTH, self::TEST_HEIGHT )
                        ),
                        array(
                                270,
-                               array( self::TEST_HEIGHT, self::TEST_WIDTH ) 
+                               array( self::TEST_HEIGHT, self::TEST_WIDTH )
                        ),
                );
        }
 }
-
index 7cc56f6..e7e95f7 100644 (file)
@@ -15,7 +15,7 @@ class ExifTest extends MediaWikiTestCase {
 
        public function testGPSExtraction() {
                $filename = $this->mediaPath . 'exif-gps.jpg';
-               $seg = JpegMetadataExtractor::segmentSplitter( $filename ); 
+               $seg = JpegMetadataExtractor::segmentSplitter( $filename );
                $exif = new Exif( $filename, $seg['byteOrder'] );
                $data = $exif->getFilteredData();
                $expected = array(
@@ -30,7 +30,7 @@ class ExifTest extends MediaWikiTestCase {
 
        public function testUnicodeUserComment() {
                $filename = $this->mediaPath . 'exif-user-comment.jpg';
-               $seg = JpegMetadataExtractor::segmentSplitter( $filename ); 
+               $seg = JpegMetadataExtractor::segmentSplitter( $filename );
                $exif = new Exif( $filename, $seg['byteOrder'] );
                $data = $exif->getFilteredData();
 
index 4dadde5..f26d27e 100644 (file)
@@ -7,15 +7,15 @@ class FormatMetadataTest extends MediaWikiTestCase {
                if ( !wfDl( 'exif' ) ) {
                        $this->markTestSkipped( "This test needs the exif extension." );
                }
-               $filePath = __DIR__ .  '/../../data/media';
+               $filePath = __DIR__ . '/../../data/media';
                $this->backend = new FSFileBackend( array(
-                       'name'           => 'localtesting',
-                       'lockManager'    => 'nullLockManager',
+                       'name' => 'localtesting',
+                       'lockManager' => 'nullLockManager',
                        'containerPaths' => array( 'data' => $filePath )
                ) );
                $this->repo = new FSRepo( array(
-                       'name'    => 'temp',
-                       'url'     => 'http://localhost/thumbtest',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
                        'backend' => $this->backend
                ) );
 
@@ -24,11 +24,11 @@ class FormatMetadataTest extends MediaWikiTestCase {
 
        public function testInvalidDate() {
                $file = $this->dataFile( 'broken_exif_date.jpg', 'image/jpeg' );
-               
+
                // Throws an error if bug hit
                $meta = $file->formatMetadata();
                $this->assertNotEquals( false, $meta, 'Valid metadata extracted' );
-               
+
                // Find date exif entry
                $this->assertArrayHasKey( 'visible', $meta );
                $dateIndex = null;
@@ -38,7 +38,7 @@ class FormatMetadataTest extends MediaWikiTestCase {
                        }
                }
                $this->assertNotNull( $dateIndex, 'Date entry exists in metadata' );
-               $this->assertEquals( '0000:01:00 00:02:27', 
+               $this->assertEquals( '0000:01:00 00:02:27',
                        $meta['visible'][$dateIndex]['value'],
                        'File with invalid date metadata (bug 29471)' );
        }
index 3a750aa..86cf346 100644 (file)
@@ -6,6 +6,7 @@ class GIFMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->mediaPath = __DIR__ . '/../../data/media/';
        }
+
        /**
         * Put in a file, and see if the metadata coming out is as expected.
         * @param $filename String
@@ -16,6 +17,7 @@ class GIFMetadataExtractorTest extends MediaWikiTestCase {
                $actual = GIFMetadataExtractor::getMetadata( $this->mediaPath . $filename );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideGetMetadata() {
 
                $xmpNugget = <<<EOF
@@ -68,29 +70,35 @@ EOF;
                $xmpNugget = str_replace( "\r", '', $xmpNugget ); // Windows compat
 
                return array(
-                       array( 'nonanimated.gif', array(
-                               'comment' => array( 'GIF test file ⁕ Created with GIMP' ),
-                               'duration' => 0.1,
-                               'frameCount' => 1,
-                               'looped' => false,
-                               'xmp' => '',
+                       array(
+                               'nonanimated.gif',
+                               array(
+                                       'comment' => array( 'GIF test file ⁕ Created with GIMP' ),
+                                       'duration' => 0.1,
+                                       'frameCount' => 1,
+                                       'looped' => false,
+                                       'xmp' => '',
                                )
                        ),
-                       array( 'animated.gif', array(
-                               'comment' => array( 'GIF test file . Created with GIMP' ),
-                               'duration' => 2.4,
-                               'frameCount' => 4,
-                               'looped' => true,
-                               'xmp' => '',
+                       array(
+                               'animated.gif',
+                               array(
+                                       'comment' => array( 'GIF test file . Created with GIMP' ),
+                                       'duration' => 2.4,
+                                       'frameCount' => 4,
+                                       'looped' => true,
+                                       'xmp' => '',
                                )
                        ),
 
-                       array( 'animated-xmp.gif', array(
-                               'xmp' => $xmpNugget,
-                               'duration' => 2.4,
-                               'frameCount' => 4,
-                               'looped' => true,
-                               'comment' => array( 'GIƒ·test·file' ),
+                       array(
+                               'animated-xmp.gif',
+                               array(
+                                       'xmp' => $xmpNugget,
+                                       'duration' => 2.4,
+                                       'frameCount' => 4,
+                                       'looped' => true,
+                                       'comment' => array( 'GIƒ·test·file' ),
                                )
                        ),
                );
index 9ffc764..7ea6b7e 100644 (file)
@@ -4,15 +4,15 @@ class GIFHandlerTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->filePath = __DIR__ .  '/../../data/media';
+               $this->filePath = __DIR__ . '/../../data/media';
                $this->backend = new FSFileBackend( array(
-                       'name'           => 'localtesting',
-                       'lockManager'    => 'nullLockManager',
+                       'name' => 'localtesting',
+                       'lockManager' => 'nullLockManager',
                        'containerPaths' => array( 'data' => $this->filePath )
                ) );
                $this->repo = new FSRepo( array(
-                       'name'    => 'temp',
-                       'url'     => 'http://localhost/thumbtest',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
                        'backend' => $this->backend
                ) );
                $this->handler = new GIFHandler();
@@ -33,6 +33,7 @@ class GIFHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isAnimatedImage( $file );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsAnimated() {
                return array(
                        array( 'animated.gif', true ),
@@ -50,6 +51,7 @@ class GIFHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideGetImageArea() {
                return array(
                        array( 'animated.gif', 5400 ),
@@ -66,6 +68,7 @@ class GIFHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isMetadataValid( null, $metadata );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsMetadataValid() {
                return array(
                        array( GIFHandler::BROKEN_FILE, GIFHandler::METADATA_GOOD ),
index ec6deeb..c9648a7 100644 (file)
@@ -14,6 +14,7 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( '¼' ), $res['Keywords'] );
        }
+
        /* This one contains a sequence that's valid iso 8859-1 but not valid utf8 */
        /* \xC3 = Ã, \xB8 = ¸  */
        public function testIPTCParseNoCharset88591b() {
@@ -21,6 +22,7 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( 'ÃÃø' ), $res['Keywords'] );
        }
+
        /* Same as testIPTCParseNoCharset88591b, but forcing the charset to utf-8.
         * What should happen is the first "\xC3\xC3" should be dropped as invalid,
         * leaving \xC3\xB8, which is ø
@@ -31,11 +33,13 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( 'ø' ), $res['Keywords'] );
        }
+
        public function testIPTCParseNoCharsetUTF8() {
                $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x07\x1c\x02\x19\x00\x02¼";
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( '¼' ), $res['Keywords'] );
        }
+
        // Testing something that has 2 values for keyword
        public function testIPTCParseMulti() {
                $iptcData = /* identifier */ "Photoshop 3.0\08BIM\4\4"
@@ -45,6 +49,7 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( '¼', '¼½' ), $res['Keywords'] );
        }
+
        public function testIPTCParseUTF8() {
                // This has the magic "\x1c\x01\x5A\x00\x03\x1B\x25\x47" which marks content as UTF8.
                $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x0F\x1c\x02\x19\x00\x02¼\x1c\x01\x5A\x00\x03\x1B\x25\x47";
index 6e1c0af..cae7137 100644 (file)
@@ -26,6 +26,7 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . $file );
                $this->assertEquals( array( 'UTF-8 JPEG Comment — ¼' ), $res['COM'] );
        }
+
        public static function provideUtf8Comment() {
                return array(
                        array( 'jpeg-comment-utf.jpg' ),
@@ -33,11 +34,13 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                        array( 'jpeg-padding-odd.jpg' ),
                );
        }
+
        /** The file is iso-8859-1, but it should get auto converted */
        public function testIso88591Comment() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-iso8859-1.jpg' );
                $this->assertEquals( array( 'ISO-8859-1 JPEG Comment - ¼' ), $res['COM'] );
        }
+
        /** Comment values that are non-textual (random binary junk) should not be shown.
         * The example test file has a comment with a 0x5 byte in it which is a control character
         * and considered binary junk for our purposes.
@@ -46,6 +49,7 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-binary.jpg' );
                $this->assertEmpty( $res['COM'] );
        }
+
        /* Very rarely a file can have multiple comments.
         *   Order of comments is based on order inside the file.
         */
@@ -53,16 +57,19 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-multiple.jpg' );
                $this->assertEquals( array( 'foo', 'bar' ), $res['COM'] );
        }
+
        public function testXMPExtraction() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' );
                $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' );
                $this->assertEquals( $expected, $res['XMP'] );
        }
+
        public function testPSIRExtraction() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' );
                $expected = '50686f746f73686f7020332e30003842494d04040000000000181c02190004746573741c02190003666f6f1c020000020004';
                $this->assertEquals( $expected, bin2hex( $res['PSIR'][0] ) );
        }
+
        public function testXMPExtractionAltAppId() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-alt.jpg' );
                $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' );
@@ -76,18 +83,21 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->assertEquals( 'iptc-no-hash', $res );
        }
+
        public function testIPTCHashComparisionBadHash() {
                $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-bad-hash.jpg' );
                $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] );
 
                $this->assertEquals( 'iptc-bad-hash', $res );
        }
+
        public function testIPTCHashComparisionGoodHash() {
                $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-good-hash.jpg' );
                $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] );
 
                $this->assertEquals( 'iptc-good-hash', $res );
        }
+
        public function testExifByteOrder() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'exif-user-comment.jpg' );
                $expected = 'BE';
index 99df4f8..4e4c649 100644 (file)
@@ -46,5 +46,3 @@ class MediaHandlerTest extends MediaWikiTestCase {
                }
        }
 }
-
-
index e027668..1e91201 100644 (file)
@@ -5,10 +5,13 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
                parent::setUp();
                $this->filePath = __DIR__ . '/../../data/media/';
        }
+
        /**
-        * Tests zTXt tag (compressed textual metadata) 
+        * Tests zTXt tag (compressed textual metadata)
         */
        function testPngNativetZtxt() {
+               $this->checkPHPExtension( 'zlib' );
+
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'Png-native-test.png' );
                $expected = "foo bar baz foo foo foo foof foo foo foo foo";
@@ -62,7 +65,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
         * Test extraction of pHYs tags, which can tell what the
         * actual resolution of the image is (aka in dots per meter).
         */
-/*
+       /*
        function testPngPhysTag () {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'Png-native-test.png' );
@@ -74,7 +77,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
                $this->assertEquals( '2835/100', $meta['YResolution'] );
                $this->assertEquals( 3, $meta['ResolutionUnit'] ); // 3 = cm
        }
-*/
+       */
 
        /**
         * Given a normal static PNG, check the animation metadata returned.
@@ -108,6 +111,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->assertEquals( 8, $meta['bitDepth'] );
        }
+
        function testPngBitDepth1() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        '1bit-png.png' );
@@ -121,21 +125,25 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->assertEquals( 'index-coloured', $meta['colorType'] );
        }
+
        function testPngRgbColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'rgb-png.png' );
                $this->assertEquals( 'truecolour-alpha', $meta['colorType'] );
        }
+
        function testPngRgbNoAlphaColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'rgb-na-png.png' );
                $this->assertEquals( 'truecolour', $meta['colorType'] );
        }
+
        function testPngGreyscaleColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'greyscale-png.png' );
                $this->assertEquals( 'greyscale-alpha', $meta['colorType'] );
        }
+
        function testPngGreyscaleNoAlphaColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'greyscale-na-png.png' );
index 2075758..855780d 100644 (file)
@@ -4,15 +4,15 @@ class PNGHandlerTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->filePath = __DIR__ .  '/../../data/media';
+               $this->filePath = __DIR__ . '/../../data/media';
                $this->backend = new FSFileBackend( array(
-                       'name'           => 'localtesting',
-                       'lockManager'    => 'nullLockManager',
+                       'name' => 'localtesting',
+                       'lockManager' => 'nullLockManager',
                        'containerPaths' => array( 'data' => $this->filePath )
                ) );
                $this->repo = new FSRepo( array(
-                       'name'    => 'temp',
-                       'url'     => 'http://localhost/thumbtest',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
                        'backend' => $this->backend
                ) );
                $this->handler = new PNGHandler();
@@ -22,6 +22,7 @@ class PNGHandlerTest extends MediaWikiTestCase {
                $res = $this->handler->getMetadata( null, $this->filePath . '/README' );
                $this->assertEquals( PNGHandler::BROKEN_FILE, $res );
        }
+
        /**
         * @param $filename String basename of the file to check
         * @param $expected boolean Expected result.
@@ -32,6 +33,7 @@ class PNGHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isAnimatedImage( $file );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsAnimated() {
                return array(
                        array( 'Animated_PNG_example_bouncing_beach_ball.png', true ),
@@ -45,10 +47,11 @@ class PNGHandlerTest extends MediaWikiTestCase {
         * @dataProvider provideGetImageArea
         */
        public function testGetImageArea( $filename, $expected ) {
-               $file = $this->dataFile($filename, 'image/png' );
+               $file = $this->dataFile( $filename, 'image/png' );
                $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideGetImageArea() {
                return array(
                        array( '1bit-png.png', 2500 ),
@@ -67,6 +70,7 @@ class PNGHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isMetadataValid( null, $metadata );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsMetadataValid() {
                return array(
                        array( PNGHandler::BROKEN_FILE, PNGHandler::METADATA_GOOD ),
@@ -88,10 +92,11 @@ class PNGHandlerTest extends MediaWikiTestCase {
 //             $this->assertEquals( unserialize( $expected ), unserialize( $actual ) );
                $this->assertEquals( ( $expected ), ( $actual ) );
        }
+
        public static function provideGetMetadata() {
                return array(
                        array( 'rgb-na-png.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}' ),
-                       array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ), 
+                       array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ),
                );
        }
 
index d9a59ca..97a0000 100644 (file)
@@ -13,13 +13,13 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase {
        function testGetMetadata( $infile, $expected ) {
                $this->assertMetadata( $infile, $expected );
        }
-       
+
        /**
         * @dataProvider provideSvgFilesWithXMLMetadata
         */
        function testGetXMLMetadata( $infile, $expected ) {
                $r = new XMLReader();
-               if( !method_exists( $r, 'readInnerXML' ) ) {
+               if ( !method_exists( $r, 'readInnerXML' ) ) {
                        $this->markTestSkipped( 'XMLReader::readInnerXML() does not exist (libxml >2.6.20 needed).' );
                        return;
                }
@@ -84,8 +84,7 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase {
 
        public static function provideSvgFilesWithXMLMetadata() {
                $base = __DIR__ . '/../../data/media';
-               $metadata = 
-    '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+               $metadata = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
       <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about="">
         <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format>
         <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
@@ -106,4 +105,3 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase {
                );
        }
 }
-
index 452016f..86c722b 100644 (file)
@@ -27,7 +27,7 @@ class XMPTest extends MediaWikiTestCase {
        }
 
        public static function provideXMPParse() {
-               $xmpPath = __DIR__ . '/../../data/xmp/' ;
+               $xmpPath = __DIR__ . '/../../data/xmp/';
                $data = array();
 
                // $xmpFiles format: array of arrays with first arg file base name,
@@ -54,8 +54,9 @@ class XMPTest extends MediaWikiTestCase {
                        array( 'utf32LE', 'UTF-32LE encoding' ),
                        array( 'xmpExt', 'Extended XMP missing second part' ),
                        array( 'gps', 'Handling of exif GPS parameters in XMP' ),
-                );
-               foreach( $xmpFiles as $file ) {
+               );
+
+               foreach ( $xmpFiles as $file ) {
                        $xmp = file_get_contents( $xmpPath . $file[0] . '.xmp' );
                        // I'm not sure if this is the best way to handle getting the
                        // result array, but it seems kind of big to put directly in the test
@@ -88,8 +89,8 @@ class XMPTest extends MediaWikiTestCase {
                $reader->parseExtended( $extendedPacket );
                $actual = $reader->getResults();
 
-               $expected = array( 'xmp-exif' =>
-                       array(
+               $expected = array(
+                       'xmp-exif' => array(
                                'DigitalZoomRatio' => '0/10',
                                'Flash' => 9,
                                'FNumber' => '2/10',
@@ -118,8 +119,8 @@ class XMPTest extends MediaWikiTestCase {
                $reader->parseExtended( $extendedPacket );
                $actual = $reader->getResults();
 
-               $expected = array( 'xmp-exif' =>
-                       array(
+               $expected = array(
+                       'xmp-exif' => array(
                                'DigitalZoomRatio' => '0/10',
                                'Flash' => 9,
                        )
@@ -127,6 +128,7 @@ class XMPTest extends MediaWikiTestCase {
 
                $this->assertEquals( $expected, $actual );
        }
+
        /**
         * Have a high offset to simulate a missing packet,
         * which should cause it to ignore the ExtendedXMP packet.
@@ -146,8 +148,8 @@ class XMPTest extends MediaWikiTestCase {
                $reader->parseExtended( $extendedPacket );
                $actual = $reader->getResults();
 
-               $expected = array( 'xmp-exif' =>
-                       array(
+               $expected = array(
+                       'xmp-exif' => array(
                                'DigitalZoomRatio' => '0/10',
                                'Flash' => 9,
                        )
index d5ad18d..86fd95c 100644 (file)
@@ -65,19 +65,24 @@ class CleanUpTest extends MediaWikiTestCase {
         */
        function XtestAllChars() {
                $rep = UTF8_REPLACEMENT;
-               for( $i = 0x0; $i < UNICODE_MAX; $i++ ) {
+               for ( $i = 0x0; $i < UNICODE_MAX; $i++ ) {
                        $char = codepointToUtf8( $i );
                        $clean = UtfNormal::cleanUp( $char );
                        $x = sprintf( "%04X", $i );
-                       if( $i % 0x1000 == 0 ) echo "U+$x\n";
-                       if( $i == 0x0009 ||
-                           $i == 0x000a ||
-                           $i == 0x000d ||
-                           ($i > 0x001f && $i < UNICODE_SURROGATE_FIRST) ||
-                           ($i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) ||
-                           ($i > 0xffff && $i <= UNICODE_MAX ) ) {
-                               if( isset( UtfNormal::$utfCanonicalComp[$char] ) || isset( UtfNormal::$utfCanonicalDecomp[$char] ) ) {
-                                   $comp = UtfNormal::NFC( $char );
+
+                       if ( $i % 0x1000 == 0 ) {
+                               echo "U+$x\n";
+                       }
+
+                       if ( $i == 0x0009 ||
+                               $i == 0x000a ||
+                               $i == 0x000d ||
+                               ( $i > 0x001f && $i < UNICODE_SURROGATE_FIRST ) ||
+                               ( $i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) ||
+                               ( $i > 0xffff && $i <= UNICODE_MAX )
+                       ) {
+                               if ( isset( UtfNormal::$utfCanonicalComp[$char] ) || isset( UtfNormal::$utfCanonicalDecomp[$char] ) ) {
+                                       $comp = UtfNormal::NFC( $char );
                                        $this->assertEquals(
                                                bin2hex( $comp ),
                                                bin2hex( $clean ),
@@ -104,26 +109,32 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function doTestBytes( $head, $tail ) {
-               for( $i = 0x0; $i < 256; $i++ ) {
+               for ( $i = 0x0; $i < 256; $i++ ) {
                        $char = $head . chr( $i ) . $tail;
                        $clean = UtfNormal::cleanUp( $char );
                        $x = sprintf( "%02X", $i );
-                       if( $i == 0x0009 ||
-                           $i == 0x000a ||
-                           $i == 0x000d ||
-                           ($i > 0x001f && $i < 0x80) ) {
+
+                       if ( $i == 0x0009 ||
+                               $i == 0x000a ||
+                               $i == 0x000d ||
+                               ( $i > 0x001f && $i < 0x80 )
+                       ) {
                                $this->assertEquals(
                                        bin2hex( $char ),
                                        bin2hex( $clean ),
                                        "ASCII byte $x should be intact" );
-                               if( $char != $clean ) return;
+                               if ( $char != $clean ) {
+                                       return;
+                               }
                        } else {
                                $norm = $head . UTF8_REPLACEMENT . $tail;
                                $this->assertEquals(
                                        bin2hex( $norm ),
                                        bin2hex( $clean ),
                                        "Forbidden byte $x should be rejected" );
-                               if( $norm != $clean ) return;
+                               if ( $norm != $clean ) {
+                                       return;
+                               }
                        }
                }
        }
@@ -140,35 +151,42 @@ class CleanUpTest extends MediaWikiTestCase {
         * @todo document
         */
        function doTestDoubleBytes( $head, $tail ) {
-               for( $first = 0xc0; $first < 0x100; $first+=2 ) {
-                       for( $second = 0x80; $second < 0x100; $second+=2 ) {
+               for ( $first = 0xc0; $first < 0x100; $first += 2 ) {
+                       for ( $second = 0x80; $second < 0x100; $second += 2 ) {
                                $char = $head . chr( $first ) . chr( $second ) . $tail;
                                $clean = UtfNormal::cleanUp( $char );
                                $x = sprintf( "%02X,%02X", $first, $second );
-                               if( $first > 0xc1 &&
-                                   $first < 0xe0 &&
-                                   $second < 0xc0 ) {
-                                   $norm = UtfNormal::NFC( $char );
+                               if ( $first > 0xc1 &&
+                                       $first < 0xe0 &&
+                                       $second < 0xc0
+                               ) {
+                                       $norm = UtfNormal::NFC( $char );
                                        $this->assertEquals(
                                                bin2hex( $norm ),
                                                bin2hex( $clean ),
                                                "Pair $x should be intact" );
-                                   if( $norm != $clean ) return;
-                               } elseif( $first > 0xfd || $second > 0xbf ) {
+                                       if ( $norm != $clean ) {
+                                               return;
+                                       }
+                               } elseif ( $first > 0xfd || $second > 0xbf ) {
                                        # fe and ff are not legal head bytes -- expect two replacement chars
                                        $norm = $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail;
                                        $this->assertEquals(
                                                bin2hex( $norm ),
                                                bin2hex( $clean ),
                                                "Forbidden pair $x should be rejected" );
-                                       if( $norm != $clean ) return;
+                                       if ( $norm != $clean ) {
+                                               return;
+                                       }
                                } else {
                                        $norm = $head . UTF8_REPLACEMENT . $tail;
                                        $this->assertEquals(
                                                bin2hex( $norm ),
                                                bin2hex( $clean ),
                                                "Forbidden pair $x should be rejected" );
-                                       if( $norm != $clean ) return;
+                                       if ( $norm != $clean ) {
+                                               return;
+                                       }
                                }
                        }
                }
@@ -184,24 +202,27 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function doTestTripleBytes( $head, $tail ) {
-               for( $first = 0xc0; $first < 0x100; $first+=2 ) {
-                       for( $second = 0x80; $second < 0x100; $second+=2 ) {
+               for ( $first = 0xc0; $first < 0x100; $first += 2 ) {
+                       for ( $second = 0x80; $second < 0x100; $second += 2 ) {
                                #for( $third = 0x80; $third < 0x100; $third++ ) {
-                               for( $third = 0x80; $third < 0x81; $third++ ) {
+                               for ( $third = 0x80; $third < 0x81; $third++ ) {
                                        $char = $head . chr( $first ) . chr( $second ) . chr( $third ) . $tail;
                                        $clean = UtfNormal::cleanUp( $char );
                                        $x = sprintf( "%02X,%02X,%02X", $first, $second, $third );
-                                       if( $first >= 0xe0 &&
+
+                                       if ( $first >= 0xe0 &&
                                                $first < 0xf0 &&
                                                $second < 0xc0 &&
-                                               $third < 0xc0 ) {
-                                               if( $first == 0xe0 && $second < 0xa0 ) {
+                                               $third < 0xc0
+                                       ) {
+                                               if ( $first == 0xe0 && $second < 0xa0 ) {
                                                        $this->assertEquals(
                                                                bin2hex( $head . UTF8_REPLACEMENT . $tail ),
                                                                bin2hex( $clean ),
                                                                "Overlong triplet $x should be rejected" );
-                                               } elseif( $first == 0xed &&
-                                                       ( chr( $first ) . chr( $second ) . chr( $third ))  >= UTF8_SURROGATE_FIRST ) {
+                                               } elseif ( $first == 0xed &&
+                                                       ( chr( $first ) . chr( $second ) . chr( $third ) ) >= UTF8_SURROGATE_FIRST
+                                               ) {
                                                        $this->assertEquals(
                                                                bin2hex( $head . UTF8_REPLACEMENT . $tail ),
                                                                bin2hex( $clean ),
@@ -212,27 +233,28 @@ class CleanUpTest extends MediaWikiTestCase {
                                                                bin2hex( $clean ),
                                                                "Triplet $x should be intact" );
                                                }
-                                       } elseif( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) {
+                                       } elseif ( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) {
                                                $this->assertEquals(
                                                        bin2hex( UtfNormal::NFC( $head . chr( $first ) . chr( $second ) ) . UTF8_REPLACEMENT . $tail ),
                                                        bin2hex( $clean ),
                                                        "Valid 2-byte $x + broken tail" );
-                                       } elseif( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) {
+                                       } elseif ( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) {
                                                $this->assertEquals(
                                                        bin2hex( $head . UTF8_REPLACEMENT . UtfNormal::NFC( chr( $second ) . chr( $third ) . $tail ) ),
                                                        bin2hex( $clean ),
                                                        "Broken head + valid 2-byte $x" );
-                                       } elseif( ( $first > 0xfd || $second > 0xfd ) &&
-                                                   ( ( $second > 0xbf && $third > 0xbf ) ||
-                                                     ( $second < 0xc0 && $third < 0xc0 ) ||
-                                                     ( $second > 0xfd ) ||
-                                                     ( $third > 0xfd ) ) ) {
+                                       } elseif ( ( $first > 0xfd || $second > 0xfd ) &&
+                                               ( ( $second > 0xbf && $third > 0xbf ) ||
+                                                       ( $second < 0xc0 && $third < 0xc0 ) ||
+                                                       ( $second > 0xfd ) ||
+                                                       ( $third > 0xfd ) )
+                                       ) {
                                                # fe and ff are not legal head bytes -- expect three replacement chars
                                                $this->assertEquals(
                                                        bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ),
                                                        bin2hex( $clean ),
                                                        "Forbidden triplet $x should be rejected" );
-                                       } elseif( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) {
+                                       } elseif ( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) {
                                                $this->assertEquals(
                                                        bin2hex( $head . UTF8_REPLACEMENT . $tail ),
                                                        bin2hex( $clean ),
@@ -251,20 +273,20 @@ class CleanUpTest extends MediaWikiTestCase {
        /** @todo document */
        function testChunkRegression() {
                # Check for regression against a chunking bug
-               $text   = "\x46\x55\xb8" .
-                         "\xdc\x96" .
-                         "\xee" .
-                         "\xe7" .
-                         "\x44" .
-                         "\xaa" .
-                         "\x2f\x25";
+               $text = "\x46\x55\xb8" .
+                       "\xdc\x96" .
+                       "\xee" .
+                       "\xe7" .
+                       "\x44" .
+                       "\xaa" .
+                       "\x2f\x25";
                $expect = "\x46\x55\xef\xbf\xbd" .
-                         "\xdc\x96" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x44" .
-                         "\xef\xbf\xbd" .
-                         "\x2f\x25";
+                       "\xdc\x96" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x44" .
+                       "\xef\xbf\xbd" .
+                       "\x2f\x25";
 
                $this->assertEquals(
                        bin2hex( $expect ),
@@ -273,33 +295,33 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testInterposeRegression() {
-               $text   = "\x4e\x30" .
-                         "\xb1" .              # bad tail
-                         "\x3a" .
-                         "\x92" .              # bad tail
-                         "\x62\x3a" .
-                         "\x84" .              # bad tail
-                         "\x43" .
-                         "\xc6" .              # bad head
-                         "\x3f" .
-                         "\x92" .              # bad tail
-                         "\xad" .              # bad tail
-                         "\x7d" .
-                         "\xd9\x95";
+               $text = "\x4e\x30" .
+                       "\xb1" . # bad tail
+                       "\x3a" .
+                       "\x92" . # bad tail
+                       "\x62\x3a" .
+                       "\x84" . # bad tail
+                       "\x43" .
+                       "\xc6" . # bad head
+                       "\x3f" .
+                       "\x92" . # bad tail
+                       "\xad" . # bad tail
+                       "\x7d" .
+                       "\xd9\x95";
 
                $expect = "\x4e\x30" .
-                         "\xef\xbf\xbd" .
-                         "\x3a" .
-                         "\xef\xbf\xbd" .
-                         "\x62\x3a" .
-                         "\xef\xbf\xbd" .
-                         "\x43" .
-                         "\xef\xbf\xbd" .
-                         "\x3f" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x7d" .
-                         "\xd9\x95";
+                       "\xef\xbf\xbd" .
+                       "\x3a" .
+                       "\xef\xbf\xbd" .
+                       "\x62\x3a" .
+                       "\xef\xbf\xbd" .
+                       "\x43" .
+                       "\xef\xbf\xbd" .
+                       "\x3f" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x7d" .
+                       "\xd9\x95";
 
                $this->assertEquals(
                        bin2hex( $expect ),
@@ -308,24 +330,24 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testOverlongRegression() {
-               $text   = "\x67" .
-                         "\x1a" . # forbidden ascii
-                         "\xea" . # bad head
-                         "\xc1\xa6" . # overlong sequence
-                         "\xad" . # bad tail
-                         "\x1c" . # forbidden ascii
-                         "\xb0" . # bad tail
-                         "\x3c" .
-                         "\x9e";  # bad tail
+               $text = "\x67" .
+                       "\x1a" . # forbidden ascii
+                       "\xea" . # bad head
+                       "\xc1\xa6" . # overlong sequence
+                       "\xad" . # bad tail
+                       "\x1c" . # forbidden ascii
+                       "\xb0" . # bad tail
+                       "\x3c" .
+                       "\x9e"; # bad tail
                $expect = "\x67" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x3c" .
-                         "\xef\xbf\xbd";
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x3c" .
+                       "\xef\xbf\xbd";
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
@@ -333,14 +355,14 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testSurrogateRegression() {
-               $text   = "\xed\xb4\x96" . # surrogate 0xDD16
-                         "\x83" . # bad tail
-                         "\xb4" . # bad tail
-                         "\xac";  # bad head
+               $text = "\xed\xb4\x96" . # surrogate 0xDD16
+                       "\x83" . # bad tail
+                       "\xb4" . # bad tail
+                       "\xac"; # bad head
                $expect = "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd";
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd";
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
@@ -348,14 +370,14 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testBomRegression() {
-               $text   = "\xef\xbf\xbe" . # U+FFFE, illegal char
-                         "\xb2" . # bad tail
-                         "\xef" . # bad head
-                         "\x59";
+               $text = "\xef\xbf\xbe" . # U+FFFE, illegal char
+                       "\xb2" . # bad tail
+                       "\xef" . # bad head
+                       "\x59";
                $expect = "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x59";
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x59";
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
@@ -363,7 +385,7 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testForbiddenRegression() {
-               $text   = "\xef\xbf\xbf"; # U+FFFF, illegal char
+               $text = "\xef\xbf\xbf"; # U+FFFF, illegal char
                $expect = "\xef\xbf\xbd";
                $this->assertEquals(
                        bin2hex( $expect ),
@@ -373,8 +395,8 @@ class CleanUpTest extends MediaWikiTestCase {
        /** @todo document */
        function testHangulRegression() {
                $text = "\xed\x9c\xaf" . # Hangul char
-                               "\xe1\x87\x81";  # followed by another final jamo
-               $expect = $text;         # Should *not* change.
+                       "\xe1\x87\x81"; # followed by another final jamo
+               $expect = $text; # Should *not* change.
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
index ab3d811..f3dd0a0 100644 (file)
@@ -15,9 +15,8 @@ class BagOStuffTest extends MediaWikiTestCase {
                        $name = $this->getCliArg( 'use-bagostuff=' );
 
                        $this->cache = ObjectCache::newFromId( $name );
-
-               // no type defined - use simple hash
                } else {
+                       // no type defined - use simple hash
                        $this->cache = new HashBagOStuff;
                }
 
@@ -41,7 +40,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                 * @use int $usleep
                 * @return int
                 */
-               $callback = function( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) {
+               $callback = function ( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) {
                        // let's pretend this is an expensive callback to test concurrent merge attempts
                        usleep( $usleep );
 
@@ -68,7 +67,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                 * - pcntl_fork is supported by the system
                 * - cache type will correctly support calls over forks
                 */
-               $fork = (bool) $this->getCliArg( 'use-bagostuff=' );
+               $fork = (bool)$this->getCliArg( 'use-bagostuff=' );
                $fork &= function_exists( 'pcntl_fork' );
                $fork &= !$this->cache instanceof HashBagOStuff;
                $fork &= !$this->cache instanceof EmptyBagOStuff;
index 5f670fc..51643ce 100644 (file)
@@ -65,38 +65,68 @@ class MagicVariableTest extends MediaWikiTestCase {
 
        # day
 
-       /** @dataProvider MediaWikiProvide::Days */
+       /**
+        * @dataProvider MediaWikiProvide::Days
+        * @group Database
+        */
        function testCurrentdayIsUnPadded( $day ) {
                $this->assertUnPadded( 'currentday', $day );
        }
-       /** @dataProvider MediaWikiProvide::Days */
+
+       /**
+        * @dataProvider MediaWikiProvide::Days
+        * @group Database
+        */
        function testCurrentdaytwoIsZeroPadded( $day ) {
                $this->assertZeroPadded( 'currentday2', $day );
        }
-       /** @dataProvider MediaWikiProvide::Days */
+
+       /**
+        * @dataProvider MediaWikiProvide::Days
+        * @group Database
+        */
        function testLocaldayIsUnPadded( $day ) {
                $this->assertUnPadded( 'localday', $day );
        }
-       /** @dataProvider MediaWikiProvide::Days */
+
+       /**
+        * @dataProvider MediaWikiProvide::Days
+        * @group Database
+        */
        function testLocaldaytwoIsZeroPadded( $day ) {
                $this->assertZeroPadded( 'localday2', $day );
        }
 
        # month
 
-       /** @dataProvider MediaWikiProvide::Months */
+       /**
+        * @dataProvider MediaWikiProvide::Months
+        * @group Database
+        */
        function testCurrentmonthIsZeroPadded( $month ) {
                $this->assertZeroPadded( 'currentmonth', $month );
        }
-       /** @dataProvider MediaWikiProvide::Months */
+
+       /**
+        * @dataProvider MediaWikiProvide::Months
+        * @group Database
+        */
        function testCurrentmonthoneIsUnPadded( $month ) {
                $this->assertUnPadded( 'currentmonth1', $month );
        }
-       /** @dataProvider MediaWikiProvide::Months */
+
+       /**
+        * @dataProvider MediaWikiProvide::Months
+        * @group Database
+        */
        function testLocalmonthIsZeroPadded( $month ) {
                $this->assertZeroPadded( 'localmonth', $month );
        }
-       /** @dataProvider MediaWikiProvide::Months */
+
+       /**
+        * @dataProvider MediaWikiProvide::Months
+        * @group Database
+        */
        function testLocalmonthoneIsUnPadded( $month ) {
                $this->assertUnPadded( 'localmonth1', $month );
        }
@@ -104,22 +134,36 @@ class MagicVariableTest extends MediaWikiTestCase {
 
        # revision day
 
-       /** @dataProvider MediaWikiProvide::Days */
+       /**
+        * @dataProvider MediaWikiProvide::Days
+        * @group Database
+        */
        function testRevisiondayIsUnPadded( $day ) {
                $this->assertUnPadded( 'revisionday', $day );
        }
-       /** @dataProvider MediaWikiProvide::Days */
+
+       /**
+        * @dataProvider MediaWikiProvide::Days
+        * @group Database
+        */
        function testRevisiondaytwoIsZeroPadded( $day ) {
                $this->assertZeroPadded( 'revisionday2', $day );
        }
 
        # revision month
 
-       /** @dataProvider MediaWikiProvide::Months */
+       /**
+        * @dataProvider MediaWikiProvide::Months
+        * @group Database
+        */
        function testRevisionmonthIsZeroPadded( $month ) {
                $this->assertZeroPadded( 'revisionmonth', $month );
        }
-       /** @dataProvider MediaWikiProvide::Months */
+
+       /**
+        * @dataProvider MediaWikiProvide::Months
+        * @group Database
+        */
        function testRevisionmonthoneIsUnPadded( $month ) {
                $this->assertUnPadded( 'revisionmonth1', $month );
        }
@@ -127,16 +171,17 @@ class MagicVariableTest extends MediaWikiTestCase {
        /**
         * Rough tests for {{SERVERNAME}} magic word
         * Bug 31176
+        * @group Database
         */
        function testServernameFromDifferentProtocols() {
                global $wgServer;
-               $saved_wgServer= $wgServer;
+               $saved_wgServer = $wgServer;
 
                $wgServer = 'http://localhost/';
                $this->assertMagic( 'localhost', 'servername' );
                $wgServer = 'https://localhost/';
                $this->assertMagic( 'localhost', 'servername' );
-               $wgServer = '//localhost/';  # bug 31176
+               $wgServer = '//localhost/'; # bug 31176
                $this->assertMagic( 'localhost', 'servername' );
 
                $wgServer = $saved_wgServer;
@@ -163,8 +208,11 @@ class MagicVariableTest extends MediaWikiTestCase {
        private function assertMagicPadding( $magic, $value, $format ) {
                # Initialize parser timestamp as year 2010 at 12h34 56s.
                # month and day are given by the caller ($value). Month < 12!
-               if( $value > 12 ) { $month = $value % 12; }
-               else { $month = $value; }
+               if ( $value > 12 ) {
+                       $month = $value % 12;
+               } else {
+                       $month = $value;
+               }
 
                $this->setParserTS(
                        sprintf( '2010%02d%02d123456', $month, $value )
@@ -188,8 +236,8 @@ class MagicVariableTest extends MediaWikiTestCase {
         * Assertion helper to test a magic variable output
         */
        private function assertMagic( $expected, $magic ) {
-               if( in_array( $magic, $this->expectedAsInteger ) ) {
-                       $expected = (int) $expected;
+               if ( in_array( $magic, $this->expectedAsInteger ) ) {
+                       $expected = (int)$expected;
                }
 
                # Generate a message for the assertion
index b15365c..067a7c4 100644 (file)
@@ -3,9 +3,9 @@ require_once( __DIR__ . '/NewParserTest.php' );
 
 /**
  * The UnitTest must be either a class that inherits from MediaWikiTestCase
- * or a class that provides a public static suite() method which returns 
+ * or a class that provides a public static suite() method which returns
  * an PHPUnit_Framework_Test object
- * 
+ *
  * @group Parser
  * @group Database
  */
@@ -22,7 +22,7 @@ class MediaWikiParserTest {
                         * and then was ucfirst( basename( $filename, '.txt' )
                         * but that didn't work with names like foo.tests.txt
                         */
-                       $className = str_replace( '.', '_',  ucfirst( $testsName ) );
+                       $className = str_replace( '.', '_', ucfirst( $testsName ) );
 
                        eval( "/** @group Database\n@group Parser\n*/ class $className extends NewParserTest { protected \$file = '" . strtr( $filename, array( "'" => "\\'", '\\' => '\\\\' ) ) . "'; } " );
 
index 3e3b141..ec9ee1a 100644 (file)
@@ -8,7 +8,7 @@
  * @group Stub
  */
 class NewParserTest extends MediaWikiTestCase {
-       static protected $articles = array();   // Array of test articles defined by the tests
+       static protected $articles = array(); // Array of test articles defined by the tests
        /* The data provider is run on a different instance than the test, so it must be static
         * When running tests from several files, all tests will see all articles.
         */
@@ -32,15 +32,11 @@ class NewParserTest extends MediaWikiTestCase {
        protected $file = false;
 
        protected function setUp() {
-               global $wgContLang, $wgLanguageCode;
                global $wgNamespaceProtection, $wgNamespaceAliases;
                global $wgHooks, $IP;
 
                parent::setUp();
 
-               $wgLanguageCode = 'en';
-               $wgContLang = Language::factory( 'en' );
-
                //Setup CLI arguments
                if ( $this->getCliArg( 'regex=' ) ) {
                        $this->regex = $this->getCliArg( 'regex=' );
@@ -53,6 +49,8 @@ class NewParserTest extends MediaWikiTestCase {
 
                $tmpGlobals = array();
 
+               $tmpGlobals['wgLanguageCode'] = 'en';
+               $tmpGlobals['wgContLang'] = Language::factory( 'en' );
                $tmpGlobals['wgScript'] = '/index.php';
                $tmpGlobals['wgScriptPath'] = '/';
                $tmpGlobals['wgArticlePath'] = '/wiki/$1';
@@ -60,12 +58,12 @@ class NewParserTest extends MediaWikiTestCase {
                $tmpGlobals['wgStylePath'] = '/skins';
                $tmpGlobals['wgThumbnailScriptPath'] = false;
                $tmpGlobals['wgLocalFileRepo'] = array(
-                       'class'           => 'LocalRepo',
-                       'name'            => 'local',
-                       'url'             => 'http://example.com/images',
-                       'hashLevels'      => 2,
+                       'class' => 'LocalRepo',
+                       'name' => 'local',
+                       'url' => 'http://example.com/images',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => 'local-backend'
+                       'backend' => 'local-backend'
                );
                $tmpGlobals['wgForeignFileRepos'] = array();
                $tmpGlobals['wgEnableParserCache'] = false;
@@ -132,44 +130,43 @@ class NewParserTest extends MediaWikiTestCase {
                # Hack: insert a few Wikipedia in-project interwiki prefixes,
                # for testing inter-language links
                $this->db->insert( 'interwiki', array(
-                       array( 'iw_prefix' => 'wikipedia',
-                                  'iw_url'    => 'http://en.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
-                       array( 'iw_prefix' => 'meatball',
-                                  'iw_url'    => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
-                       array( 'iw_prefix' => 'zh',
-                                  'iw_url'    => 'http://zh.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       array( 'iw_prefix' => 'es',
-                                  'iw_url'    => 'http://es.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       array( 'iw_prefix' => 'fr',
-                                  'iw_url'    => 'http://fr.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       array( 'iw_prefix' => 'ru',
-                                  'iw_url'    => 'http://ru.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       /**
-                        * @todo Fixme! Why are we inserting duplicate data here? Shouldn't
-                        * need this IGNORE or shouldn't need the insert at all.
-                        */
+                               array( 'iw_prefix' => 'wikipedia',
+                                       'iw_url' => 'http://en.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 0 ),
+                               array( 'iw_prefix' => 'meatball',
+                                       'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 0 ),
+                               array( 'iw_prefix' => 'zh',
+                                       'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               array( 'iw_prefix' => 'es',
+                                       'iw_url' => 'http://es.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               array( 'iw_prefix' => 'fr',
+                                       'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               array( 'iw_prefix' => 'ru',
+                                       'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               /**
+                                * @todo Fixme! Why are we inserting duplicate data here? Shouldn't
+                                * need this IGNORE or shouldn't need the insert at all.
+                                */
                        ), __METHOD__, array( 'IGNORE' )
                );
 
-
                # Update certain things in site_stats
                $this->db->insert( 'site_stats',
                        array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ),
@@ -196,15 +193,15 @@ class NewParserTest extends MediaWikiTestCase {
                                'Upload of some lame file',
                                'Some lame file',
                                array(
-                                       'size'        => 12345,
-                                       'width'       => 1941,
-                                       'height'      => 220,
-                                       'bits'        => 24,
-                                       'media_type'  => MEDIATYPE_BITMAP,
-                                       'mime'        => 'image/jpeg',
-                                       'metadata'    => serialize( array() ),
-                                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                                       'fileExists'  => true ),
+                                       'size' => 12345,
+                                       'width' => 1941,
+                                       'height' => 220,
+                                       'bits' => 24,
+                                       'media_type' => MEDIATYPE_BITMAP,
+                                       'mime' => 'image/jpeg',
+                                       'metadata' => serialize( array() ),
+                                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                                       'fileExists' => true ),
                                $this->db->timestamp( '20010115123500' ), $user
                        );
                }
@@ -217,30 +214,27 @@ class NewParserTest extends MediaWikiTestCase {
                                'zomgnotcensored',
                                'Borderline image',
                                array(
-                                       'size'        => 12345,
-                                       'width'       => 320,
-                                       'height'      => 240,
-                                       'bits'        => 24,
-                                       'media_type'  => MEDIATYPE_BITMAP,
-                                       'mime'        => 'image/jpeg',
-                                       'metadata'    => serialize( array() ),
-                                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                                       'fileExists'  => true ),
+                                       'size' => 12345,
+                                       'width' => 320,
+                                       'height' => 240,
+                                       'bits' => 24,
+                                       'media_type' => MEDIATYPE_BITMAP,
+                                       'mime' => 'image/jpeg',
+                                       'metadata' => serialize( array() ),
+                                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                                       'fileExists' => true ),
                                $this->db->timestamp( '20010115123500' ), $user
                        );
                }
        }
 
-
-
-
        //ParserTest setup/teardown functions
 
        /**
         * Set up the global variables for a consistent environment for each test.
         * Ideally this should replace the global configuration entirely.
         */
-       protected function setupGlobals( $opts = '', $config = '' ) {
+       protected function setupGlobals( $opts = array(), $config = '' ) {
                global $wgFileBackends;
                # Find out values for some special options.
                $lang =
@@ -271,11 +265,11 @@ class NewParserTest extends MediaWikiTestCase {
                        }
                } else {
                        $backend = new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                               'name' => 'local-backend',
                                'lockManager' => 'nullLockManager',
                                'containerPaths' => array(
                                        'local-public' => "$uploadDir",
-                                       'local-thumb'  => "$uploadDir/thumb",
+                                       'local-thumb' => "$uploadDir/thumb",
                                )
                        ) );
                }
@@ -288,12 +282,12 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgExtensionAssetsPath' => '/extensions',
                        'wgActionPaths' => array(),
                        'wgLocalFileRepo' => array(
-                               'class'           => 'LocalRepo',
-                               'name'            => 'local',
-                               'url'             => 'http://example.com/images',
-                               'hashLevels'      => 2,
+                               'class' => 'LocalRepo',
+                               'name' => 'local',
+                               'url' => 'http://example.com/images',
+                               'hashLevels' => 2,
                                'transformVia404' => false,
-                               'backend'         => $backend
+                               'backend' => $backend
                        ),
                        'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
                        'wgStylePath' => '/skins',
@@ -304,7 +298,7 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgRawHtml' => isset( $opts['rawhtml'] ),
                        'wgLang' => null,
                        'wgContLang' => null,
-                       'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ),
+                       'wgNamespacesWithSubpages' => array( NS_MAIN => isset( $opts['subpage'] ) ),
                        'wgMaxTocLevel' => $maxtoclevel,
                        'wgCapitalLinks' => true,
                        'wgNoFollowLinks' => true,
@@ -320,10 +314,10 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgVariantArticlePath' => false,
                        'wgGroupPermissions' => array( '*' => array(
                                'createaccount' => true,
-                               'read'          => true,
-                               'edit'          => true,
-                               'createpage'    => true,
-                               'createtalk'    => true,
+                               'read' => true,
+                               'edit' => true,
+                               'createpage' => true,
+                               'createtalk' => true,
                        ) ),
                        'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ),
                        'wgDefaultExternalStore' => array(),
@@ -466,7 +460,7 @@ class NewParserTest extends MediaWikiTestCase {
                $base = $this->getBaseDir();
                // delete the files first, then the dirs.
                self::deleteFiles(
-                       array (
+                       array(
                                "$base/local-public/3/3a/Foobar.jpg",
                                "$base/local-thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
                                "$base/local-thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
@@ -545,7 +539,7 @@ class NewParserTest extends MediaWikiTestCase {
                        // @todo: When setting up pages, force the content model. Only skip if
                        //        $wgtContentModelUseDB is false.
                        $this->markTestSkipped( "Main namespace does not support wikitext,"
-                                       . "skipping parser test: $desc" );
+                               . "skipping parser test: $desc" );
                }
 
                wfDebug( "Running parser test: $desc\n" );
@@ -558,8 +552,7 @@ class NewParserTest extends MediaWikiTestCase {
 
                if ( isset( $opts['title'] ) ) {
                        $titleText = $opts['title'];
-               }
-               else {
+               } else {
                        $titleText = 'Parser test';
                }
 
@@ -632,7 +625,7 @@ class NewParserTest extends MediaWikiTestCase {
 
                $files = $wgParserTestFiles;
 
-               if( $this->getCliArg( 'file=' ) ) {
+               if ( $this->getCliArg( 'file=' ) ) {
                        $files = array( $this->getCliArg( 'file=' ) );
                }
 
@@ -794,15 +787,16 @@ class NewParserTest extends MediaWikiTestCase {
         */
        public function requireHook( $name ) {
                global $wgParser;
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
                return isset( $wgParser->mTagHooks[$name] );
        }
 
        public function requireFunctionHook( $name ) {
                global $wgParser;
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
                return isset( $wgParser->mFunctionHooks[$name] );
        }
+
        //Various "cleanup" functions
 
        /**
@@ -828,8 +822,7 @@ class NewParserTest extends MediaWikiTestCase {
        public function removeEndingNewline( $s ) {
                if ( substr( $s, -1 ) === "\n" ) {
                        return substr( $s, 0, -1 );
-               }
-               else {
+               } else {
                        return $s;
                }
        }
index e0f95b6..5c1a268 100644 (file)
@@ -5,10 +5,10 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
        public static function providePreSaveTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
+                               "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
                        ),
                        array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
-                              'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
+                               'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
                        ),
                );
        }
@@ -30,4 +30,3 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
 
        // TODO: Add tests for cleanSig() / cleanSigInSig(), getSection(), replaceSection(), getPreloadText()
 }
-
index 2244fdb..68f77ab 100644 (file)
@@ -35,4 +35,21 @@ class ParserOutputTest extends MediaWikiTestCase {
 
                $this->assertEquals( $shouldMatch, ParserOutput::isLinkInternal( $server, $url ) );
        }
+
+       public function testExtensionData() {
+               $po = new ParserOutput();
+
+               $po->setExtensionData( "one", "Foo" );
+
+               $this->assertEquals( "Foo", $po->getExtensionData( "one" ) );
+               $this->assertNull( $po->getExtensionData( "spam" ) );
+
+               $po->setExtensionData( "two", "Bar" );
+               $this->assertEquals( "Foo", $po->getExtensionData( "one" ) );
+               $this->assertEquals( "Bar", $po->getExtensionData( "two" ) );
+
+               $po->setExtensionData( "one", null );
+               $this->assertNull( $po->getExtensionData( "one" ) );
+               $this->assertEquals( "Bar", $po->getExtensionData( "two" ) );
+       }
 }
index 8c22c59..e16b407 100644 (file)
@@ -57,7 +57,7 @@ class ParserPreloadTest extends MediaWikiTestCase {
                );
        }
 
-       function assertPreloaded( $expected, $text, $msg='') {
+       function assertPreloaded( $expected, $text, $msg = '' ) {
                $this->assertEquals(
                        $expected,
                        $this->testParser->getPreloadText(
index 8b83b67..c51a1dc 100644 (file)
@@ -52,16 +52,16 @@ class PreprocessorTest extends MediaWikiTestCase {
                        array( "Foo\n=\n==\n=\n", "<root>Foo\n=\n==\n=\n</root>" ),
                        array( "{{Foo}}", "<root><template><title>Foo</title></template></root>" ),
                        array( "\n{{Foo}}", "<root>\n<template lineStart=\"1\"><title>Foo</title></template></root>" ),
-                       array( "{{Foo|bar}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ),  
-                       array( "{{Foo|bar}}a", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ),  
-                       array( "{{Foo|bar|baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ),  
+                       array( "{{Foo|bar}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ),
+                       array( "{{Foo|bar}}a", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ),
+                       array( "{{Foo|bar|baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ),
                        array( "{{Foo|1=bar}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part></template></root>" ),
                        array( "{{Foo|=bar}}", "<root><template><title>Foo</title><part><name></name>=<value>bar</value></part></template></root>" ),
-                       array( "{{Foo|bar=baz}}", "<root><template><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ), 
+                       array( "{{Foo|bar=baz}}", "<root><template><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ),
                        array( "{{Foo|{{bar}}=baz}}", "<root><template><title>Foo</title><part><name><template><title>bar</title></template></name>=<value>baz</value></part></template></root>" ),
-                       array( "{{Foo|1=bar|baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ), 
+                       array( "{{Foo|1=bar|baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ),
                        array( "{{Foo|1=bar|2=baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name>2</name>=<value>baz</value></part></template></root>" ),
-                       array( "{{Foo|bar|foo=baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ), 
+                       array( "{{Foo|bar|foo=baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ),
                        array( "{{{1}}}", "<root><tplarg><title>1</title></tplarg></root>" ),
                        array( "{{{1|}}}", "<root><tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ),
                        array( "{{{Foo}}}", "<root><tplarg><title>Foo</title></tplarg></root>" ),
@@ -84,26 +84,26 @@ class PreprocessorTest extends MediaWikiTestCase {
                        array( "Foo <gallery bar=\"baz\" />", "<root>Foo <ext><name>gallery</name><attr> bar=&quot;baz&quot; </attr></ext></root>" ),
                        array( "Foo <gallery bar=\"1\" baz=2 />", "<root>Foo <ext><name>gallery</name><attr> bar=&quot;1&quot; baz=2 </attr></ext></root>" ),
                        array( "</foo>Foo<//foo>", "<root><ext><name>/foo</name><attr></attr><inner>Foo</inner><close>&lt;//foo&gt;</close></ext></root>" ), # Worth blacklisting IMHO
-                       array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>"),
-                       array( "{{ {{Foo}}", "<root>{{ <template><title>Foo</title></template></root>"),
-                       array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "<root>{{Foobar <template><title>Foo</title></template> <template><title>Bar</title></template> <template><title>Baz</title></template> </root>"),
-                       array( "[[Foo]] |", "<root>[[Foo]] |</root>"),
-                       array( "{{Foo|Bar|", "<root>{{Foo|Bar|</root>"),
-                       array( "[[Foo]", "<root>[[Foo]</root>"),
-                       array( "[[Foo|Bar]", "<root>[[Foo|Bar]</root>"),
-                       array( "{{Foo| [[Bar] }}", "<root>{{Foo| [[Bar] }}</root>"),
-                       array( "{{Foo| [[Bar|Baz] }}", "<root>{{Foo| [[Bar|Baz] }}</root>"),
-                       array( "{{Foo|bar=[[baz]}}", "<root>{{Foo|bar=[[baz]}}</root>"),
-                       array( "{{foo|", "<root>{{foo|</root>"),
-                       array( "{{foo|}", "<root>{{foo|}</root>"),
-                       array( "{{foo|} }}", "<root><template><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>"),
-                       array( "{{foo|bar=|}", "<root>{{foo|bar=|}</root>"),
-                       array( "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>"),
-                       array( "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>"),
+                       array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>" ),
+                       array( "{{ {{Foo}}", "<root>{{ <template><title>Foo</title></template></root>" ),
+                       array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "<root>{{Foobar <template><title>Foo</title></template> <template><title>Bar</title></template> <template><title>Baz</title></template> </root>" ),
+                       array( "[[Foo]] |", "<root>[[Foo]] |</root>" ),
+                       array( "{{Foo|Bar|", "<root>{{Foo|Bar|</root>" ),
+                       array( "[[Foo]", "<root>[[Foo]</root>" ),
+                       array( "[[Foo|Bar]", "<root>[[Foo|Bar]</root>" ),
+                       array( "{{Foo| [[Bar] }}", "<root>{{Foo| [[Bar] }}</root>" ),
+                       array( "{{Foo| [[Bar|Baz] }}", "<root>{{Foo| [[Bar|Baz] }}</root>" ),
+                       array( "{{Foo|bar=[[baz]}}", "<root>{{Foo|bar=[[baz]}}</root>" ),
+                       array( "{{foo|", "<root>{{foo|</root>" ),
+                       array( "{{foo|}", "<root>{{foo|}</root>" ),
+                       array( "{{foo|} }}", "<root><template><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>" ),
+                       array( "{{foo|bar=|}", "<root>{{foo|bar=|}</root>" ),
+                       array( "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>" ),
+                       array( "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>" ),
                        /* array( file_get_contents( __DIR__ . '/QuoteQuran.txt' ), file_get_contents( __DIR__ . '/QuoteQuranExpanded.txt' ) ), */
                );
        }
@@ -154,6 +154,7 @@ class PreprocessorTest extends MediaWikiTestCase {
                        array( "Factorial" ), # http://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC-BY-SA by Polonium
                        array( "All_system_messages" ), # http://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki
                        array( "Fundraising" ), # http://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC-BY-SA, copied there by Sky Harbor.
+                       array( "NestedTemplates" ), # bug 27936
                );
        }
 
@@ -180,7 +181,7 @@ class PreprocessorTest extends MediaWikiTestCase {
         * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642
         */
        function provideHeadings() {
-               return array(   /* These should become headings: */
+               return array( /* These should become headings: */
                        array( "== h ==<!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==<comment>&lt;!--c1--&gt;</comment></h></root>" ),
                        array( "== h ==         <!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==       <comment>&lt;!--c1--&gt;</comment></h></root>" ),
                        array( "== h ==<!--c1-->        ", "<root><h level=\"2\" i=\"1\">== h ==<comment>&lt;!--c1--&gt;</comment>      </h></root>" ),
@@ -226,4 +227,3 @@ class PreprocessorTest extends MediaWikiTestCase {
                $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) );
        }
 }
-
index 292f13a..d643264 100644 (file)
@@ -4,13 +4,12 @@
  * @group Parser
  */
 class TagHookTest extends MediaWikiTestCase {
-       
        public static function provideValidNames() {
                return array( array( 'foo' ), array( 'foo-bar' ), array( 'foo_bar' ), array( 'FOO-BAR' ), array( 'foo bar' ) );
        }
 
        public static function provideBadNames() {
-               return array( array( "foo<bar" ), array( "foo>bar" ), array( "foo\nbar" ),  array( "foo\rbar" ) );
+               return array( array( "foo<bar" ), array( "foo>bar" ), array( "foo\nbar" ), array( "foo\rbar" ) );
        }
 
        protected function setUp() {
@@ -21,18 +20,19 @@ class TagHookTest extends MediaWikiTestCase {
 
        /**
         * @dataProvider provideValidNames
+        * @group Database
         */
        function testTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setHook( $tag, array( $this, 'tagCallback' ) );
                $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
                $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() );
-               
+
                $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle
        }
-       
+
        /**
         * @dataProvider provideBadNames
         * @expectedException MWException
@@ -40,26 +40,27 @@ class TagHookTest extends MediaWikiTestCase {
        function testBadTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setHook( $tag, array( $this, 'tagCallback' ) );
                $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
-               $this->fail('Exception not thrown.');
+               $this->fail( 'Exception not thrown.' );
        }
-       
+
        /**
         * @dataProvider provideValidNames
+        * @group Database
         */
        function testFunctionTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), 0 );
                $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
                $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() );
-               
+
                $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle
        }
-       
+
        /**
         * @dataProvider provideBadNames
         * @expectedException MWException
@@ -67,16 +68,16 @@ class TagHookTest extends MediaWikiTestCase {
        function testBadFunctionTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), SFH_OBJECT_ARGS );
                $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
-               $this->fail('Exception not thrown.');
+               $this->fail( 'Exception not thrown.' );
        }
-       
+
        function tagCallback( $text, $params, $parser ) {
                return str_rot13( $text );
        }
-       
+
        function functionTagCallback( &$parser, $frame, $code, $attribs ) {
                return str_rot13( $code );
        }
index 7339fb8..6abca6d 100644 (file)
@@ -18,10 +18,10 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                # Get database type and version
                $dbType = $this->db->getType();
                $dbSupported =
-                       ($dbType === 'mysql')
-                       || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' );
+                       ( $dbType === 'mysql' )
+                               || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' );
 
-               if( !$dbSupported ) {
+               if ( !$dbSupported ) {
                        $this->markTestSkipped( "MySQL or SQLite with FTS3 only" );
                }
 
@@ -49,29 +49,29 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        return;
                }
 
-               $this->insertPage( "Not_Main_Page",     "This is not a main page", 0 );
-               $this->insertPage( 'Talk:Not_Main_Page',        'This is not a talk page to the main page, see [[smithee]]', 1 );
-               $this->insertPage( 'Smithee',   'A smithee is one who smiths. See also [[Alan Smithee]]', 0 );
-               $this->insertPage( 'Talk:Smithee',      'This article sucks.', 1 );
-               $this->insertPage( 'Unrelated_page',    'Nothing in this page is about the S word.', 0 );
-               $this->insertPage( 'Another_page',      'This page also is unrelated.', 0 );
-               $this->insertPage( 'Help:Help',         'Help me!', 4 );
-               $this->insertPage( 'Thppt',             'Blah blah', 0 );
-               $this->insertPage( 'Alan_Smithee',      'yum', 0 );
-               $this->insertPage( 'Pages',             'are\'food', 0 );
-               $this->insertPage( 'HalfOneUp', 'AZ', 0 );
-               $this->insertPage( 'FullOneUp', 'AZ', 0 );
-               $this->insertPage( 'HalfTwoLow',        'az', 0 );
-               $this->insertPage( 'FullTwoLow',        'az', 0 );
-               $this->insertPage( 'HalfNumbers',       '1234567890', 0 );
-               $this->insertPage( 'FullNumbers',       '1234567890', 0 );
-               $this->insertPage( 'DomainName',        'example.com', 0 );
+               $this->insertPage( "Not_Main_Page", "This is not a main page", 0 );
+               $this->insertPage( 'Talk:Not_Main_Page', 'This is not a talk page to the main page, see [[smithee]]', 1 );
+               $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 );
+               $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 );
+               $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 );
+               $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 );
+               $this->insertPage( 'Help:Help', 'Help me!', 4 );
+               $this->insertPage( 'Thppt', 'Blah blah', 0 );
+               $this->insertPage( 'Alan_Smithee', 'yum', 0 );
+               $this->insertPage( 'Pages', 'are\'food', 0 );
+               $this->insertPage( 'HalfOneUp', 'AZ', 0 );
+               $this->insertPage( 'FullOneUp', 'AZ', 0 );
+               $this->insertPage( 'HalfTwoLow', 'az', 0 );
+               $this->insertPage( 'FullTwoLow', 'az', 0 );
+               $this->insertPage( 'HalfNumbers', '1234567890', 0 );
+               $this->insertPage( 'FullNumbers', '1234567890', 0 );
+               $this->insertPage( 'DomainName', 'example.com', 0 );
        }
 
        function fetchIds( $results ) {
                if ( !$this->isWikitextNS( NS_MAIN ) ) {
                        $this->markTestIncomplete( __CLASS__ . " does no yet support non-wikitext content "
-                               . "in the main namespace");
+                               . "in the main namespace" );
                }
 
                $this->assertTrue( is_object( $results ) );
@@ -135,9 +135,9 @@ class SearchEngineTest extends MediaWikiLangTestCase {
 
        function testTextSearch() {
                $this->assertEquals(
-                               array( 'Smithee' ),
-                               $this->fetchIds( $this->search->searchText( 'smithee' ) ),
-                               "Plain search failed" );
+                       array( 'Smithee' ),
+                       $this->fetchIds( $this->search->searchText( 'smithee' ) ),
+                       "Plain search failed" );
        }
 
        function testTextPowerSearch() {
index 208ab1e..0cecdee 100644 (file)
  * @ingroup Test
  *
  * @group Site
- * @group Database
  *
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
-class MediaWikiSiteTest extends SiteObjectTest {
-
-       public function setUp() {
-               parent::setUp();
-
-               static $hasSites = false;
-
-               if ( !$hasSites ) {
-                       TestSites::insertIntoDb();
-                       $hasSites = true;
-               }
-       }
-
-       public function testFactoryConstruction() {
-               $this->assertInstanceOf( 'MediaWikiSite', MediaWikiSite::newFromGlobalId( 'enwiki' ) );
-               $this->assertInstanceOf( 'Site', MediaWikiSite::newFromGlobalId( 'enwiki' ) );
-               $this->assertInstanceOf( 'MediaWikiSite', SitesTable::singleton()->newRow( array( 'type' => Site::TYPE_MEDIAWIKI ) ) );
-       }
+class MediaWikiSiteTest extends SiteTest {
 
        public function testNormalizePageTitle() {
-               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'enwiki' );
 
                //NOTE: this does not actually call out to the enwiki site to perform the normalization,
                //      but uses a local Title object to do so. This is hardcoded on SiteLink::normalizePageTitle
@@ -73,8 +56,7 @@ class MediaWikiSiteTest extends SiteObjectTest {
         * @dataProvider fileUrlProvider
         */
        public function testGetFileUrl( $url, $filePath, $pathArgument, $expected ) {
-               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
-
+               $site = new MediaWikiSite();
                $site->setFilePath( $url . $filePath );
 
                $this->assertEquals( $expected, $site->getFileUrl( $pathArgument ) );
@@ -97,10 +79,9 @@ class MediaWikiSiteTest extends SiteObjectTest {
         * @dataProvider provideGetPageUrl
         */
        public function testGetPageUrl( $path, $page, $expected ) {
-               /* @var MediaWikiSite $site */
-               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
-
+               $site = new MediaWikiSite();
                $site->setLinkPath( $path );
+
                $this->assertContains( $path, $site->getPageUrl() );
                $this->assertContains( $expected, $site->getPageUrl( $page ) );
        }
diff --git a/tests/phpunit/includes/site/SiteArrayTest.php b/tests/phpunit/includes/site/SiteArrayTest.php
deleted file mode 100644 (file)
index 613f63f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-
-/**
- * Tests for the SiteArray class.
- * The tests for methods defined in the SiteList interface are in SiteListTest.
- *
- * 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
- *Both
- * Bith
- * @file
- * @since 1.21
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- *
- * @licence GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SiteArrayTest extends GenericArrayObjectTest {
-
-       /**
-        * @see GenericArrayObjectTest::elementInstancesProvider
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       public function elementInstancesProvider() {
-               $sites = TestSites::getSites();
-
-               $siteArrays = array();
-
-               $siteArrays[] = $sites;
-
-               $siteArrays[] = array( array_shift( $sites ) );
-
-               $siteArrays[] = array( array_shift( $sites ), array_shift( $sites ) );
-
-               return $this->arrayWrap( $siteArrays );
-       }
-
-       /**
-        * @see GenericArrayObjectTest::getInstanceClass
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       public function getInstanceClass() {
-               return 'SiteArray';
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        *
-        * @since 1.21
-        *
-        * @param SiteArray $list
-        */
-       public function testSerializationMore( SiteArray $list ) {
-               $serialization = serialize( $list );
-               /**
-                * @var SiteArray $copy
-                */
-               $copy = unserialize( $serialization );
-
-               $this->assertArrayEquals( $list->getGlobalIdentifiers(), $copy->getGlobalIdentifiers() );
-
-               /**
-                * @var Site $site
-                */
-               foreach ( $list as $site ) {
-                       $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) );
-               }
-       }
-
-}
\ No newline at end of file
index bb8367f..c329839 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Tests for the SiteList implementing classes.
+ * Tests for the SiteList 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
@@ -41,7 +41,7 @@ class SiteListTest extends MediaWikiTestCase {
                $listInstances = array();
 
                foreach ( $sitesArrays as $sitesArray ) {
-                       $listInstances[] = new SiteArray( $sitesArray[0] );
+                       $listInstances[] = new SiteList( $sitesArray[0] );
                }
 
                return $this->arrayWrap( $listInstances );
@@ -80,8 +80,7 @@ class SiteListTest extends MediaWikiTestCase {
        public function testGetSiteByGlobalId( SiteList $sites ) {
                if ( $sites->isEmpty() ) {
                        $this->assertTrue( true );
-               }
-               else {
+               } else {
                        /**
                         * @var Site $site
                         */
@@ -164,5 +163,28 @@ class SiteListTest extends MediaWikiTestCase {
                $this->assertArrayEquals( $expected, $identifiers );
        }
 
+       /**
+        * @dataProvider siteListProvider
+        *
+        * @since 1.21
+        *
+        * @param SiteList $list
+        */
+       public function testSerialization( SiteList $list ) {
+               $serialization = serialize( $list );
+               /**
+                * @var SiteArray $copy
+                */
+               $copy = unserialize( $serialization );
+
+               $this->assertArrayEquals( $list->getGlobalIdentifiers(), $copy->getGlobalIdentifiers() );
+
+               /**
+                * @var Site $site
+                */
+               foreach ( $list as $site ) {
+                       $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) );
+               }
+       }
 
-}
\ No newline at end of file
+}
diff --git a/tests/phpunit/includes/site/SiteObjectTest.php b/tests/phpunit/includes/site/SiteObjectTest.php
deleted file mode 100644 (file)
index 207f46c..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-<?php
-
-/**
- * Tests for the SiteObject 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
- *
- * @file
- * @since 1.21
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- * @group Database
- *
- * @licence GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SiteObjectTest extends ORMRowTest {
-
-       /**
-        * @see ORMRowTest::getRowClass
-        * @since 1.21
-        * @return string
-        */
-       protected function getRowClass() {
-               return 'SiteObject';
-       }
-
-       /**
-        * @see ORMRowTest::getTableInstance
-        * @since 1.21
-        * @return IORMTable
-        */
-       protected function getTableInstance() {
-               return SitesTable::singleton();
-       }
-
-       /**
-        * @see ORMRowTest::constructorTestProvider
-        * @since 1.21
-        * @return array
-        */
-       public function constructorTestProvider() {
-               $argLists = array();
-
-               $argLists[] = array( 'global_key' => 'foo' );
-
-               $argLists[] = array( 'global_key' => 'bar', 'type' => Site::TYPE_MEDIAWIKI );
-
-               $constructorArgs = array();
-
-               foreach ( $argLists as $argList ) {
-                       $constructorArgs[] = array( $argList, true );
-               }
-
-               return $constructorArgs;
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetInterwikiIds( Site $site ) {
-               $this->assertInternalType( 'array', $site->getInterwikiIds() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetNavigationIds( Site $site ) {
-               $this->assertInternalType( 'array', $site->getNavigationIds() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testAddNavigationId( Site $site ) {
-               $site->addNavigationId( 'foobar' );
-               $this->assertTrue( in_array( 'foobar', $site->getNavigationIds(), true ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testAddInterwikiId( Site $site ) {
-               $site->addInterwikiId( 'foobar' );
-               $this->assertTrue( in_array( 'foobar', $site->getInterwikiIds(), true ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetLanguageCode( Site $site ) {
-               $this->assertTypeOrFalse( 'string', $site->getLanguageCode() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testSetLanguageCode( Site $site ) {
-               $site->setLanguageCode( 'en' );
-               $this->assertEquals( 'en', $site->getLanguageCode() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testNormalizePageName( Site $site ) {
-               $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetGlobalId( Site $site ) {
-               $this->assertInternalType( 'string', $site->getGlobalId() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testSetGlobalId( Site $site ) {
-               $site->setGlobalId( 'foobar' );
-               $this->assertEquals( 'foobar', $site->getGlobalId() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetType( Site $site ) {
-               $this->assertInternalType( 'string', $site->getType() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetPath( Site $site ) {
-               $this->assertTypeOrFalse( 'string', $site->getPath( 'page_path' ) );
-               $this->assertTypeOrFalse( 'string', $site->getPath( 'file_path' ) );
-               $this->assertTypeOrFalse( 'string', $site->getPath( 'foobar' ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetAllPaths( Site $site ) {
-               $this->assertInternalType( 'array', $site->getAllPaths() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testSetAndRemovePath( Site $site ) {
-               $count = count( $site->getAllPaths() );
-
-               $site->setPath( 'spam', 'http://www.wikidata.org/$1' );
-               $site->setPath( 'spam', 'http://www.wikidata.org/foo/$1' );
-               $site->setPath( 'foobar', 'http://www.wikidata.org/bar/$1' );
-
-               $this->assertEquals( $count + 2, count( $site->getAllPaths() ) );
-
-               $this->assertInternalType( 'string', $site->getPath( 'foobar' ) );
-               $this->assertEquals( 'http://www.wikidata.org/foo/$1', $site->getPath( 'spam' ) );
-
-               $site->removePath( 'spam' );
-               $site->removePath( 'foobar' );
-
-               $this->assertEquals( $count, count( $site->getAllPaths() ) );
-
-               $this->assertFalse( $site->getPath( 'foobar' ) );
-               $this->assertFalse( $site->getPath( 'spam' ) );
-       }
-
-       public function testSetLinkPath() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-               $path = "TestPath/$1";
-
-               $site->setLinkPath( $path );
-               $this->assertEquals( $path, $site->getLinkPath() );
-       }
-
-       public function testGetLinkPathType() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               $path = 'TestPath/$1';
-               $site->setLinkPath( $path );
-               $this->assertEquals( $path, $site->getPath( $site->getLinkPathType() ) );
-
-               $path = 'AnotherPath/$1';
-               $site->setPath( $site->getLinkPathType(), $path );
-               $this->assertEquals( $path, $site->getLinkPath() );
-       }
-
-       public function testSetPath() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               $path = 'TestPath/$1';
-               $site->setPath( 'foo', $path );
-
-               $this->assertEquals( $path, $site->getPath( 'foo' ) );
-       }
-
-       public function testProtocolRelativePath() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               $type = $site->getLinkPathType();
-               $path = '//acme.com/'; // protocol-relative URL
-               $site->setPath( $type, $path );
-
-               $this->assertEquals( '', $site->getProtocol() );
-       }
-
-       public function provideGetPageUrl() {
-               //NOTE: the assumption that the URL is built by replacing $1
-               //      with the urlencoded version of $page
-               //      is true for SiteObject but not guaranteed for subclasses.
-               //      Subclasses need to override this provider appropriately.
-
-               return array(
-                       array( #0
-                               'http://acme.test/TestPath/$1',
-                               'Foo',
-                               '/TestPath/Foo',
-                       ),
-                       array( #1
-                               'http://acme.test/TestScript?x=$1&y=bla',
-                               'Foo',
-                               'TestScript?x=Foo&y=bla',
-                       ),
-                       array( #2
-                               'http://acme.test/TestPath/$1',
-                               'foo & bar/xyzzy (quux-shmoox?)',
-                               '/TestPath/foo%20%26%20bar%2Fxyzzy%20%28quux-shmoox%3F%29',
-                       ),
-               );
-       }
-
-       /**
-        * @dataProvider provideGetPageUrl
-        */
-       public function testGetPageUrl( $path, $page, $expected ) {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               //NOTE: the assumption that getPageUrl is based on getLinkPath
-               //      is true for SiteObject but not guaranteed for subclasses.
-               //      Subclasses need to override this test case appropriately.
-               $site->setLinkPath( $path );
-               $this->assertContains( $path, $site->getPageUrl() );
-
-               $this->assertContains( $expected, $site->getPageUrl( $page ) );
-       }
-
-       protected function assertTypeOrFalse( $type, $value ) {
-               if ( $value === false ) {
-                       $this->assertTrue( true );
-               }
-               else {
-                       $this->assertInternalType( $type, $value );
-               }
-       }
-
-}
\ No newline at end of file
diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php b/tests/phpunit/includes/site/SiteSQLStoreTest.php
new file mode 100644 (file)
index 0000000..cf4ce94
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * Tests for the SiteSQLStore 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
+ *
+ * @file
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ * @group Database
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteSQLStoreTest extends MediaWikiTestCase {
+
+       public function testGetSites() {
+               $expectedSites = TestSites::getSites();
+               TestSites::insertIntoDb();
+
+               $store = SiteSQLStore::newInstance();
+
+               $sites = $store->getSites();
+
+               $this->assertInstanceOf( 'SiteList', $sites );
+
+               /**
+                * @var Site $site
+                */
+               foreach ( $sites as $site ) {
+                       $this->assertInstanceOf( 'Site', $site );
+               }
+
+               foreach ( $expectedSites as $site ) {
+                       if ( $site->getGlobalId() !== null ) {
+                               $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) );
+                       }
+               }
+       }
+
+       public function testSaveSites() {
+               $store = SiteSQLStore::newInstance();
+
+               $sites = array();
+
+               $site = new Site();
+               $site->setGlobalId( 'ertrywuutr' );
+               $site->setLanguageCode( 'en' );
+               $sites[] = $site;
+
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'sdfhxujgkfpth' );
+               $site->setLanguageCode( 'nl' );
+               $sites[] = $site;
+
+               $this->assertTrue( $store->saveSites( $sites ) );
+
+               $site = $store->getSite( 'ertrywuutr' );
+               $this->assertInstanceOf( 'Site', $site );
+               $this->assertEquals( 'en', $site->getLanguageCode() );
+               $this->assertTrue( is_integer( $site->getInternalId() ) );
+               $this->assertTrue( $site->getInternalId() >= 0 );
+
+               $site = $store->getSite( 'sdfhxujgkfpth' );
+               $this->assertInstanceOf( 'Site', $site );
+               $this->assertEquals( 'nl', $site->getLanguageCode() );
+               $this->assertTrue( is_integer( $site->getInternalId() ) );
+               $this->assertTrue( $site->getInternalId() >= 0 );
+       }
+
+       public function testReset() {
+               $store1 = SiteSQLStore::newInstance();
+               $store2 = SiteSQLStore::newInstance();
+
+               // initialize internal cache
+               $this->assertGreaterThan( 0, $store1->getSites()->count() );
+               $this->assertGreaterThan( 0, $store2->getSites()->count() );
+
+               // Clear actual data. Will purge the external cache and reset the internal
+               // cache in $store1, but not the internal cache in store2.
+               $this->assertTrue( $store1->clear() );
+
+               // sanity check: $store2 should have a stale cache now
+               $this->assertNotNull( $store2->getSite( 'enwiki' ) );
+
+               // purge cache
+               $store2->reset();
+
+               // ...now the internal cache of $store2 should be updated and thus empty.
+               $site = $store2->getSite( 'enwiki' );
+               $this->assertNull( $site );
+       }
+
+       public function testClear() {
+               $store = SiteSQLStore::newInstance();
+               $this->assertTrue( $store->clear() );
+
+               $site = $store->getSite( 'enwiki' );
+               $this->assertNull( $site );
+
+               $sites = $store->getSites();
+               $this->assertEquals( 0, $sites->count() );
+       }
+
+}
diff --git a/tests/phpunit/includes/site/SiteTest.php b/tests/phpunit/includes/site/SiteTest.php
new file mode 100644 (file)
index 0000000..d20e2a5
--- /dev/null
@@ -0,0 +1,267 @@
+<?php
+
+/**
+ * Tests for the Site 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
+ *
+ * @file
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteTest extends MediaWikiTestCase {
+
+       public function instanceProvider() {
+               return $this->arrayWrap( TestSites::getSites() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetInterwikiIds( Site $site ) {
+               $this->assertInternalType( 'array', $site->getInterwikiIds() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetNavigationIds( Site $site ) {
+               $this->assertInternalType( 'array', $site->getNavigationIds() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testAddNavigationId( Site $site ) {
+               $site->addNavigationId( 'foobar' );
+               $this->assertTrue( in_array( 'foobar', $site->getNavigationIds(), true ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testAddInterwikiId( Site $site ) {
+               $site->addInterwikiId( 'foobar' );
+               $this->assertTrue( in_array( 'foobar', $site->getInterwikiIds(), true ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetLanguageCode( Site $site ) {
+               $this->assertTypeOrValue( 'string', $site->getLanguageCode(), null );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetLanguageCode( Site $site ) {
+               $site->setLanguageCode( 'en' );
+               $this->assertEquals( 'en', $site->getLanguageCode() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testNormalizePageName( Site $site ) {
+               $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetGlobalId( Site $site ) {
+               $this->assertTypeOrValue( 'string', $site->getGlobalId(), null );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetGlobalId( Site $site ) {
+               $site->setGlobalId( 'foobar' );
+               $this->assertEquals( 'foobar', $site->getGlobalId() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetType( Site $site ) {
+               $this->assertInternalType( 'string', $site->getType() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetPath( Site $site ) {
+               $this->assertTypeOrValue( 'string', $site->getPath( 'page_path' ), null );
+               $this->assertTypeOrValue( 'string', $site->getPath( 'file_path' ), null );
+               $this->assertTypeOrValue( 'string', $site->getPath( 'foobar' ), null );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetAllPaths( Site $site ) {
+               $this->assertInternalType( 'array', $site->getAllPaths() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetAndRemovePath( Site $site ) {
+               $count = count( $site->getAllPaths() );
+
+               $site->setPath( 'spam', 'http://www.wikidata.org/$1' );
+               $site->setPath( 'spam', 'http://www.wikidata.org/foo/$1' );
+               $site->setPath( 'foobar', 'http://www.wikidata.org/bar/$1' );
+
+               $this->assertEquals( $count + 2, count( $site->getAllPaths() ) );
+
+               $this->assertInternalType( 'string', $site->getPath( 'foobar' ) );
+               $this->assertEquals( 'http://www.wikidata.org/foo/$1', $site->getPath( 'spam' ) );
+
+               $site->removePath( 'spam' );
+               $site->removePath( 'foobar' );
+
+               $this->assertEquals( $count, count( $site->getAllPaths() ) );
+
+               $this->assertNull( $site->getPath( 'foobar' ) );
+               $this->assertNull( $site->getPath( 'spam' ) );
+       }
+
+       public function testSetLinkPath() {
+               $site = new Site();
+               $path = "TestPath/$1";
+
+               $site->setLinkPath( $path );
+               $this->assertEquals( $path, $site->getLinkPath() );
+       }
+
+       public function testGetLinkPathType() {
+               $site = new Site();
+
+               $path = 'TestPath/$1';
+               $site->setLinkPath( $path );
+               $this->assertEquals( $path, $site->getPath( $site->getLinkPathType() ) );
+
+               $path = 'AnotherPath/$1';
+               $site->setPath( $site->getLinkPathType(), $path );
+               $this->assertEquals( $path, $site->getLinkPath() );
+       }
+
+       public function testSetPath() {
+               $site = new Site();
+
+               $path = 'TestPath/$1';
+               $site->setPath( 'foo', $path );
+
+               $this->assertEquals( $path, $site->getPath( 'foo' ) );
+       }
+
+       public function testProtocolRelativePath() {
+               $site = new Site();
+
+               $type = $site->getLinkPathType();
+               $path = '//acme.com/'; // protocol-relative URL
+               $site->setPath( $type, $path );
+
+               $this->assertEquals( '', $site->getProtocol() );
+       }
+
+       public function provideGetPageUrl() {
+               //NOTE: the assumption that the URL is built by replacing $1
+               //      with the urlencoded version of $page
+               //      is true for Site but not guaranteed for subclasses.
+               //      Subclasses need to override this provider appropriately.
+
+               return array(
+                       array( #0
+                               'http://acme.test/TestPath/$1',
+                               'Foo',
+                               '/TestPath/Foo',
+                       ),
+                       array( #1
+                               'http://acme.test/TestScript?x=$1&y=bla',
+                               'Foo',
+                               'TestScript?x=Foo&y=bla',
+                       ),
+                       array( #2
+                               'http://acme.test/TestPath/$1',
+                               'foo & bar/xyzzy (quux-shmoox?)',
+                               '/TestPath/foo%20%26%20bar%2Fxyzzy%20%28quux-shmoox%3F%29',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provideGetPageUrl
+        */
+       public function testGetPageUrl( $path, $page, $expected ) {
+               $site = new Site();
+
+               //NOTE: the assumption that getPageUrl is based on getLinkPath
+               //      is true for Site but not guaranteed for subclasses.
+               //      Subclasses need to override this test case appropriately.
+               $site->setLinkPath( $path );
+               $this->assertContains( $path, $site->getPageUrl() );
+
+               $this->assertContains( $expected, $site->getPageUrl( $page ) );
+       }
+
+       protected function assertTypeOrFalse( $type, $value ) {
+               if ( $value === false ) {
+                       $this->assertTrue( true );
+               } else {
+                       $this->assertInternalType( $type, $value );
+               }
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSerialization( Site $site ) {
+               $this->assertInstanceOf( 'Serializable', $site );
+
+               $serialization = serialize( $site );
+               $newInstance = unserialize( $serialization );
+
+               $this->assertInstanceOf( 'Site', $newInstance );
+
+               $this->assertEquals( $serialization, serialize( $newInstance ) );
+       }
+
+}
diff --git a/tests/phpunit/includes/site/SitesTest.php b/tests/phpunit/includes/site/SitesTest.php
deleted file mode 100644 (file)
index 7675d42..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-/**
- * Tests for the Sites 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
- *
- * @file
- * @since 1.21
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- * @group Database
- *
- * @licence GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SitesTest extends MediaWikiTestCase {
-
-       public function setUp() {
-               parent::setUp();
-               TestSites::insertIntoDb();
-       }
-
-       public function testSingleton() {
-               $this->assertInstanceOf( 'Sites', Sites::singleton() );
-               $this->assertTrue( Sites::singleton() === Sites::singleton() );
-       }
-
-       public function testGetSites() {
-               $this->assertInstanceOf( 'SiteList', Sites::singleton()->getSites() );
-       }
-
-
-       public function testGetSite() {
-               $count = 0;
-               $sites = Sites::singleton()->getSites();
-
-               /**
-                * @var Site $site
-                */
-               foreach ( $sites as $site ) {
-                       $this->assertInstanceOf( 'Site', $site );
-
-                       $this->assertEquals(
-                               $site,
-                               Sites::singleton()->getSite( $site->getGlobalId() )
-                       );
-
-                       if ( ++$count > 100 ) {
-                               break;
-                       }
-               }
-       }
-
-       public function testNewSite() {
-               $this->assertInstanceOf( 'Site', Sites::newSite() );
-               $this->assertInstanceOf( 'Site', Sites::newSite( 'enwiki' ) );
-       }
-
-       public function testGetGroup() {
-               $wikipedias = Sites::singleton()->getSiteGroup( "wikipedia" );
-
-               $this->assertFalse( $wikipedias->isEmpty() );
-
-               /* @var Site $site */
-               foreach ( $wikipedias as $site ) {
-                       $this->assertEquals( 'wikipedia', $site->getGroup() );
-               }
-       }
-
-}
index 6003a8d..a5656a7 100644 (file)
@@ -39,21 +39,22 @@ class TestSites {
        public static function getSites() {
                $sites = array();
 
-               $site = Sites::newSite( 'foobar' );
+               $site = new Site();
+               $site->setGlobalId( 'foobar' );
                $sites[] = $site;
 
-               $site = Sites::newSite( 'enwiktionary' );
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'enwiktionary' );
                $site->setGroup( 'wiktionary' );
-               $site->setType( Site::TYPE_MEDIAWIKI );
                $site->setLanguageCode( 'en' );
                $site->addNavigationId( 'enwiktionary' );
                $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" );
                $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" );
                $sites[] = $site;
 
-               $site = Sites::newSite( 'dewiktionary' );
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'dewiktionary' );
                $site->setGroup( 'wiktionary' );
-               $site->setType( Site::TYPE_MEDIAWIKI );
                $site->setLanguageCode( 'de' );
                $site->addInterwikiId( 'dewiktionary' );
                $site->addInterwikiId( 'wiktionaryde' );
@@ -61,9 +62,9 @@ class TestSites {
                $site->setPath( MediaWikiSite::PATH_FILE, "https://de.wiktionary.org/w/$1" );
                $sites[] = $site;
 
-               $site = Sites::newSite( 'spam' );
+               $site = new Site();
+               $site->setGlobalId( 'spam' );
                $site->setGroup( 'spam' );
-               $site->setType( Site::TYPE_UNKNOWN );
                $site->setLanguageCode( 'en' );
                $site->addNavigationId( 'spam' );
                $site->addNavigationId( 'spamz' );
@@ -72,9 +73,9 @@ class TestSites {
                $sites[] = $site;
 
                foreach ( array( 'en', 'de', 'nl', 'sv', 'sr', 'no', 'nn' ) as $langCode ) {
-                       $site = Sites::newSite( $langCode . 'wiki' );
+                       $site = new MediaWikiSite();
+                       $site->setGlobalId( $langCode . 'wiki' );
                        $site->setGroup( 'wikipedia' );
-                       $site->setType( Site::TYPE_MEDIAWIKI );
                        $site->setLanguageCode( $langCode );
                        $site->addInterwikiId( $langCode );
                        $site->addNavigationId( $langCode );
@@ -92,23 +93,9 @@ class TestSites {
         * @since 0.1
         */
        public static function insertIntoDb() {
-               $dbw = wfGetDB( DB_MASTER );
-
-               $dbw->begin( __METHOD__ );
-
-               $dbw->delete( 'sites', '*', __METHOD__ );
-               $dbw->delete( 'site_identifiers', '*', __METHOD__ );
-
-               /**
-                * @var Site $site
-                */
-               foreach ( TestSites::getSites() as $site ) {
-                       $site->save();
-               }
-
-               $dbw->commit( __METHOD__ );
-
-               Sites::singleton()->getSites( false ); // re-cache
+               $sitesTable = SiteSQLStore::newInstance();
+               $sitesTable->clear();
+               $sitesTable->saveSites( TestSites::getSites() );
        }
 
-}
\ No newline at end of file
+}
index a33c7b6..3b82e07 100644 (file)
@@ -39,9 +39,9 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
                parent::__construct();
 
                global $wgQueryPages;
-               foreach( $wgQueryPages as $page ) {
+               foreach ( $wgQueryPages as $page ) {
                        $class = $page[0];
-                       if( ! in_array( $class, $this->manualTest ) ) {
+                       if ( !in_array( $class, $this->manualTest ) ) {
                                $this->queryPages[$class] = new $class;
                        }
                }
@@ -54,22 +54,22 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
        function testQuerypageSqlQuery() {
                global $wgDBtype;
 
-               foreach( $this->queryPages as $page ) {
+               foreach ( $this->queryPages as $page ) {
 
                        // With MySQL, skips special pages reopening a temporary table
                        // See http://bugs.mysql.com/bug.php?id=10327
-                       if(
+                       if (
                                $wgDBtype === 'mysql'
                                && in_array( $page->getName(), $this->reopensTempTable )
                        ) {
-                                       $this->markTestSkipped( "SQL query for page {$page->getName()} can not be tested on MySQL backend (it reopens a temporary table)" );
-                                       continue;
-                               }
+                               $this->markTestSkipped( "SQL query for page {$page->getName()} can not be tested on MySQL backend (it reopens a temporary table)" );
+                               continue;
+                       }
 
-                       $msg = "SQL query for page {$page->getName()} should give a result wrapper object" ;
+                       $msg = "SQL query for page {$page->getName()} should give a result wrapper object";
 
                        $result = $page->reallyDoQuery( 50 );
-                       if( $result instanceof ResultWrapper ) {
+                       if ( $result instanceof ResultWrapper ) {
                                $this->assertTrue( true, $msg );
                        } else {
                                $this->assertFalse( false, $msg );
index 82426bd..add830b 100644 (file)
@@ -41,7 +41,7 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
 
        /** return false if condition begin with 'rc_timestamp ' */
        private static function filterOutRcTimestampCondition( $var ) {
-               return (false === strpos( $var, 'rc_timestamp ' ));
+               return ( false === strpos( $var, 'rc_timestamp ' ) );
 
        }
 
@@ -70,7 +70,7 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
                                'namespace' => NS_MAIN,
                                'invert' => 1,
                        ),
-                 "rc conditions with namespace inverted"
+                       "rc conditions with namespace inverted"
                );
        }
 
@@ -89,7 +89,7 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
                                'namespace' => $ns1,
                                'associated' => 1,
                        ),
-                 "rc conditions with namespace inverted"
+                       "rc conditions with namespace inverted"
                );
        }
 
@@ -105,11 +105,11 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
                                1 => sprintf( "(rc_namespace != '%s' AND rc_namespace != '%s')", $ns1, $ns2 ),
                        ),
                        array(
-                               'namespace'  => $ns1,
+                               'namespace' => $ns1,
                                'associated' => 1,
-                               'invert'     => 1,
+                               'invert' => 1,
                        ),
-                 "rc conditions with namespace inverted"
+                       "rc conditions with namespace inverted"
                );
        }
 
@@ -119,11 +119,9 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
         */
        public static function provideNamespacesAssociations() {
                return array( # (NS => Associated_NS)
-                       array( NS_MAIN, NS_TALK),
-                       array( NS_TALK, NS_MAIN),
+                       array( NS_MAIN, NS_TALK ),
+                       array( NS_TALK, NS_MAIN ),
                );
        }
 
 }
-
-
index 9d7dc71..f5ef0fb 100644 (file)
@@ -32,7 +32,7 @@ class SpecialSearchTest extends MediaWikiTestCase {
                        'ns6'=>true,
                ) ));
                 */
-               $context->setRequest( new FauxRequest( $requested ));
+               $context->setRequest( new FauxRequest( $requested ) );
                $search = new SpecialSearch();
                $search->setContext( $context );
                $search->load();
@@ -45,11 +45,11 @@ class SpecialSearchTest extends MediaWikiTestCase {
                $this->assertEquals(
                        array( /** Expected: */
                                'ProfileName' => $expectedProfile,
-                               'Namespaces'  => $expectedNS,
+                               'Namespaces' => $expectedNS,
                        )
                        , array( /** Actual: */
                                'ProfileName' => $search->getProfile(),
-                               'Namespaces'  => $search->getNamespaces(),
+                               'Namespaces' => $search->getNamespaces(),
                        )
                        , $message
                );
@@ -59,14 +59,14 @@ class SpecialSearchTest extends MediaWikiTestCase {
        function provideSearchOptionsTests() {
                $defaultNS = SearchEngine::defaultNamespaces();
                $EMPTY_REQUEST = array();
-               $NO_USER_PREF  = null;
+               $NO_USER_PREF = null;
 
                return array(
                        /**
                         * Parameters:
-                        *      <Web Request>, <User options>
+                        *     <Web Request>, <User options>
                         * Followed by expected values:
-                        *      <ProfileName>, <NSList>
+                        *     <ProfileName>, <NSList>
                         * Then an optional message.
                         */
                        array(
@@ -76,19 +76,19 @@ class SpecialSearchTest extends MediaWikiTestCase {
                        ),
                        array(
                                array( 'ns5' => 1 ), $NO_USER_PREF,
-                               'advanced', array(  5),
+                               'advanced', array( ),
                                'Web request with specific NS should override user preference'
                        ),
                        array(
                                $EMPTY_REQUEST, array(
-                                       'searchNs2' => 1,
-                                       'searchNs14' => 1,
-                               ) + array_fill_keys( array_map( function( $ns ) {
-                                       return "searchNs$ns";
-                               }, $defaultNS ), 0 ),
+                               'searchNs2' => 1,
+                               'searchNs14' => 1,
+                       ) + array_fill_keys( array_map( function ( $ns ) {
+                               return "searchNs$ns";
+                       }, $defaultNS ), 0 ),
                                'advanced', array( 2, 14 ),
                                'Bug 33583: search with no option should honor User search preferences'
-                               . ' and have all other namespace disabled'
+                                       . ' and have all other namespace disabled'
                        ),
                );
        }
@@ -98,11 +98,11 @@ class SpecialSearchTest extends MediaWikiTestCase {
         * User remains anonymous though
         */
        function newUserWithSearchNS( $opt = null ) {
-               $u = User::newFromId(0);
-               if( $opt === null ) {
+               $u = User::newFromId( 0 );
+               if ( $opt === null ) {
                        return $u;
                }
-               foreach($opt as $name => $value) {
+               foreach ( $opt as $name => $value ) {
                        $u->setOption( $name, $value );
                }
                return $u;
@@ -116,7 +116,7 @@ class SpecialSearchTest extends MediaWikiTestCase {
 
                # Initialize [[Special::Search]]
                $search = new SpecialSearch();
-               $search->getContext()->setTitle( Title::newFromText('Special:Search' ) );
+               $search->getContext()->setTitle( Title::newFromText( 'Special:Search' ) );
                $search->load();
 
                # Simulate a user searching for a given term
@@ -138,4 +138,3 @@ class SpecialSearchTest extends MediaWikiTestCase {
 
        }
 }
-
index a693cdb..4d2d8ce 100644 (file)
@@ -336,7 +336,7 @@ class UploadFromUrlTest extends ApiTestCase {
         */
        protected function deleteFile( $name ) {
                $t = Title::newFromText( $name, NS_FILE );
-               $this->assertTrue($t->exists(), "File '$name' exists");
+               $this->assertTrue( $t->exists(), "File '$name' exists" );
 
                if ( $t->exists() ) {
                        $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) );
@@ -347,6 +347,6 @@ class UploadFromUrlTest extends ApiTestCase {
                }
                $t = Title::newFromText( $name, NS_FILE );
 
-               $this->assertFalse($t->exists(), "File '$name' was deleted");
+               $this->assertFalse( $t->exists(), "File '$name' was deleted" );
        }
- }
+}
index 857aef5..8fcaa21 100644 (file)
@@ -59,19 +59,19 @@ class UploadStashTest extends MediaWikiTestCase {
        }
 
        public function testValidRequest() {
-               $request = new FauxRequest( array( 'wpFileKey' => 'foo') );
-               $this->assertFalse( UploadFromStash::isValidRequest($request), 'Check failure on bad wpFileKey' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'foo' ) );
+               $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpFileKey' );
 
-               $request = new FauxRequest( array( 'wpSessionKey' => 'foo') );
-               $this->assertFalse( UploadFromStash::isValidRequest($request), 'Check failure on bad wpSessionKey' );
+               $request = new FauxRequest( array( 'wpSessionKey' => 'foo' ) );
+               $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpSessionKey' );
 
-               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test') );
-               $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check good wpFileKey' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) );
+               $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpFileKey' );
 
-               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test') );
-               $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check good wpSessionKey' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) );
+               $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpSessionKey' );
 
-               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test', 'wpSessionKey' => 'foo') );
-               $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check key precedence' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test', 'wpSessionKey' => 'foo' ) );
+               $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check key precedence' );
        }
 }
index 34c57aa..b809d32 100644 (file)
@@ -12,7 +12,7 @@ class UploadTest extends MediaWikiTestCase {
 
                $this->upload = new UploadTestHandler;
                $this->hooks = $wgHooks;
-               $wgHooks['InterwikiLoadPrefix'][] = function( $prefix, &$data ) {
+               $wgHooks['InterwikiLoadPrefix'][] = function ( $prefix, &$data ) {
                        return false;
                };
        }
@@ -28,7 +28,7 @@ class UploadTest extends MediaWikiTestCase {
        /**
         * First checks the return code
         * of UploadBase::getTitle() and then the actual returned title
-        * 
+        *
         * @dataProvider provideTestTitleValidation
         */
        public function testTitleValidation( $srcFilename, $dstFilename, $code, $msg ) {
@@ -44,38 +44,38 @@ class UploadTest extends MediaWikiTestCase {
                                "$msg text" );
                }
        }
-       
+
        /**
         * Test various forms of valid and invalid titles that can be supplied.
         */
        public static function provideTestTitleValidation() {
                return array(
                        /* Test a valid title */
-                       array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK, 
+                       array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK,
                                'upload valid title' ),
                        /* A title with a slash */
-                       array( 'A/B.jpg', 'B.jpg', UploadBase::OK, 
+                       array( 'A/B.jpg', 'B.jpg', UploadBase::OK,
                                'upload title with slash' ),
                        /* A title with illegal char */
-                       array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK, 
+                       array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK,
                                'upload title with colon' ),
                        /* Stripping leading File: prefix */
-                       array( 'File:C.jpg', 'C.jpg', UploadBase::OK, 
+                       array( 'File:C.jpg', 'C.jpg', UploadBase::OK,
                                'upload title with File prefix' ),
                        /* Test illegal suggested title (r94601) */
-                       array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME, 
+                       array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME,
                                'illegal title for upload' ),
                        /* A title without extension */
-                       array( 'A', null, UploadBase::FILETYPE_MISSING, 
+                       array( 'A', null, UploadBase::FILETYPE_MISSING,
                                'upload title without extension' ),
                        /* A title with no basename */
-                       array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME, 
+                       array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME,
                                'upload title without basename' ),
                        /* A title that is longer than 255 bytes */
-                       array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, 
+                       array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG,
                                'upload title longer than 255 bytes' ),
                        /* A title that is longer than 240 bytes */
-                       array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, 
+                       array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG,
                                'upload title longer than 240 bytes' ),
                );
        }
@@ -118,26 +118,27 @@ class UploadTest extends MediaWikiTestCase {
                $wgMaxUploadSize = 100;
 
                $filename = $this->createFileOfSize( $wgMaxUploadSize );
-               $this->upload->initializePathInfo( basename($filename) . '.txt', $filename, 100 );
+               $this->upload->initializePathInfo( basename( $filename ) . '.txt', $filename, 100 );
                $result = $this->upload->verifyUpload();
                unlink( $filename );
 
                $this->assertEquals(
                        array( 'status' => UploadBase::OK ), $result );
 
-               $wgMaxUploadSize = $savedGlobal;  // restore global
+               $wgMaxUploadSize = $savedGlobal; // restore global
        }
 }
 
 class UploadTestHandler extends UploadBase {
-               public function initializeFromRequest( &$request ) { }
-               public function testTitleValidation( $name ) {
-                       $this->mTitle = false;
-                       $this->mDesiredDestName = $name;
-                       $this->mTitleError = UploadBase::OK;
-                       $this->getTitle();
-                       return $this->mTitleError;
-               }
+       public function initializeFromRequest( &$request ) {}
+
+       public function testTitleValidation( $name ) {
+               $this->mTitle = false;
+               $this->mDesiredDestName = $name;
+               $this->mTitleError = UploadBase::OK;
+               $this->getTitle();
+               return $this->mTitleError;
+       }
 
 
 }
index 16215c5..9723e1e 100644 (file)
@@ -10,12 +10,12 @@ class LanguageAmTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 17f7352..523ee7f 100644 (file)
@@ -44,13 +44,15 @@ class LanguageArTest extends LanguageClassesTestCase {
                        ),
                );
        }
+
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'zero', 'one', 'two', 'few', 'many', 'other' );
+               $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providePlural() {
-               return array (
+               return array(
                        array( 'zero', 0 ),
                        array( 'one', 1 ),
                        array( 'two', 2 ),
index 06ee240..0144941 100644 (file)
@@ -10,12 +10,12 @@ class LanguageBeTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
index ad0ef43..5b246d8 100644 (file)
@@ -21,23 +21,26 @@ class LanguageBe_taraskTest extends LanguageClassesTestCase {
                        'bug 23156: U+2019 conversion to U+0027'
                );
        }
+
        /** see bug 23156 & r64981 */
        function testCommafy() {
                $this->assertEquals( '1,234,567', $this->getLang()->commafy( '1234567' ) );
-               $this->assertEquals(    '12,345', $this->getLang()->commafy(   '12345' ) );
+               $this->assertEquals( '12,345', $this->getLang()->commafy( '12345' ) );
        }
+
        /** see bug 23156 & r64981 */
        function testDoesNotCommafyFourDigitsNumber() {
-               $this->assertEquals(      '1234', $this->getLang()->commafy(    '1234' ) );
+               $this->assertEquals( '1234', $this->getLang()->commafy( '1234' ) );
        }
+
        /** @dataProvider providePluralFourForms */
        function testPluralFourForms( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -51,13 +54,15 @@ class LanguageBe_taraskTest extends LanguageClassesTestCase {
                        array( 'many', 120 ),
                );
        }
+
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
-               $forms =  array( 'one', 'several' );
+               $forms = array( 'one', 'several' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providePluralTwoForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'several', 11 ),
                        array( 'several', 91 ),
index 5bbd4fe..c364917 100644 (file)
@@ -10,12 +10,12 @@ class LanguageBhoTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index dd00428..76d0070 100644 (file)
@@ -10,12 +10,12 @@ class LanguageBsTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'many', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index 4f0a37f..6659dad 100644 (file)
@@ -32,7 +32,7 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase {
        /**
         * Regex used to find out the language code out of the class name
         * used by setUpBeforeClass
-       */
+        */
        private static $reExtractLangFromClass = '/Language(.*)Test/';
 
        /**
@@ -68,7 +68,7 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase {
                        $m[1] = 'en';
                        wfDebug(
                                __METHOD__ . " could not extract a language name "
-                               . "out of " . get_called_class() . " failling back to 'en'\n"
+                                       . "out of " . get_called_class() . " failling back to 'en'\n"
                        );
                }
                // TODO: validate $m[1] which should be a valid language code
index 72c9e79..884a129 100644 (file)
@@ -10,12 +10,12 @@ class LanguageCsTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index 95f8da7..e2394b3 100644 (file)
@@ -10,12 +10,12 @@ class LanguageCuTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index de6ba5c..2a7f4a9 100644 (file)
@@ -10,12 +10,12 @@ class LanguageCyTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'zero', 'one', 'two', 'few', 'many', 'other' );
+               $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'zero', 0 ),
                        array( 'one', 1 ),
                        array( 'two', 2 ),
index 8fb6024..285ce64 100644 (file)
@@ -10,12 +10,12 @@ class LanguageDsbTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'two', 'few', 'other' );
+               $forms = array( 'one', 'two', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'one', 101 ),
index 05de960..faf0de5 100644 (file)
@@ -10,12 +10,12 @@ class LanguageFrTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 0a54592..2dbb088 100644 (file)
@@ -10,12 +10,12 @@ class LanguageGaTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'two', 'other' );
+               $forms = array( 'one', 'two', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'two', 2 ),
index 7831cd2..409820f 100644 (file)
@@ -11,11 +11,12 @@ class LanguageGdTest extends LanguageClassesTestCase {
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
                // The CLDR ticket for this plural forms is not same as mw plural forms. See http://unicode.org/cldr/trac/ticket/2883
-               $forms =  array( 'Form 1', 'Form 2', 'Form 3', 'Form 4', 'Form 5', 'Form 6' );
+               $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4', 'Form 5', 'Form 6' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providerPlural() {
-               return array (
+               return array(
                        array( 'Form 6', 0 ),
                        array( 'Form 1', 1 ),
                        array( 'Form 2', 2 ),
index 0edff59..4126e07 100644 (file)
@@ -11,11 +11,12 @@ class LanguageGvTest extends LanguageClassesTestCase {
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
                // This is not compatible with CLDR plural rules http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#gv
-               $forms =  array( 'Form 1', 'Form 2', 'Form 3', 'Form 4' );
+               $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providerPlural() {
-               return array (
+               return array(
                        array( 'Form 4', 0 ),
                        array( 'Form 2', 1 ),
                        array( 'Form 3', 2 ),
index 575b277..6de88e5 100644 (file)
@@ -15,7 +15,7 @@ class LanguageHeTest extends LanguageClassesTestCase {
        }
 
        function providerPluralDual() {
-               return array (
+               return array(
                        array( 'other', 0 ), // Zero -> plural
                        array( 'one', 1 ), // Singular
                        array( 'two', 2 ), // Dual
@@ -30,7 +30,7 @@ class LanguageHeTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ), // Zero -> plural
                        array( 'one', 1 ), // Singular
                        array( 'other', 2 ), // Plural, no dual provided
@@ -46,7 +46,7 @@ class LanguageHeTest extends LanguageClassesTestCase {
        // The comments in the beginning of the line help avoid RTL problems
        // with text editors.
        function providerGrammar() {
-               return array (
+               return array(
                        array(
                                /* result */ 'וויקיפדיה',
                                /* word   */ 'ויקיפדיה',
index 5a780a2..86d6af5 100644 (file)
@@ -10,12 +10,12 @@ class LanguageHiTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 748aaf4..9dce4ea 100644 (file)
@@ -10,12 +10,12 @@ class LanguageHrTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'many', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index 2d90ef0..bec7d81 100644 (file)
@@ -10,12 +10,12 @@ class LanguageHsbTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'two', 'few', 'other' );
+               $forms = array( 'one', 'two', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'one', 101 ),
index e01278b..23d8e0c 100644 (file)
@@ -15,7 +15,7 @@ class LanguageHuTest extends LanguageClassesTestCase {
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index ea6e255..7088d37 100644 (file)
@@ -10,13 +10,13 @@ class LanguageHyTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one', 0 ),
+               return array(
+                       array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 200 ),
index e92d264..9b4a53a 100644 (file)
@@ -10,12 +10,12 @@ class LanguageKshTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array(  'one', 'other', 'zero' );
+               $forms = array( 'one', 'other', 'zero' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'zero', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 8853caa..669d8b0 100644 (file)
@@ -10,12 +10,12 @@ class LanguageLnTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 485a090..9d6428b 100644 (file)
@@ -10,18 +10,18 @@ class LanguageLtTest extends LanguageClassesTestCase {
 
        /** @dataProvider provideOneFewOtherCases */
        function testOneFewOtherPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
-       
+
        /** @dataProvider provideOneFewCases */
        function testOneFewPlural( $result, $value ) {
-               $forms =  array( 'one', 'few' );
+               $forms = array( 'one', 'few' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function provideOneFewOtherCases() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
@@ -35,9 +35,9 @@ class LanguageLtTest extends LanguageClassesTestCase {
                        array( 'one', 40001 ),
                );
        }
-       
+
        function provideOneFewCases() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'few', 15 ),
                );
index bf4f793..efb6de6 100644 (file)
@@ -10,12 +10,12 @@ class LanguageLvTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ), #this must be zero form as per CLDR
                        array( 'one', 1 ),
                        array( 'other', 11 ),
index d6d3de9..c1e516b 100644 (file)
@@ -10,12 +10,12 @@ class LanguageMgTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 8cd84b8..5c241ba 100644 (file)
@@ -10,13 +10,13 @@ class LanguageMkTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 11 ),
index b7f6182..396114d 100644 (file)
@@ -9,17 +9,17 @@
 class LanguageMlTest extends LanguageClassesTestCase {
 
        /** see bug 29495 */
-       /** @dataProvider providerFormatNum*/
+       /** @dataProvider providerFormatNum */
        function testFormatNum( $result, $value ) {
-               $this->assertEquals( $result,  $this->getLang()->formatNum( $value ) );
+               $this->assertEquals( $result, $this->getLang()->formatNum( $value ) );
        }
 
        function providerFormatNum() {
                return array(
-                       array( '12,34,567', '1234567'  ),
+                       array( '12,34,567', '1234567' ),
                        array( '12,345', '12345' ),
                        array( '1', '1' ),
-                       array( '123', '123' ) ,
+                       array( '123', '123' ),
                        array( '1,234', '1234' ),
                        array( '12,345.56', '12345.56' ),
                        array( '12,34,56,79,81,23,45,678', '12345679812345678' ),
@@ -27,7 +27,7 @@ class LanguageMlTest extends LanguageClassesTestCase {
                        array( '-12,00,000', '-1200000' ),
                        array( '-98', '-98' ),
                        array( '-98', -98 ),
-                       array( '-1,23,45,678',  -12345678 ),
+                       array( '-1,23,45,678', -12345678 ),
                        array( '', '' ),
                        array( '', null ),
                );
index 491d8ac..f7da1cd 100644 (file)
@@ -10,25 +10,25 @@ class LanguageMoTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
-                       array( 'few',   0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   19 ),
+               return array(
+                       array( 'few', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
-                       array( 'few',   101 ),
-                       array( 'few',   119 ),
+                       array( 'few', 101 ),
+                       array( 'few', 119 ),
                        array( 'other', 120 ),
                        array( 'other', 200 ),
-                       array( 'few',   201 ),
-                       array( 'few',   219 ),
+                       array( 'few', 201 ),
+                       array( 'few', 219 ),
                        array( 'other', 220 ),
                );
        }
index 70cd93a..f2b881e 100644 (file)
@@ -15,21 +15,21 @@ class LanguageMtTest extends LanguageClassesTestCase {
        }
 
        function providerPluralAllForms() {
-               return array (
-                       array( 'few',   0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  19 ),
+               return array(
+                       array( 'few', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
                        array( 'other', 101 ),
-                       array( 'few',   102 ),
-                       array( 'few',   110 ),
-                       array( 'many',  111 ),
-                       array( 'many',  119 ),
+                       array( 'few', 102 ),
+                       array( 'few', 110 ),
+                       array( 'many', 111 ),
+                       array( 'many', 119 ),
                        array( 'other', 120 ),
                        array( 'other', 201 ),
                );
@@ -42,23 +42,23 @@ class LanguageMtTest extends LanguageClassesTestCase {
        }
 
        function providerPluralTwoForms() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'many',  2 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  19 ),
-                       array( 'many',  20 ),
-                       array( 'many',  99 ),
-                       array( 'many',  100 ),
-                       array( 'many',  101 ),
-                       array( 'many',  102 ),
-                       array( 'many',  110 ),
-                       array( 'many',  111 ),
-                       array( 'many',  119 ),
-                       array( 'many',  120 ),
-                       array( 'many',  201 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'many', 2 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 19 ),
+                       array( 'many', 20 ),
+                       array( 'many', 99 ),
+                       array( 'many', 100 ),
+                       array( 'many', 101 ),
+                       array( 'many', 102 ),
+                       array( 'many', 110 ),
+                       array( 'many', 111 ),
+                       array( 'many', 119 ),
+                       array( 'many', 120 ),
+                       array( 'many', 201 ),
                );
        }
 }
index 97146d3..9d80d13 100644 (file)
@@ -15,9 +15,9 @@ class LanguageNsoTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index 00b7e9e..1e36097 100644 (file)
@@ -15,23 +15,23 @@ class LanguagePlTest extends LanguageClassesTestCase {
        }
 
        function providerPluralFourForms() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   3 ),
-                       array( 'few',   4 ),
-                       array( 'many',  5 ),
-                       array( 'many',  9 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  21 ),
-                       array( 'few',   22 ),
-                       array( 'few',   23 ),
-                       array( 'few',   24 ),
-                       array( 'many',  25 ),
-                       array( 'many',  200 ),
-                       array( 'many',  201 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 3 ),
+                       array( 'few', 4 ),
+                       array( 'many', 5 ),
+                       array( 'many', 9 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 21 ),
+                       array( 'few', 22 ),
+                       array( 'few', 23 ),
+                       array( 'few', 24 ),
+                       array( 'many', 25 ),
+                       array( 'many', 200 ),
+                       array( 'many', 201 ),
                );
        }
 
@@ -42,23 +42,23 @@ class LanguagePlTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'many',  2 ),
-                       array( 'many',  3 ),
-                       array( 'many',  4 ),
-                       array( 'many',  5 ),
-                       array( 'many',  9 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  21 ),
-                       array( 'many',  22 ),
-                       array( 'many',  23 ),
-                       array( 'many',  24 ),
-                       array( 'many',  25 ),
-                       array( 'many',  200 ),
-                       array( 'many',  201 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'many', 2 ),
+                       array( 'many', 3 ),
+                       array( 'many', 4 ),
+                       array( 'many', 5 ),
+                       array( 'many', 9 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 21 ),
+                       array( 'many', 22 ),
+                       array( 'many', 23 ),
+                       array( 'many', 24 ),
+                       array( 'many', 25 ),
+                       array( 'many', 200 ),
+                       array( 'many', 201 ),
                );
        }
 }
index 61726bc..916ea45 100644 (file)
@@ -10,25 +10,25 @@ class LanguageRoTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
-                       array( 'few',   0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   19 ),
+               return array(
+                       array( 'few', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
-                       array( 'few',   101 ),
-                       array( 'few',   119 ),
+                       array( 'few', 101 ),
+                       array( 'few', 119 ),
                        array( 'other', 120 ),
                        array( 'other', 200 ),
-                       array( 'few',   201 ),
-                       array( 'few',   219 ),
+                       array( 'few', 201 ),
+                       array( 'few', 219 ),
                        array( 'other', 220 ),
                );
        }
index f545a13..0792f75 100644 (file)
@@ -16,7 +16,7 @@ class LanguageRuTest extends LanguageClassesTestCase {
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -30,17 +30,49 @@ class LanguageRuTest extends LanguageClassesTestCase {
                        array( 'many', 120 ),
                );
        }
+
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
-               $forms =  array( 'one', 'several' );
+               $forms = array( 'one', 'several' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providePluralTwoForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'several', 11 ),
                        array( 'several', 91 ),
                        array( 'several', 121 ),
                );
        }
+
+       /** @dataProvider providerGrammar */
+       function testGrammar( $result, $word, $case ) {
+               $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) );
+       }
+
+       function providerGrammar() {
+               return array(
+                       array(
+                               'Википедии',
+                               'Википедия',
+                               'genitive',
+                       ),
+                       array(
+                               'Викитеки',
+                               'Викитека',
+                               'genitive',
+                       ),
+                       array(
+                               'Викитеке',
+                               'Викитека',
+                               'prepositional',
+                       ),
+                       array(
+                               'Викиданных',
+                               'Викиданные',
+                               'prepositional',
+                       ),
+               );
+       }
 }
index cf76353..c7dd802 100644 (file)
@@ -15,10 +15,10 @@ class LanguageSeTest extends LanguageClassesTestCase {
        }
 
        function providerPluralThreeForms() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
-                       array( 'two',   2 ),
+                       array( 'one', 1 ),
+                       array( 'two', 2 ),
                        array( 'other', 3 ),
                );
        }
@@ -30,9 +30,9 @@ class LanguageSeTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
+                       array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 3 ),
                );
index e2a56ca..8a6e979 100644 (file)
@@ -15,33 +15,33 @@ class LanguageSgsTest extends LanguageClassesTestCase {
        }
 
        function providePluralAllForms() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
                        array( 'other', 3 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  12 ),
-                       array( 'many',  19 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 12 ),
+                       array( 'many', 19 ),
                        array( 'other', 20 ),
-                       array( 'many',  100 ),
-                       array( 'one',   101 ),
-                       array( 'many',  111 ),
-                       array( 'many',  112 ),
+                       array( 'many', 100 ),
+                       array( 'one', 101 ),
+                       array( 'many', 111 ),
+                       array( 'many', 112 ),
                );
        }
 
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePluralTwoForms() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
+                       array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 3 ),
                        array( 'other', 10 ),
@@ -50,7 +50,7 @@ class LanguageSgsTest extends LanguageClassesTestCase {
                        array( 'other', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 100 ),
-                       array( 'one',   101 ),
+                       array( 'one', 101 ),
                        array( 'other', 111 ),
                        array( 'other', 112 ),
                );
index 25618c4..282fd2f 100644 (file)
@@ -15,9 +15,9 @@ class LanguageShTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'many', 0 ),
-                       array( 'one',  1 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index b50f7df..89cbbf0 100644 (file)
@@ -16,7 +16,7 @@ class LanguageSkTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index bfb7c7e..075e6af 100644 (file)
@@ -16,19 +16,19 @@ class LanguageSlTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'zero',  0 ),
-                       array( 'one',   1 ),
-                       array( 'two',   2 ),
-                       array( 'few',   3 ),
-                       array( 'few',   4 ),
+               return array(
+                       array( 'zero', 0 ),
+                       array( 'one', 1 ),
+                       array( 'two', 2 ),
+                       array( 'few', 3 ),
+                       array( 'few', 4 ),
                        array( 'other', 5 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
-                       array( 'one',   101 ),
-                       array( 'two',   102 ),
-                       array( 'few',   103 ),
-                       array( 'one',   201 ),
+                       array( 'one', 101 ),
+                       array( 'two', 102 ),
+                       array( 'few', 103 ),
+                       array( 'one', 201 ),
                );
        }
 }
index 85fa9fb..6d65521 100644 (file)
@@ -15,10 +15,10 @@ class LanguageSmaTest extends LanguageClassesTestCase {
        }
 
        function providerPluralThreeForms() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
-                       array( 'two',   2 ),
+                       array( 'one', 1 ),
+                       array( 'two', 2 ),
                        array( 'other', 3 ),
                );
        }
@@ -30,9 +30,9 @@ class LanguageSmaTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
+                       array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 3 ),
                );
index c88115d..5611030 100644 (file)
@@ -19,7 +19,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
 
        ##### TESTS #######################################################
 
-       function testEasyConversions( ) {
+       function testEasyConversions() {
                $this->assertCyrillic(
                        'шђчћжШЂЧЋЖ',
                        'Cyrillic guessing characters'
@@ -120,7 +120,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -134,13 +134,15 @@ class LanguageSrTest extends LanguageClassesTestCase {
                        array( 'many', 120 ),
                );
        }
+
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
                $forms = array( 'one', 'several' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providePluralTwoForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'several', 11 ),
                        array( 'several', 91 ),
@@ -162,6 +164,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
                        $msg
                );
        }
+
        /**
         * Wrapper to verify a text is different once converted to a variant.
         * @param $text string Text to convert
@@ -185,6 +188,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
                $this->assertUnConverted( $text, 'sr-ec', $msg );
                $this->assertConverted( $text, 'sr-el', $msg );
        }
+
        /**
         * Verifiy the given Latin text is not converted when using
         * using the Latin variant and converted to Cyrillic when using
@@ -201,12 +205,14 @@ class LanguageSrTest extends LanguageClassesTestCase {
                return $this->getLang()
                        ->mConverter
                        ->convertTo(
-                               $text, $variant
-                       );
+                       $text, $variant
+               );
        }
+
        function convertToCyrillic( $text ) {
                return $this->convertTo( $text, 'sr-ec' );
        }
+
        function convertToLatin( $text ) {
                return $this->convertTo( $text, 'sr-el' );
        }
index 785c21c..3c9ca23 100644 (file)
@@ -307,36 +307,198 @@ class LanguageTest extends LanguageClassesTestCase {
                );
        }
 
+       /**
+        * Test Language::isWellFormedLanguageTag()
+        * @dataProvider provideWellFormedLanguageTags
+        */
+       function testWellFormedLanguageTag( $code, $message = '' ) {
+               $this->assertTrue(
+                       Language::isWellFormedLanguageTag( $code ),
+                       "validating code $code $message"
+               );
+       }
+
+       /**
+        * The test cases are based on the tests in the GaBuZoMeu parser
+        * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr>
+        * and distributed as free software, under the GNU General Public Licence.
+        * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html
+        */
+       function provideWellFormedLanguageTags() {
+               return array(
+                       array( 'fr', 'two-letter code' ),
+                       array( 'fr-latn', 'two-letter code with lower case script code' ),
+                       array( 'fr-Latn-FR', 'two-letter code with title case script code and uppercase country code' ),
+                       array( 'fr-Latn-419', 'two-letter code with title case script code and region number' ),
+                       array( 'fr-FR', 'two-letter code with uppercase' ),
+                       array( 'ax-TZ', 'Not in the registry, but well-formed' ),
+                       array( 'fr-shadok', 'two-letter code with variant' ),
+                       array( 'fr-y-myext-myext2', 'non-x singleton' ),
+                       array( 'fra-Latn', 'ISO 639 can be 3-letters' ),
+                       array( 'fra', 'three-letter language code' ),
+                       array( 'fra-FX', 'three-letter language code with country code' ),
+                       array( 'i-klingon', 'grandfathered with singleton' ),
+                       array( 'I-kLINgon', 'tags are case-insensitive...' ),
+                       array( 'no-bok', 'grandfathered without singleton' ),
+                       array( 'i-enochian', 'Grandfathered' ),
+                       array( 'x-fr-CH', 'private use' ),
+                       array( 'es-419', 'two-letter code with region number' ),
+                       array( 'en-Latn-GB-boont-r-extended-sequence-x-private', 'weird, but well-formed' ),
+                       array( 'ab-x-abc-x-abc', 'anything goes after x' ),
+                       array( 'ab-x-abc-a-a', 'anything goes after x, including several non-x singletons' ),
+                       array( 'i-default', 'grandfathered' ),
+                       array( 'abcd-Latn', 'Language of 4 chars reserved for future use' ),
+                       array( 'AaBbCcDd-x-y-any-x', 'Language of 5-8 chars, registered' ),
+                       array( 'de-CH-1901', 'with country and year' ),
+                       array( 'en-US-x-twain', 'with country and singleton' ),
+                       array( 'zh-cmn', 'three-letter variant' ),
+                       array( 'zh-cmn-Hant', 'three-letter variant and script' ),
+                       array( 'zh-cmn-Hant-HK', 'three-letter variant, script and country' ),
+                       array( 'xr-p-lze', 'Extension' ),
+               );
+       }
+
+       /**
+        * Negative test for Language::isWellFormedLanguageTag()
+        * @dataProvider provideMalformedLanguageTags
+        */
+       function testMalformedLanguageTag( $code, $message = '' ) {
+               $this->assertFalse(
+                       Language::isWellFormedLanguageTag( $code ),
+                       "validating that code $code is a malformed language tag - $message"
+               );
+       }
+
+       /**
+        * The test cases are based on the tests in the GaBuZoMeu parser
+        * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr>
+        * and distributed as free software, under the GNU General Public Licence.
+        * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html
+        */
+       function provideMalformedLanguageTags() {
+               return array(
+                       array( 'f', 'language too short' ),
+                       array( 'f-Latn', 'language too short with script' ),
+                       array( 'xr-lxs-qut', 'variants too short' ), # extlangS
+                       array( 'fr-Latn-F', 'region too short' ),
+                       array( 'a-value', 'language too short with region' ),
+                       array( 'tlh-a-b-foo', 'valid three-letter with wrong variant' ),
+                       array( 'i-notexist', 'grandfathered but not registered: invalid, even if we only test well-formedness' ),
+                       array( 'abcdefghi-012345678', 'numbers too long' ),
+                       array( 'ab-abc-abc-abc-abc', 'invalid extensions' ),
+                       array( 'ab-abcd-abc', 'invalid extensions' ),
+                       array( 'ab-ab-abc', 'invalid extensions' ),
+                       array( 'ab-123-abc', 'invalid extensions' ),
+                       array( 'a-Hant-ZH', 'short language with valid extensions' ),
+                       array( 'a1-Hant-ZH', 'invalid character in language' ),
+                       array( 'ab-abcde-abc', 'invalid extensions' ),
+                       array( 'ab-1abc-abc', 'invalid characters in extensions' ),
+                       array( 'ab-ab-abcd', 'invalid order of extensions' ),
+                       array( 'ab-123-abcd', 'invalid order of extensions' ),
+                       array( 'ab-abcde-abcd', 'invalid extensions' ),
+                       array( 'ab-1abc-abcd', 'invalid characters in extensions' ),
+                       array( 'ab-a-b', 'extensions too short' ),
+                       array( 'ab-a-x', 'extensions too short, even with singleton' ),
+                       array( 'ab--ab', 'two separators' ),
+                       array( 'ab-abc-', 'separator in the end' ),
+                       array( '-ab-abc', 'separator in the beginning' ),
+                       array( 'abcd-efg', 'language too long' ),
+                       array( 'aabbccddE', 'tag too long' ),
+                       array( 'pa_guru', 'A tag with underscore is invalid in strict mode' ),
+                       array( 'de-f', 'subtag too short' ),
+               );
+       }
+
+       /**
+        * Negative test for Language::isWellFormedLanguageTag()
+        */
+       function testLenientLanguageTag() {
+               $this->assertTrue(
+                       Language::isWellFormedLanguageTag( 'pa_guru', true ),
+                       'pa_guru is a well-formed language tag in lenient mode'
+               );
+       }
+
        /**
         * Test Language::isValidBuiltInCode()
         * @dataProvider provideLanguageCodes
         */
        function testBuiltInCodeValidation( $code, $message = '' ) {
                $this->assertTrue(
-                       (bool) Language::isValidBuiltInCode( $code ),
+                       (bool)Language::isValidBuiltInCode( $code ),
                        "validating code $code $message"
                );
        }
 
        function testBuiltInCodeValidationRejectUnderscore() {
                $this->assertFalse(
-                       (bool) Language::isValidBuiltInCode( 'be_tarask' ),
+                       (bool)Language::isValidBuiltInCode( 'be_tarask' ),
                        "reject underscore in language code"
                );
        }
 
        function provideLanguageCodes() {
                return array(
-                       array( 'fr'       , 'Two letters, minor case' ),
-                       array( 'EN'       , 'Two letters, upper case' ),
-                       array( 'tyv'      , 'Three letters' ),
-                       array( 'tokipona'   , 'long language code' ),
+                       array( 'fr', 'Two letters, minor case' ),
+                       array( 'EN', 'Two letters, upper case' ),
+                       array( 'tyv', 'Three letters' ),
+                       array( 'tokipona', 'long language code' ),
                        array( 'be-tarask', 'With dash' ),
                        array( 'Zh-classical', 'Begin with upper case, dash' ),
                        array( 'Be-x-old', 'With extension (two dashes)' ),
                );
        }
 
+       /**
+        * Test Language::isKnownLanguageTag()
+        * @dataProvider provideKnownLanguageTags
+        */
+       function testKnownLanguageTag( $code, $message = '' ) {
+               $this->assertTrue(
+                       (bool)Language::isKnownLanguageTag( $code ),
+                       "validating code $code - $message"
+               );
+       }
+
+       function provideKnownLanguageTags() {
+               return array(
+                       array( 'fr', 'simple code' ),
+                       array( 'bat-smg', 'an MW legacy tag' ),
+                       array( 'sgs', 'an internal standard MW name, for which a legacy tag is used externally' ),
+               );
+       }
+
+       /**
+        * Test Language::isKnownLanguageTag()
+        */
+       function testKnownCldrLanguageTag() {
+               if ( !class_exists( 'LanguageNames' ) ) {
+                       $this->markTestSkipped( 'The LanguageNames class is not available. The cldr extension is probably not installed.' );
+               }
+
+               $this->assertTrue(
+                       (bool)Language::isKnownLanguageTag( 'pal' ),
+                       'validating code "pal" an ancient language, which probably will not appear in Names.php, but appears in CLDR in English'
+               );
+       }
+
+       /**
+        * Negative tests for Language::isKnownLanguageTag()
+        * @dataProvider provideUnKnownLanguageTags
+        */
+       function testUnknownLanguageTag( $code, $message = '' ) {
+               $this->assertFalse(
+                       (bool)Language::isKnownLanguageTag( $code ),
+                       "checking that code $code is invalid - $message"
+               );
+       }
+
+       function provideUnknownLanguageTags() {
+               return array(
+                       array( 'mw', 'non-existent two-letter code' ),
+               );
+       }
+
        /**
         * @dataProvider provideSprintfDateSamples
         */
@@ -347,6 +509,7 @@ class LanguageTest extends LanguageClassesTestCase {
                        "sprintfDate('$format', '$ts'): $msg"
                );
        }
+
        /**
         * bug 33454. sprintfDate should always use UTC.
         * @dataProvider provideSprintfDateSamples
@@ -796,7 +959,6 @@ class LanguageTest extends LanguageClassesTestCase {
        }
 
 
-
        /**
         * @dataProvider provideFormatDuration
         */
@@ -939,13 +1101,13 @@ class LanguageTest extends LanguageClassesTestCase {
        function testCheckTitleEncoding( $s ) {
                $this->assertEquals(
                        $s,
-                       $this->getLang()->checkTitleEncoding($s),
+                       $this->getLang()->checkTitleEncoding( $s ),
                        "checkTitleEncoding('$s')"
                );
        }
 
        function provideCheckTitleEncodingData() {
-               return array (
+               return array(
                        array( "" ),
                        array( "United States of America" ), // 7bit ASCII
                        array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ),
@@ -1050,7 +1212,7 @@ class LanguageTest extends LanguageClassesTestCase {
                        array( 7000, 'MMMMMMM' ),
                        array( 8000, 'MMMMMMMM' ),
                        array( 9000, 'MMMMMMMMM' ),
-                       array( 9999, 'MMMMMMMMMCMXCIX'),
+                       array( 9999, 'MMMMMMMMMCMXCIX' ),
                        array( 10000, 'MMMMMMMMMM' ),
                );
        }
@@ -1149,11 +1311,26 @@ class LanguageTest extends LanguageClassesTestCase {
                $s = $lang->getMessageFromDB( 'word-separator' );
                $c = $lang->getMessageFromDB( 'comma-separator' );
 
-               $this->assertEquals( '', $lang->listToText( array( ) ) );
+               $this->assertEquals( '', $lang->listToText( array() ) );
                $this->assertEquals( 'a', $lang->listToText( array( 'a' ) ) );
                $this->assertEquals( "a{$and}{$s}b", $lang->listToText( array( 'a', 'b' ) ) );
                $this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( array( 'a', 'b', 'c' ) ) );
                $this->assertEquals( "a{$c}b{$c}c{$and}{$s}d", $lang->listToText( array( 'a', 'b', 'c', 'd' ) ) );
        }
-}
 
+       /**
+        * @dataProvider provideIsSupportedLanguage
+        */
+       function testIsSupportedLanguage( $code, $expected, $comment ) {
+               $this->assertEquals( $expected, Language::isSupportedLanguage( $code ), $comment );
+       }
+
+       static function provideIsSupportedLanguage() {
+               return array(
+                       array( 'en', true, 'is supported language' ),
+                       array( 'fi', true, 'is supported language' ),
+                       array( 'bunny', false, 'is not supported language' ),
+                       array( 'FI', false, 'is not supported language, input should be in lower case' ),
+               );
+       }
+}
index 259e007..8af0eee 100644 (file)
@@ -15,9 +15,9 @@ class LanguageTiTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index bf3dafc..abd8581 100644 (file)
@@ -15,9 +15,9 @@ class LanguageTlTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index e4859df..e93d49d 100644 (file)
@@ -18,9 +18,9 @@ class LanguageTrTest extends LanguageClassesTestCase {
         * @dataProvider provideDottedAndDotlessI
         */
        function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) {
-               if( $func == 'ucfirst' ) {
+               if ( $func == 'ucfirst' ) {
                        $res = $this->getLang()->ucfirst( $input );
-               } elseif( $func == 'lcfirst' ) {
+               } elseif ( $func == 'lcfirst' ) {
                        $res = $this->getLang()->lcfirst( $input );
                } else {
                        throw new MWException( __METHOD__ . " given an invalid function name '$func'" );
index f29b90b..9bbfaf6 100644 (file)
@@ -16,7 +16,7 @@ class LanguageUkTest extends LanguageClassesTestCase {
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -30,13 +30,15 @@ class LanguageUkTest extends LanguageClassesTestCase {
                        array( 'many', 120 ),
                );
        }
+
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
                $forms = array( 'one', 'several' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providePluralTwoForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'several', 11 ),
                        array( 'several', 91 ),
index 99607d1..495c0be 100644 (file)
@@ -64,6 +64,7 @@ class LanguageUzTest extends LanguageClassesTestCase {
                        $msg
                );
        }
+
        /**
         * Wrapper to verify a text is different once converted to a variant.
         * @param $text string Text to convert
@@ -87,6 +88,7 @@ class LanguageUzTest extends LanguageClassesTestCase {
                $this->assertUnConverted( $text, 'uz-cyrl', $msg );
                $this->assertConverted( $text, 'uz-latn', $msg );
        }
+
        /**
         * Verifiy the given Latin text is not converted when using
         * using the Latin variant and converted to Cyrillic when using
@@ -102,9 +104,11 @@ class LanguageUzTest extends LanguageClassesTestCase {
        function convertTo( $text, $variant ) {
                return $this->getLang()->mConverter->convertTo( $text, $variant );
        }
+
        function convertToCyrillic( $text ) {
                return $this->convertTo( $text, 'uz-cyrl' );
        }
+
        function convertToLatin( $text ) {
                return $this->convertTo( $text, 'uz-latn' );
        }
index 4a1c0e7..28329fa 100644 (file)
@@ -15,9 +15,9 @@ class LanguageWaTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index 033164b..73d5dcc 100644 (file)
@@ -9,7 +9,7 @@ class CLDRPluralRuleEvaluatorTest extends MediaWikiTestCase {
         * @dataProvider validTestCases
         */
        function testValidRules( $expected, $rules, $number, $comment ) {
-               $result = CLDRPluralRuleEvaluator::evaluate( $number, (array) $rules );
+               $result = CLDRPluralRuleEvaluator::evaluate( $number, (array)$rules );
                $this->assertEquals( $expected, $result, $comment );
        }
 
@@ -18,7 +18,7 @@ class CLDRPluralRuleEvaluatorTest extends MediaWikiTestCase {
         * @expectedException CLDRPluralRuleError
         */
        function testInvalidRules( $rules, $comment ) {
-               CLDRPluralRuleEvaluator::evaluate( 1, (array) $rules );
+               CLDRPluralRuleEvaluator::evaluate( 1, (array)$rules );
        }
 
        function validTestCases() {
@@ -31,19 +31,19 @@ class CLDRPluralRuleEvaluatorTest extends MediaWikiTestCase {
                        array( 1, 'n is 1', 1.1, 'float number and is' ),
                        array( 1, 'n is 1', 2, 'float number and is' ),
 
-                       array( 0, 'n in 1,3,5',     3, '' ),
+                       array( 0, 'n in 1,3,5', 3, '' ),
                        array( 1, 'n not in 1,3,5', 5, '' ),
 
-                       array( 1, 'n in 1,3,5',     2, '' ),
+                       array( 1, 'n in 1,3,5', 2, '' ),
                        array( 0, 'n not in 1,3,5', 4, '' ),
 
-                       array( 0, 'n in 1..3',      2, '' ),
-                       array( 0, 'n in 1..3',      3, 'in is inclusive' ),
-                       array( 1, 'n in 1..3',      0, '' ),
+                       array( 0, 'n in 1..3', 2, '' ),
+                       array( 0, 'n in 1..3', 3, 'in is inclusive' ),
+                       array( 1, 'n in 1..3', 0, '' ),
 
-                       array( 1, 'n not in 1..3',      2, '' ),
-                       array( 1, 'n not in 1..3',      3, 'in is inclusive' ),
-                       array( 0, 'n not in 1..3',      0, '' ),
+                       array( 1, 'n not in 1..3', 2, '' ),
+                       array( 1, 'n not in 1..3', 3, 'in is inclusive' ),
+                       array( 0, 'n not in 1..3', 0, '' ),
 
                        array( 1, 'n is not 1 and n is not 2 and n is not 3', 1, 'and relation' ),
                        array( 0, 'n is not 1 and n is not 2 and n is not 4', 3, 'and relation' ),
index 0f3a6a1..40d24fc 100644 (file)
@@ -57,7 +57,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         */
        protected function gunzip( $fname ) {
                $gzipped_contents = file_get_contents( $fname );
-               if ( $gzipped_contents === FALSE ) {
+               if ( $gzipped_contents === false ) {
                        $this->fail( "Could not get contents of $fname" );
                }
                // We resort to use gzinflate instead of gzdecode, as gzdecode
@@ -121,7 +121,8 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
        protected function skipToNodeEnd( $name ) {
                while ( $this->xml->read() ) {
                        if ( $this->xml->nodeType == XMLReader::END_ELEMENT &&
-                               $this->xml->name == $name ) {
+                               $this->xml->name == $name
+                       ) {
                                return true;
                        }
                }
@@ -189,7 +190,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
        protected function skipWhitespace() {
                $cont = true;
                while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE )
-                               || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
+                       || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
                        $cont = $this->xml->read();
                }
        }
@@ -300,7 +301,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         * @param $parentid int|false: (optional) id of the parent revision
         */
        protected function assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text = false, $parentid = false,
-                                               $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT ) {
+                                                                          $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT ) {
 
                $this->assertNodeStart( "revision" );
                $this->skipWhitespace();
@@ -358,7 +359,8 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
                        $this->assertFalse( $this->xml->hasValue, "Revision has text" );
                        $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
                        if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT )
-                               && ( $this->xml->name == "text" ) ) {
+                               && ( $this->xml->name == "text" )
+                       ) {
 
                                $this->xml->read();
                        }
index a0ed745..235e9ad 100644 (file)
@@ -81,14 +81,14 @@ class MaintenanceFixup extends Maintenance {
                        return;
                }
 
-               return call_user_func_array ( array( "parent", __FUNCTION__ ), func_get_args() );
+               return call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() );
        }
 
        /**
         * Safety net around register_shutdown_function of Maintenance.php
         */
        public function __destruct() {
-               if ( ! $this->shutdownSimulated ) {
+               if ( !$this->shutdownSimulated ) {
                        // Someone generated a MaintenanceFixup instance without calling
                        // simulateShutdown. We'd have to raise a PHPUnit exception to correctly
                        // flag this illegal usage. However, we are already in a destruktor, which
@@ -112,7 +112,6 @@ class MaintenanceFixup extends Maintenance {
        }
 
 
-
        // --- Making protected functions visible for test
 
        public function output( $out, $channel = null ) {
@@ -120,11 +119,10 @@ class MaintenanceFixup extends Maintenance {
                // Maintenance::output signature. However, we do not use (or rely on)
                // those variables. Instead we pass to Maintenance::output whatever we
                // receive at runtime.
-               return call_user_func_array ( array( "parent", __FUNCTION__ ), func_get_args() );
+               return call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() );
        }
 
 
-
        // --- Requirements for getting instance of abstract class
 
        public function execute() {
@@ -173,7 +171,7 @@ class MaintenanceTest extends MediaWikiTestCase {
        private function assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending ) {
 
                $this->assertEquals( $preShutdownOutput, $this->getActualOutput(),
-                               "Output before shutdown simulation" );
+                       "Output before shutdown simulation" );
 
                $this->m->simulateShutdown();
                $this->m = null;
@@ -191,44 +189,44 @@ class MaintenanceTest extends MediaWikiTestCase {
 
        function testOutputEmpty() {
                $this->m->output( "" );
-               $this->assertOutputPrePostShutdown( "", False );
+               $this->assertOutputPrePostShutdown( "", false );
        }
 
        function testOutputString() {
                $this->m->output( "foo" );
-               $this->assertOutputPrePostShutdown( "foo", False );
+               $this->assertOutputPrePostShutdown( "foo", false );
        }
 
        function testOutputStringString() {
                $this->m->output( "foo" );
                $this->m->output( "bar" );
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testOutputStringNL() {
                $this->m->output( "foo\n" );
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testOutputStringNLNL() {
                $this->m->output( "foo\n\n" );
-               $this->assertOutputPrePostShutdown( "foo\n\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n\n", false );
        }
 
        function testOutputStringNLString() {
                $this->m->output( "foo\nbar" );
-               $this->assertOutputPrePostShutdown( "foo\nbar", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar", false );
        }
 
        function testOutputStringNLStringNL() {
                $this->m->output( "foo\nbar\n" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputStringNLStringNLLinewise() {
                $this->m->output( "foo\n" );
                $this->m->output( "bar\n" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputStringNLStringNLArbitrary() {
@@ -239,7 +237,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "ba" );
                $this->m->output( "" );
                $this->m->output( "r\n" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputStringNLStringNLArbitraryAgain() {
@@ -250,49 +248,49 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "a" );
                $this->m->output( "" );
                $this->m->output( "r\n" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputWNullChannelEmpty() {
                $this->m->output( "", null );
-               $this->assertOutputPrePostShutdown( "", False );
+               $this->assertOutputPrePostShutdown( "", false );
        }
 
        function testOutputWNullChannelString() {
                $this->m->output( "foo", null );
-               $this->assertOutputPrePostShutdown( "foo", False );
+               $this->assertOutputPrePostShutdown( "foo", false );
        }
 
        function testOutputWNullChannelStringString() {
                $this->m->output( "foo", null );
                $this->m->output( "bar", null );
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testOutputWNullChannelStringNL() {
                $this->m->output( "foo\n", null );
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testOutputWNullChannelStringNLNL() {
                $this->m->output( "foo\n\n", null );
-               $this->assertOutputPrePostShutdown( "foo\n\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n\n", false );
        }
 
        function testOutputWNullChannelStringNLString() {
                $this->m->output( "foo\nbar", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar", false );
        }
 
        function testOutputWNullChannelStringNLStringNL() {
                $this->m->output( "foo\nbar\n", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputWNullChannelStringNLStringNLLinewise() {
                $this->m->output( "foo\n", null );
                $this->m->output( "bar\n", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputWNullChannelStringNLStringNLArbitrary() {
@@ -303,7 +301,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "ba", null );
                $this->m->output( "", null );
                $this->m->output( "r\n", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputWNullChannelStringNLStringNLArbitraryAgain() {
@@ -314,17 +312,17 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "a", null );
                $this->m->output( "", null );
                $this->m->output( "r\n", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputWChannelString() {
                $this->m->output( "foo", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo", True );
+               $this->assertOutputPrePostShutdown( "foo", true );
        }
 
        function testOutputWChannelStringNL() {
                $this->m->output( "foo\n", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo", True );
+               $this->assertOutputPrePostShutdown( "foo", true );
        }
 
        function testOutputWChannelStringNLNL() {
@@ -333,23 +331,23 @@ class MaintenanceTest extends MediaWikiTestCase {
                // outputChanneled with a string ending in a nl ... which is not allowed
                // according to the documentation of outputChanneled)
                $this->m->output( "foo\n\n", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\n", True );
+               $this->assertOutputPrePostShutdown( "foo\n", true );
        }
 
        function testOutputWChannelStringNLString() {
                $this->m->output( "foo\nbar", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testOutputWChannelStringNLStringNL() {
                $this->m->output( "foo\nbar\n", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testOutputWChannelStringNLStringNLLinewise() {
                $this->m->output( "foo\n", "bazChannel" );
                $this->m->output( "bar\n", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar", True );
+               $this->assertOutputPrePostShutdown( "foobar", true );
        }
 
        function testOutputWChannelStringNLStringNLArbitrary() {
@@ -360,7 +358,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "ba", "bazChannel" );
                $this->m->output( "", "bazChannel" );
                $this->m->output( "r\n", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar", True );
+               $this->assertOutputPrePostShutdown( "foobar", true );
        }
 
        function testOutputWChannelStringNLStringNLArbitraryAgain() {
@@ -371,7 +369,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "a", "bazChannel" );
                $this->m->output( "", "bazChannel" );
                $this->m->output( "r\n", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testOutputWMultipleChannelsChannelChange() {
@@ -379,7 +377,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "bar", "bazChannel" );
                $this->m->output( "qux", "quuxChannel" );
                $this->m->output( "corge", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", True );
+               $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
        }
 
        function testOutputWMultipleChannelsChannelChangeNL() {
@@ -387,7 +385,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "bar\n", "bazChannel" );
                $this->m->output( "qux\n", "quuxChannel" );
                $this->m->output( "corge", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", True );
+               $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
        }
 
        function testOutputWAndWOChannelStringStartWO() {
@@ -395,7 +393,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "bar", "bazChannel" );
                $this->m->output( "qux" );
                $this->m->output( "quux", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar\nquxquux", True );
+               $this->assertOutputPrePostShutdown( "foobar\nquxquux", true );
        }
 
        function testOutputWAndWOChannelStringStartW() {
@@ -403,27 +401,27 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "bar" );
                $this->m->output( "qux", "bazChannel" );
                $this->m->output( "quux" );
-               $this->assertOutputPrePostShutdown( "foo\nbarqux\nquux", False );
+               $this->assertOutputPrePostShutdown( "foo\nbarqux\nquux", false );
        }
 
        function testOutputWChannelTypeSwitch() {
                $this->m->output( "foo", 1 );
                $this->m->output( "bar", 1.0 );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testOutputIntermittentEmpty() {
                $this->m->output( "foo" );
                $this->m->output( "" );
                $this->m->output( "bar" );
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testOutputIntermittentFalse() {
                $this->m->output( "foo" );
                $this->m->output( false );
                $this->m->output( "bar" );
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testOutputIntermittentFalseAfterOtherChannel() {
@@ -431,35 +429,35 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->output( "foo" );
                $this->m->output( false );
                $this->m->output( "bar" );
-               $this->assertOutputPrePostShutdown( "qux\nfoobar", False );
+               $this->assertOutputPrePostShutdown( "qux\nfoobar", false );
        }
 
        function testOutputWNullChannelIntermittentEmpty() {
                $this->m->output( "foo", null );
                $this->m->output( "", null );
                $this->m->output( "bar", null );
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testOutputWNullChannelIntermittentFalse() {
                $this->m->output( "foo", null );
                $this->m->output( false, null );
                $this->m->output( "bar", null );
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testOutputWChannelIntermittentEmpty() {
                $this->m->output( "foo", "bazChannel" );
                $this->m->output( "", "bazChannel" );
                $this->m->output( "bar", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar", True );
+               $this->assertOutputPrePostShutdown( "foobar", true );
        }
 
        function testOutputWChannelIntermittentFalse() {
                $this->m->output( "foo", "bazChannel" );
                $this->m->output( false, "bazChannel" );
                $this->m->output( "bar", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar", True );
+               $this->assertOutputPrePostShutdown( "foobar", true );
        }
 
        // Note that (per documentation) outputChanneled does take strings that end
@@ -467,23 +465,23 @@ class MaintenanceTest extends MediaWikiTestCase {
 
        function testOutputChanneledEmpty() {
                $this->m->outputChanneled( "" );
-               $this->assertOutputPrePostShutdown( "\n", False );
+               $this->assertOutputPrePostShutdown( "\n", false );
        }
 
        function testOutputChanneledString() {
                $this->m->outputChanneled( "foo" );
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testOutputChanneledStringString() {
                $this->m->outputChanneled( "foo" );
                $this->m->outputChanneled( "bar" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputChanneledStringNLString() {
                $this->m->outputChanneled( "foo\nbar" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputChanneledStringNLStringNLArbitraryAgain() {
@@ -494,28 +492,28 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "a" );
                $this->m->outputChanneled( "" );
                $this->m->outputChanneled( "r" );
-               $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", False );
+               $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false );
        }
 
        function testOutputChanneledWNullChannelEmpty() {
                $this->m->outputChanneled( "", null );
-               $this->assertOutputPrePostShutdown( "\n", False );
+               $this->assertOutputPrePostShutdown( "\n", false );
        }
 
        function testOutputChanneledWNullChannelString() {
                $this->m->outputChanneled( "foo", null );
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testOutputChanneledWNullChannelStringString() {
                $this->m->outputChanneled( "foo", null );
                $this->m->outputChanneled( "bar", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputChanneledWNullChannelStringNLString() {
                $this->m->outputChanneled( "foo\nbar", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputChanneledWNullChannelStringNLStringNLArbitraryAgain() {
@@ -526,23 +524,23 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "a", null );
                $this->m->outputChanneled( "", null );
                $this->m->outputChanneled( "r", null );
-               $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", False );
+               $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false );
        }
 
        function testOutputChanneledWChannelString() {
                $this->m->outputChanneled( "foo", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo", True );
+               $this->assertOutputPrePostShutdown( "foo", true );
        }
 
        function testOutputChanneledWChannelStringNLString() {
                $this->m->outputChanneled( "foo\nbar", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testOutputChanneledWChannelStringString() {
                $this->m->outputChanneled( "foo", "bazChannel" );
                $this->m->outputChanneled( "bar", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar", True );
+               $this->assertOutputPrePostShutdown( "foobar", true );
        }
 
        function testOutputChanneledWChannelStringNLStringNLArbitraryAgain() {
@@ -553,7 +551,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "a", "bazChannel" );
                $this->m->outputChanneled( "", "bazChannel" );
                $this->m->outputChanneled( "r", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testOutputChanneledWMultipleChannelsChannelChange() {
@@ -561,7 +559,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "bar", "bazChannel" );
                $this->m->outputChanneled( "qux", "quuxChannel" );
                $this->m->outputChanneled( "corge", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", True );
+               $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
        }
 
        function testOutputChanneledWMultipleChannelsChannelChangeEnclosedNull() {
@@ -569,7 +567,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "bar", null );
                $this->m->outputChanneled( "qux", null );
                $this->m->outputChanneled( "corge", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true );
        }
 
        function testOutputChanneledWMultipleChannelsChannelAfterNullChange() {
@@ -577,7 +575,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "bar", null );
                $this->m->outputChanneled( "qux", null );
                $this->m->outputChanneled( "corge", "quuxChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true );
        }
 
        function testOutputChanneledWAndWOChannelStringStartWO() {
@@ -585,7 +583,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "bar", "bazChannel" );
                $this->m->outputChanneled( "qux" );
                $this->m->outputChanneled( "quux", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux", true );
        }
 
        function testOutputChanneledWAndWOChannelStringStartW() {
@@ -593,114 +591,114 @@ class MaintenanceTest extends MediaWikiTestCase {
                $this->m->outputChanneled( "bar" );
                $this->m->outputChanneled( "qux", "bazChannel" );
                $this->m->outputChanneled( "quux" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux\n", false );
        }
 
        function testOutputChanneledWChannelTypeSwitch() {
                $this->m->outputChanneled( "foo", 1 );
                $this->m->outputChanneled( "bar", 1.0 );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testOutputChanneledWOChannelIntermittentEmpty() {
                $this->m->outputChanneled( "foo" );
                $this->m->outputChanneled( "" );
                $this->m->outputChanneled( "bar" );
-               $this->assertOutputPrePostShutdown( "foo\n\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false );
        }
 
        function testOutputChanneledWOChannelIntermittentFalse() {
                $this->m->outputChanneled( "foo" );
                $this->m->outputChanneled( false );
                $this->m->outputChanneled( "bar" );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputChanneledWNullChannelIntermittentEmpty() {
                $this->m->outputChanneled( "foo", null );
                $this->m->outputChanneled( "", null );
                $this->m->outputChanneled( "bar", null );
-               $this->assertOutputPrePostShutdown( "foo\n\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false );
        }
 
        function testOutputChanneledWNullChannelIntermittentFalse() {
                $this->m->outputChanneled( "foo", null );
                $this->m->outputChanneled( false, null );
                $this->m->outputChanneled( "bar", null );
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testOutputChanneledWChannelIntermittentEmpty() {
                $this->m->outputChanneled( "foo", "bazChannel" );
                $this->m->outputChanneled( "", "bazChannel" );
                $this->m->outputChanneled( "bar", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foobar", True );
+               $this->assertOutputPrePostShutdown( "foobar", true );
        }
 
        function testOutputChanneledWChannelIntermittentFalse() {
                $this->m->outputChanneled( "foo", "bazChannel" );
                $this->m->outputChanneled( false, "bazChannel" );
                $this->m->outputChanneled( "bar", "bazChannel" );
-               $this->assertOutputPrePostShutdown( "foo\nbar", True );
+               $this->assertOutputPrePostShutdown( "foo\nbar", true );
        }
 
        function testCleanupChanneledClean() {
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "", False );
+               $this->assertOutputPrePostShutdown( "", false );
        }
 
        function testCleanupChanneledAfterOutput() {
                $this->m->output( "foo" );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo", False );
+               $this->assertOutputPrePostShutdown( "foo", false );
        }
 
        function testCleanupChanneledAfterOutputWNullChannel() {
                $this->m->output( "foo", null );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo", False );
+               $this->assertOutputPrePostShutdown( "foo", false );
        }
 
        function testCleanupChanneledAfterOutputWChannel() {
                $this->m->output( "foo", "bazChannel" );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testCleanupChanneledAfterNLOutput() {
                $this->m->output( "foo\n" );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testCleanupChanneledAfterNLOutputWNullChannel() {
                $this->m->output( "foo\n", null );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testCleanupChanneledAfterNLOutputWChannel() {
                $this->m->output( "foo\n", "bazChannel" );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testCleanupChanneledAfterOutputChanneledWOChannel() {
                $this->m->outputChanneled( "foo" );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testCleanupChanneledAfterOutputChanneledWNullChannel() {
                $this->m->outputChanneled( "foo", null );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testCleanupChanneledAfterOutputChanneledWChannel() {
                $this->m->outputChanneled( "foo", "bazChannel" );
                $this->m->cleanupChanneled();
-               $this->assertOutputPrePostShutdown( "foo\n", False );
+               $this->assertOutputPrePostShutdown( "foo\n", false );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutput() {
@@ -710,9 +708,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutputWNullChannel() {
@@ -722,9 +720,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar", null );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foobar", False );
+               $this->assertOutputPrePostShutdown( "foobar", false );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutputWChannel() {
@@ -734,9 +732,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foobar\n", True );
+               $this->assertOutputPrePostShutdown( "foobar\n", true );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutputWNullChannelNL() {
@@ -746,9 +744,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar\n", null );
 
                $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutputWChannelNL() {
@@ -758,9 +756,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar\n", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foobar\n", True );
+               $this->assertOutputPrePostShutdown( "foobar\n", true );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutputChanneled() {
@@ -770,9 +768,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar" );
 
                $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutputChanneledWNullChannel() {
@@ -782,9 +780,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar", null );
 
                $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foo\nbar\n", False );
+               $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
 
        function testMultipleMaintenanceObjectsInteractionOutputChanneledWChannel() {
@@ -794,9 +792,9 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foobar\n", True );
+               $this->assertOutputPrePostShutdown( "foobar\n", true );
        }
 
        function testMultipleMaintenanceObjectsInteractionCleanupChanneledWChannel() {
@@ -806,16 +804,16 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before first cleanup" );
+                       "Output before first cleanup" );
                $this->m->cleanupChanneled();
                $this->assertEquals( "foobar\n", $this->getActualOutput(),
-                               "Output after first cleanup" );
+                       "Output after first cleanup" );
                $m2->cleanupChanneled();
                $this->assertEquals( "foobar\n\n", $this->getActualOutput(),
-                               "Output after second cleanup" );
+                       "Output after second cleanup" );
 
                $m2->simulateShutdown();
-               $this->assertOutputPrePostShutdown( "foobar\n\n", False );
+               $this->assertOutputPrePostShutdown( "foobar\n\n", false );
        }
 
 
index a029c92..cc00e6e 100644 (file)
@@ -265,12 +265,12 @@ class BaseDumpTest extends MediaWikiTestCase {
                foreach ( $requested_pages as $i ) {
                        $this->assertTrue( array_key_exists( $i, $available_pages ),
                                "Check for availability of requested page " . $i );
-                       $content .= $available_pages[ $i ];
+                       $content .= $available_pages[$i];
                }
                $content .= $tail;
 
                $this->assertEquals( strlen( $content ), file_put_contents(
-                               $fname, $content ), "Length of prepared prefetch" );
+                       $fname, $content ), "Length of prepared prefetch" );
 
                return $fname;
        }
index 2ebb351..0962344 100644 (file)
@@ -65,7 +65,7 @@ class TextPassDumperTest extends DumpTestCase {
                        if ( $ns === NS_TALK ) {
                                //@todo: work around this.
                                throw new MWException( "The default wikitext namespace is the talk namespace. "
-                                       . " We can't currently deal with that.");
+                                       . " We can't currently deal with that." );
                        }
 
                        $title = Title::newFromText( 'BackupDumperTestP1', NS_TALK );
@@ -101,8 +101,8 @@ class TextPassDumperTest extends DumpTestCase {
                // Setting up the dump
                $nameStub = $this->setUpStub();
                $nameFull = $this->getNewTempFile();
-               $dumper = new TextPassDumper( array ( "--stub=file:" . $nameStub,
-                               "--output=file:" . $nameFull ) );
+               $dumper = new TextPassDumper( array( "--stub=file:" . $nameStub,
+                       "--output=file:" . $nameFull ) );
                $dumper->reporting = false;
                $dumper->setDb( $this->db );
 
@@ -156,7 +156,7 @@ class TextPassDumperTest extends DumpTestCase {
                );
 
                // The mock itself
-               $prefetchMock = $this->getMock( 'BaseDump', array( 'prefetch' ), array(), '', FALSE );
+               $prefetchMock = $this->getMock( 'BaseDump', array( 'prefetch' ), array(), '', false );
                $prefetchMock->expects( $this->exactly( 6 ) )
                        ->method( 'prefetch' )
                        ->will( $this->returnValueMap( $prefetchMap ) );
@@ -164,8 +164,8 @@ class TextPassDumperTest extends DumpTestCase {
                // Setting up of the dump
                $nameStub = $this->setUpStub();
                $nameFull = $this->getNewTempFile();
-               $dumper = new TextPassDumper( array ( "--stub=file:"
-                               . $nameStub, "--output=file:" . $nameFull ) );
+               $dumper = new TextPassDumper( array( "--stub=file:"
+                       . $nameStub, "--output=file:" . $nameFull ) );
                $dumper->prefetch = $prefetchMock;
                $dumper->reporting = false;
                $dumper->setDb( $this->db );
@@ -230,7 +230,7 @@ class TextPassDumperTest extends DumpTestCase {
                $nameOutputDir = $this->getNewTempDirectory();
 
                $stderr = fopen( 'php://output', 'a' );
-               if ( $stderr === FALSE ) {
+               if ( $stderr === false ) {
                        $this->fail( "Could not open stream for stderr" );
                }
 
@@ -250,10 +250,10 @@ class TextPassDumperTest extends DumpTestCase {
                        $this->assertTrue( wfMkdirParents( $nameOutputDir ),
                                "Creating temporary output directory " );
                        $this->setUpStub( $nameStub, $iterations );
-                       $dumper = new TextPassDumper( array ( "--stub=file:" . $nameStub,
-                                       "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full",
-                                       "--maxtime=1" /*This is in minutes. Fixup is below*/,
-                                       "--checkpointfile=checkpoint-%s-%s.xml.gz" ) );
+                       $dumper = new TextPassDumper( array( "--stub=file:" . $nameStub,
+                               "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full",
+                               "--maxtime=1" /*This is in minutes. Fixup is below*/,
+                               "--checkpointfile=checkpoint-%s-%s.xml.gz" ) );
                        $dumper->setDb( $this->db );
                        $dumper->maxTimeAllowed = $checkpointAfter; // Patching maxTime from 1 minute
                        $dumper->stderr = $stderr;
@@ -283,7 +283,7 @@ class TextPassDumperTest extends DumpTestCase {
 
                                $this->assertLessThan( 50000, $iterations,
                                        "Emergency stop against infinitely increasing iteration "
-                                       . "count ( last duration: $lastDuration )" );
+                                               . "count ( last duration: $lastDuration )" );
                        }
                }
 
@@ -300,11 +300,11 @@ class TextPassDumperTest extends DumpTestCase {
 
                // Each run of the following loop body tries to handle exactly 1 /page/ (not
                // iteration of stub content). $i is only increased after having treated page 4.
-               for ( $i = 0 ; $i < $iterations ; ) {
+               for ( $i = 0; $i < $iterations; ) {
 
                        // 1. Assuring a file is opened and ready. Skipping across header if
                        //    necessary.
-                       if ( ! $fileOpened ) {
+                       if ( !$fileOpened ) {
                                $this->assertNotEmpty( $files, "No more existing dump files, "
                                        . "but not yet all pages found" );
                                $fname = array_shift( $files );
@@ -323,65 +323,65 @@ class TextPassDumperTest extends DumpTestCase {
 
                        // 2. Performing a single page check
                        switch ( $lookingForPage ) {
-                       case 1:
-                               // Page 1
-                               $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN,
-                                       "BackupDumperTestP1" );
-                               $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1",
-                                       $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
-                                       "BackupDumperTestP1Text1" );
-                               $this->assertPageEnd();
-
-                               $lookingForPage = 2;
-                               break;
-
-                       case 2:
-                               // Page 2
-                               $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN,
-                                       "BackupDumperTestP2" );
-                               $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1",
-                                       $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
-                                       "BackupDumperTestP2Text1" );
-                               $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2",
-                                       $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
-                                       "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs );
-                               $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3",
-                                       $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
-                                       "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs );
-                               $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs,
-                                       "BackupDumperTestP2Summary4 extra",
-                                       $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
-                                       "BackupDumperTestP2Text4 some additional Text",
-                                       $this->revId2_3 + $i * self::$numOfRevs );
-                               $this->assertPageEnd();
-
-                               $lookingForPage = 4;
-                               break;
-
-                       case 4:
-                               // Page 4
-                               $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK,
-                                       "Talk:BackupDumperTestP1" );
-                               $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs,
-                                       "Talk BackupDumperTestP1 Summary1",
-                                       $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
-                                       "Talk about BackupDumperTestP1 Text1" );
-                               $this->assertPageEnd();
-
-                               $lookingForPage = 1;
-
-                               // We dealt with the whole iteration.
-                               $i++;
-                               break;
-
-                       default:
-                               $this->fail( "Bad setting for lookingForPage ($lookingForPage)" );
+                               case 1:
+                                       // Page 1
+                                       $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN,
+                                               "BackupDumperTestP1" );
+                                       $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1",
+                                               $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
+                                               "BackupDumperTestP1Text1" );
+                                       $this->assertPageEnd();
+
+                                       $lookingForPage = 2;
+                                       break;
+
+                               case 2:
+                                       // Page 2
+                                       $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN,
+                                               "BackupDumperTestP2" );
+                                       $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1",
+                                               $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
+                                               "BackupDumperTestP2Text1" );
+                                       $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2",
+                                               $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
+                                               "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs );
+                                       $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3",
+                                               $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
+                                               "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs );
+                                       $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs,
+                                               "BackupDumperTestP2Summary4 extra",
+                                               $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                                               "BackupDumperTestP2Text4 some additional Text",
+                                               $this->revId2_3 + $i * self::$numOfRevs );
+                                       $this->assertPageEnd();
+
+                                       $lookingForPage = 4;
+                                       break;
+
+                               case 4:
+                                       // Page 4
+                                       $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK,
+                                               "Talk:BackupDumperTestP1" );
+                                       $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs,
+                                               "Talk BackupDumperTestP1 Summary1",
+                                               $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
+                                               "Talk about BackupDumperTestP1 Text1" );
+                                       $this->assertPageEnd();
+
+                                       $lookingForPage = 1;
+
+                                       // We dealt with the whole iteration.
+                                       $i++;
+                                       break;
+
+                               default:
+                                       $this->fail( "Bad setting for lookingForPage ($lookingForPage)" );
                        }
 
                        // 3. Checking for the end of the current checkpoint file
                        if ( $this->xml->nodeType == XMLReader::END_ELEMENT
-                               && $this->xml->name == "mediawiki" ) {
-
+                               && $this->xml->name == "mediawiki"
+                       ) {
                                $this->assertDumpEnd();
                                $fileOpened = false;
                        }
@@ -417,6 +417,7 @@ class TextPassDumperTest extends DumpTestCase {
         * @group large
         */
        function testCheckpointGzip() {
+               $this->checkHasGzip();
                $this->checkpointHelper( "gzip" );
        }
 
@@ -577,8 +578,7 @@ class TextPassDumperTest extends DumpTestCase {
                }
                $content .= $tail;
                $this->assertEquals( strlen( $content ), file_put_contents(
-                               $fname, $content ), "Length of prepared stub" );
+                       $fname, $content ), "Length of prepared stub" );
                return $fname;
        }
-
 }
index 8a8dea5..5cf172e 100644 (file)
@@ -28,18 +28,18 @@ class BackupDumperLoggerTest extends DumpTestCase {
         * @return int id of the added log entry
         */
        private function addLogEntry( $type, $subtype, User $user, $ns, $title,
-               $comment = null, $parameters = null ) {
-
-                $logEntry = new ManualLogEntry( $type, $subtype );
+               $comment = null, $parameters = null
+       ) {
+               $logEntry = new ManualLogEntry( $type, $subtype );
                $logEntry->setPerformer( $user );
                $logEntry->setTarget( Title::newFromText( $title, $ns ) );
-                if ( $comment !== null ) {
+               if ( $comment !== null ) {
                        $logEntry->setComment( $comment );
                }
-                if ( $parameters !== null ) {
+               if ( $parameters !== null ) {
                        $logEntry->setParameters( $parameters );
                }
-                return $logEntry->insert();
+               return $logEntry->insert();
        }
 
        function addDBData() {
@@ -73,7 +73,7 @@ class BackupDumperLoggerTest extends DumpTestCase {
 
                        $this->logId3 = $this->addLogEntry( 'move', 'delete',
                                $user2, NS_MAIN, "PageA", "SomeOtherComment",
-                               array( 'key1' => 1,  3 => 'value3' ) );
+                               array( 'key1' => 1, 3 => 'value3' ) );
                        $this->assertGreaterThan( 0, $this->logId3 );
 
                } catch ( Exception $e ) {
@@ -101,7 +101,8 @@ class BackupDumperLoggerTest extends DumpTestCase {
         * @param $parameters array: (optional) unserialized data accompanying the log entry
         */
        private function assertLogItem( $id, $user_name, $user_id, $comment, $type,
-               $subtype, $title, $parameters = array() ) {
+               $subtype, $title, $parameters = array()
+       ) {
 
                $this->assertNodeStart( "logitem" );
                $this->skipWhitespace();
@@ -134,12 +135,12 @@ class BackupDumperLoggerTest extends DumpTestCase {
                $this->skipWhitespace();
        }
 
-       function testPlain () {
+       function testPlain() {
                global $wgContLang;
 
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->logId1;
                $dumper->endId = $this->logId3 + 1;
                $dumper->reporting = false;
@@ -172,10 +173,12 @@ class BackupDumperLoggerTest extends DumpTestCase {
        function testXmlDumpsBackupUseCaseLogging() {
                global $wgContLang;
 
+               $this->checkHasGzip();
+
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=gzip:" . $fname,
-                               "--reporting=2" ) );
+               $dumper = new BackupDumper( array( "--output=gzip:" . $fname,
+                       "--reporting=2" ) );
                $dumper->startId = $this->logId1;
                $dumper->endId = $this->logId3 + 1;
                $dumper->setDb( $this->db );
@@ -186,7 +189,7 @@ class BackupDumperLoggerTest extends DumpTestCase {
                // to be able to alert (once dumping produces reports) that this test
                // needs updates.
                $dumper->stderr = fopen( 'php://output', 'a' );
-               if ( $dumper->stderr === FALSE ) {
+               if ( $dumper->stderr === false ) {
                        $this->fail( "Could not open stream for stderr" );
                }
 
index 6cdc4ec..07c7670 100644 (file)
@@ -23,7 +23,7 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->setMwGlobals( array(
                        'wgLanguageCode' => 'en',
                        'wgContLang' => Language::factory( 'en' ),
-               ));
+               ) );
 
                $this->tablesUsed[] = 'page';
                $this->tablesUsed[] = 'revision';
@@ -36,7 +36,7 @@ class BackupDumperPageTest extends DumpTestCase {
                        if ( $this->namespace === $this->talk_namespace ) {
                                //@todo: work around this.
                                throw new MWException( "The default wikitext namespace is the talk namespace. "
-                                       . " We can't currently deal with that.");
+                                       . " We can't currently deal with that." );
                        }
 
                        $this->pageTitle1 = Title::newFromText( 'BackupDumperTestP1', $this->namespace );
@@ -96,10 +96,10 @@ class BackupDumperPageTest extends DumpTestCase {
 
        }
 
-       function testFullTextPlain () {
+       function testFullTextPlain() {
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -147,10 +147,10 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->assertDumpEnd();
        }
 
-       function testFullStubPlain () {
+       function testFullStubPlain() {
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -192,10 +192,10 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->assertDumpEnd();
        }
 
-       function testCurrentStubPlain () {
+       function testCurrentStubPlain() {
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -231,10 +231,12 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->assertDumpEnd();
        }
 
-       function testCurrentStubGzip () {
+       function testCurrentStubGzip() {
+               $this->checkHasGzip();
+
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=gzip:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=gzip:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -272,8 +274,7 @@ class BackupDumperPageTest extends DumpTestCase {
        }
 
 
-
-       function testXmlDumpsBackupUseCase () {
+       function testXmlDumpsBackupUseCase() {
                // xmldumps-backup typically performs a single dump that that writes
                // out three files
                // * gzipped stubs of everything (meta-history)
@@ -284,15 +285,17 @@ class BackupDumperPageTest extends DumpTestCase {
                // We reproduce such a setup with our mini fixture, although we omit
                // chunks, and all the other gimmicks of xmldumps-backup.
                //
+               $this->checkHasGzip();
+
                $fnameMetaHistory = $this->getNewTempFile();
                $fnameMetaCurrent = $this->getNewTempFile();
                $fnameArticles = $this->getNewTempFile();
 
-               $dumper = new BackupDumper( array ( "--output=gzip:" . $fnameMetaHistory,
-                               "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
-                               "--output=gzip:" . $fnameArticles, "--filter=latest",
-                               "--filter=notalk", "--filter=namespace:!NS_USER",
-                               "--reporting=1000" ) );
+               $dumper = new BackupDumper( array( "--output=gzip:" . $fnameMetaHistory,
+                       "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
+                       "--output=gzip:" . $fnameArticles, "--filter=latest",
+                       "--filter=notalk", "--filter=namespace:!NS_USER",
+                       "--reporting=1000" ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->setDb( $this->db );
@@ -302,7 +305,7 @@ class BackupDumperPageTest extends DumpTestCase {
                // computer. We only check that reporting does not crash the dumping
                // and that something is reported
                $dumper->stderr = fopen( 'php://output', 'a' );
-               if ( $dumper->stderr === FALSE ) {
+               if ( $dumper->stderr === false ) {
                        $this->fail( "Could not open stream for stderr" );
                }
 
@@ -402,5 +405,4 @@ class BackupDumperPageTest extends DumpTestCase {
        }
 
 
-
 }
index 8041e35..4d1d45d 100644 (file)
@@ -18,7 +18,7 @@ class SemiMockedFetchText extends FetchText {
        /**
         * @var bool Whether or not a text for stdin has been provided
         */
-       private $mockSetUp = False;
+       private $mockSetUp = false;
 
        /**
         * @var Array Invocation counters for the mocked aspects
@@ -26,16 +26,14 @@ class SemiMockedFetchText extends FetchText {
        private $mockInvocations = array( 'getStdin' => 0 );
 
 
-
        /**
         * Data for the fake stdin
         *
         * @param $stdin String The string to be used instead of stdin
         */
-       function mockStdin( $stdin )
-       {
+       function mockStdin( $stdin ) {
                $this->mockStdinText = $stdin;
-               $this->mockSetUp = True;
+               $this->mockSetUp = true;
        }
 
        /**
@@ -44,23 +42,21 @@ class SemiMockedFetchText extends FetchText {
         * @return Array An array, whose keys are function names. The corresponding values
         * denote the number of times the function has been invoked.
         */
-       function mockGetInvocations()
-       {
+       function mockGetInvocations() {
                return $this->mockInvocations;
        }
 
        // -----------------------------------------------------------------
        // Mocked functions from FetchText follow.
 
-       function getStdin( $len = null )
-       {
+       function getStdin( $len = null ) {
                $this->mockInvocations['getStdin']++;
                if ( $len !== null ) {
                        throw new PHPUnit_Framework_ExpectationFailedException(
                                "Tried to get stdin with non null parameter" );
                }
 
-               if ( ! $this->mockSetUp ) {
+               if ( !$this->mockSetUp ) {
                        throw new PHPUnit_Framework_ExpectationFailedException(
                                "Tried to get stdin before setting up rerouting" );
                }
@@ -175,7 +171,6 @@ class FetchTextTest extends MediaWikiTestCase {
        }
 
 
-
        // Instead of the following functions, a data provider would be great.
        // However, as data providers are evaluated /before/ addDBData, a data
        // provider would not know the required ids.
@@ -192,14 +187,14 @@ class FetchTextTest extends MediaWikiTestCase {
 
        function testExistingSeveral() {
                $this->assertFilter( "$this->textId1\n$this->textId5\n"
-                       . "$this->textId3\n$this->textId3",
+                               . "$this->textId3\n$this->textId3",
                        implode( "", array(
-                                       $this->textId1 . "\n23\nFetchTextTestPage1Text1",
-                                       $this->textId5 . "\n44\nFetchTextTestPage2Text4 "
+                               $this->textId1 . "\n23\nFetchTextTestPage1Text1",
+                               $this->textId5 . "\n44\nFetchTextTestPage2Text4 "
                                        . "some additional Text",
-                                       $this->textId3 . "\n23\nFetchTextTestPage2Text2",
-                                       $this->textId3 . "\n23\nFetchTextTestPage2Text2"
-                               ) ) );
+                               $this->textId3 . "\n23\nFetchTextTestPage2Text2",
+                               $this->textId3 . "\n23\nFetchTextTestPage2Text2"
+                       ) ) );
        }
 
        function testEmpty() {
@@ -231,15 +226,15 @@ class FetchTextTest extends MediaWikiTestCase {
 
        function testMix() {
                $this->assertFilter( "ab\n" . $this->textId4 . ".5cd\n\nefg\n" . $this->textId2
-                       . "\n" . $this->textId3,
+                               . "\n" . $this->textId3,
                        implode( "", array(
-                                       "0\n-1\n",
-                                       $this->textId4 . "\n23\nFetchTextTestPage2Text3",
-                                       "0\n-1\n",
-                                       "0\n-1\n",
-                                       $this->textId2 . "\n23\nFetchTextTestPage2Text1",
-                                       $this->textId3 . "\n23\nFetchTextTestPage2Text2"
-                               ) ) );
+                               "0\n-1\n",
+                               $this->textId4 . "\n23\nFetchTextTestPage2Text3",
+                               "0\n-1\n",
+                               "0\n-1\n",
+                               $this->textId2 . "\n23\nFetchTextTestPage2Text1",
+                               $this->textId3 . "\n23\nFetchTextTestPage2Text2"
+                       ) ) );
        }
 
 }
index 0b7c758..699571b 100644 (file)
@@ -52,11 +52,11 @@ class GetSlaveServerTest extends MediaWikiTestCase {
 
                // The main answer
                $output = $this->getActualOutput();
-               $firstLineEndPos = strpos( $output,"\n");
-               if ( $firstLineEndPos === FALSE ) {
+               $firstLineEndPos = strpos( $output, "\n" );
+               if ( $firstLineEndPos === false ) {
                        $this->fail( "Could not find end of first line of output" );
                }
-               $firstLine = substr( $output, 0 , $firstLineEndPos );
+               $firstLine = substr( $output, 0, $firstLineEndPos );
                $this->assertRegExp( "/^" . self::getServerRE() . "$/D",
                        $firstLine, "DB Server" );
 
index bcbf4ec..2a0298a 100755 (executable)
@@ -21,10 +21,10 @@ class PHPUnitMaintClass extends Maintenance {
 
        function __construct() {
                parent::__construct();
-               $this->addOption( 'with-phpunitdir'
-                       , 'Directory to include PHPUnit from, for example when using a git fetchout from upstream. Path will be prepended to PHP `include_path`.'
-                       , false # not required
-                       , true  # need arg
+               $this->addOption( 'with-phpunitdir',
+                       'Directory to include PHPUnit from, for example when using a git fetchout from upstream. Path will be prepended to PHP `include_path`.',
+                       false, # not required
+                       true # need arg
                );
        }
 
@@ -49,26 +49,26 @@ class PHPUnitMaintClass extends Maintenance {
                // Assume UTC for testing purposes
                $wgLocaltimezone = 'UTC';
 
-               $wgLocalisationCacheConf['storeClass'] =  'LCStore_Null';
+               $wgLocalisationCacheConf['storeClass'] = 'LCStore_Null';
        }
 
        public function execute() {
                global $IP;
 
                # Make sure we have --configuration or PHPUnit might complain
-               if( !in_array( '--configuration', $_SERVER['argv'] ) ) {
+               if ( !in_array( '--configuration', $_SERVER['argv'] ) ) {
                        //Hack to eliminate the need to use the Makefile (which sucks ATM)
                        array_splice( $_SERVER['argv'], 1, 0,
                                array( '--configuration', $IP . '/tests/phpunit/suite.xml' ) );
                }
 
                # --with-phpunitdir let us override the default PHPUnit version
-               if( $phpunitDir = $this->getOption( 'with-phpunitdir' ) ) {
+               if ( $phpunitDir = $this->getOption( 'with-phpunitdir' ) ) {
                        # Sanity checks
-                       if( !is_dir($phpunitDir) ) {
+                       if ( !is_dir( $phpunitDir ) ) {
                                $this->error( "--with-phpunitdir should be set to an existing directory", 1 );
                        }
-                       if( !is_readable( $phpunitDir."/PHPUnit/Runner/Version.php" ) ) {
+                       if ( !is_readable( $phpunitDir . "/PHPUnit/Runner/Version.php" ) ) {
                                $this->error( "No usable PHPUnit installation in $phpunitDir.\nAborting.\n", 1 );
                        }
 
@@ -80,8 +80,8 @@ class PHPUnitMaintClass extends Maintenance {
                        # Cleanup $args array so the option and its value do not
                        # pollute PHPUnit
                        $key = array_search( '--with-phpunitdir', $_SERVER['argv'] );
-                       unset( $_SERVER['argv'][$key]   ); // the option
-                       unset( $_SERVER['argv'][$key+1] ); // its value
+                       unset( $_SERVER['argv'][$key] ); // the option
+                       unset( $_SERVER['argv'][$key + 1] ); // its value
                        $_SERVER['argv'] = array_values( $_SERVER['argv'] );
 
                }
@@ -97,8 +97,9 @@ require( RUN_MAINTENANCE_IF_MAIN );
 
 require_once( 'PHPUnit/Runner/Version.php' );
 
-if( PHPUnit_Runner_Version::id() !== '@package_version@'
-   && version_compare( PHPUnit_Runner_Version::id(), '3.6.7', '<' ) ) {
+if ( PHPUnit_Runner_Version::id() !== '@package_version@'
+       && version_compare( PHPUnit_Runner_Version::id(), '3.6.7', '<' )
+) {
        die( 'PHPUnit 3.6.7 or later required, you have ' . PHPUnit_Runner_Version::id() . ".\n" );
 }
 require_once( 'PHPUnit/Autoload.php' );
index 18db399..71b8c67 100644 (file)
@@ -62,7 +62,7 @@ class ResourcesTest extends MediaWikiTestCase {
 
                foreach ( $rl->getModuleNames() as $moduleName ) {
                        $module = $rl->getModule( $moduleName );
-                       if ( ! $module instanceof ResourceLoaderFileModule ) {
+                       if ( !$module instanceof ResourceLoaderFileModule ) {
                                continue;
                        }
 
index 89337f4..3902b68 100644 (file)
@@ -10,10 +10,6 @@ class SideBarTest extends MediaWikiLangTestCase {
        /** Local cache for sidebar messages */
        private $messages;
 
-       function __construct() {
-               parent::__construct();
-       }
-
        /** Build $this->messages array */
        private function initMessagesHref() {
                # List of default messages for the sidebar:
@@ -26,8 +22,8 @@ class SideBarTest extends MediaWikiLangTestCase {
                        'helppage',
                );
 
-               foreach( $URL_messages as $m ) {
-                       $titleName = MessageCache::singleton()->get($m);
+               foreach ( $URL_messages as $m ) {
+                       $titleName = MessageCache::singleton()->get( $m );
                        $title = Title::newFromText( $titleName );
                        $this->messages[$m]['href'] = $title->getLocalURL();
                }
@@ -39,6 +35,7 @@ class SideBarTest extends MediaWikiLangTestCase {
                $this->skin = new SkinTemplate();
                $this->skin->getContext()->setLanguage( Language::factory( 'en' ) );
        }
+
        protected function tearDown() {
                parent::tearDown();
                $this->skin = null;
@@ -58,11 +55,11 @@ class SideBarTest extends MediaWikiLangTestCase {
 
        function testSidebarWithOnlyTwoTitles() {
                $this->assertSideBar(
-               array(
-                       'Title1' => array(),
-                       'Title2' => array(),
-               ),
-'* Title1
+                       array(
+                               'Title1' => array(),
+                               'Title2' => array(),
+                       ),
+                       '* Title1
 * Title2
 '
                );
@@ -70,15 +67,15 @@ class SideBarTest extends MediaWikiLangTestCase {
 
        function testExpandMessages() {
                $this->assertSidebar(
-               array( 'Title' => array(
-                       array(
-                               'text' => 'Help',
-                               'href' => $this->messages['helppage']['href'],
-                               'id' => 'n-help',
-                               'active' => null
-                       )
-               )),
-'* Title
+                       array( 'Title' => array(
+                               array(
+                                       'text' => 'Help',
+                                       'href' => $this->messages['helppage']['href'],
+                                       'id' => 'n-help',
+                                       'active' => null
+                               )
+                       ) ),
+                       '* Title
 ** helppage|help
 '
                );
@@ -86,63 +83,62 @@ class SideBarTest extends MediaWikiLangTestCase {
 
        function testExternalUrlsRequireADescription() {
                $this->assertSidebar(
-               array( 'Title' => array(
-                       # ** http://www.mediawiki.org/| Home
-                       array(
-                               'text'   => 'Home',
-                               'href'   => 'http://www.mediawiki.org/',
-                               'id'     => 'n-Home',
-                               'active' => null,
-                               'rel'    => 'nofollow',
-                       ),
-                       # ** http://valid.no.desc.org/
-                       # ... skipped since it is missing a pipe with a description
-               )),
-'* Title
+                       array( 'Title' => array(
+                               # ** http://www.mediawiki.org/| Home
+                               array(
+                                       'text' => 'Home',
+                                       'href' => 'http://www.mediawiki.org/',
+                                       'id' => 'n-Home',
+                                       'active' => null,
+                                       'rel' => 'nofollow',
+                               ),
+                               # ** http://valid.no.desc.org/
+                               # ... skipped since it is missing a pipe with a description
+                       ) ),
+                       '* Title
 ** http://www.mediawiki.org/| Home
 ** http://valid.no.desc.org/
 '
-
                );
 
        }
+
        /**
         * bug 33321 - Make sure there's a | after transforming.
         * @group Database
         */
        function testTrickyPipe() {
                $this->assertSidebar(
-               array( 'Title' => array(
-                       # The first 2 are skipped
-                       # Doesn't really test the url properly
-                       # because it will vary with $wgArticlePath et al.
-                       # ** Baz|Fred
-                       array(
-                               'text'   => 'Fred',
-                               'href'   => Title::newFromText( 'Baz' )->getLocalUrl(),
-                               'id'     => 'n-Fred',
-                               'active' => null,
-                       ),
-                       array(
-                               'text'   => 'title-to-display',
-                               'href'   => Title::newFromText( 'page-to-go-to' )->getLocalUrl(),
-                               'id'     => 'n-title-to-display',
-                               'active' => null,
-                       ),
-               )),
-'* Title
+                       array( 'Title' => array(
+                               # The first 2 are skipped
+                               # Doesn't really test the url properly
+                               # because it will vary with $wgArticlePath et al.
+                               # ** Baz|Fred
+                               array(
+                                       'text' => 'Fred',
+                                       'href' => Title::newFromText( 'Baz' )->getLocalUrl(),
+                                       'id' => 'n-Fred',
+                                       'active' => null,
+                               ),
+                               array(
+                                       'text' => 'title-to-display',
+                                       'href' => Title::newFromText( 'page-to-go-to' )->getLocalUrl(),
+                                       'id' => 'n-title-to-display',
+                                       'active' => null,
+                               ),
+                       ) ),
+                       '* Title
 ** {{PAGENAME|Foo}}
 ** Bar
 ** Baz|Fred
 ** {{PLURAL:1|page-to-go-to{{int:pipe-separator/en}}title-to-display|branch not taken}}
 '
                );
-
        }
 
 
        #### Attributes for external links ##########################
-       private function getAttribs( ) {
+       private function getAttribs() {
                # Sidebar text we will use everytime
                $text = '* Title
 ** http://www.mediawiki.org/| Home';
index f286fa1..56f6447 100644 (file)
@@ -8,8 +8,8 @@
          convertNoticesToExceptions="true"
          convertWarningsToExceptions="true"
          stopOnFailure="false"
-                timeoutForSmallTests="2"
-                timeoutForMediumTests="10"
+                timeoutForSmallTests="10"
+                timeoutForMediumTests="30"
                 timeoutForLargeTests="60"
          strict="true"
                 verbose="true">
index d728807..eec773d 100644 (file)
@@ -1,4 +1,4 @@
-<?php 
+<?php
 /**
  * This test suite runs unit tests registered by extensions.
  * See http://www.mediawiki.org/wiki/Manual:Hooks/UnitTestsList for details of how to register your tests.
index 366d8f2..28d38ab 100644 (file)
@@ -17,8 +17,8 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
 
        protected function setUp() {
                global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc,
-                         $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache,
-                         $wgNamespaceAliases, $wgNamespaceProtection, $parserMemc;
+                       $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache,
+                       $wgNamespaceAliases, $wgNamespaceProtection, $parserMemc;
 
                $tmpGlobals = array();
 
@@ -29,18 +29,18 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                $tmpGlobals['wgStylePath'] = '/skins';
                $tmpGlobals['wgThumbnailScriptPath'] = false;
                $tmpGlobals['wgLocalFileRepo'] = array(
-                       'class'           => 'LocalRepo',
-                       'name'            => 'local',
-                       'url'             => 'http://example.com/images',
-                       'hashLevels'      => 2,
+                       'class' => 'LocalRepo',
+                       'name' => 'local',
+                       'url' => 'http://example.com/images',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'local-backend',
                                'lockManager' => 'fsLockManager',
                                'containerPaths' => array(
-                                       'local-public'  => wfTempDir() . '/test-repo/public',
-                                       'local-thumb'   => wfTempDir() . '/test-repo/thumb',
-                                       'local-temp'    => wfTempDir() . '/test-repo/temp',
+                                       'local-public' => wfTempDir() . '/test-repo/public',
+                                       'local-thumb' => wfTempDir() . '/test-repo/thumb',
+                                       'local-temp' => wfTempDir() . '/test-repo/temp',
                                        'local-deleted' => wfTempDir() . '/test-repo/delete',
                                )
                        ) ),
@@ -72,7 +72,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                $wgRequest = $context->getRequest();
 
                if ( $wgStyleDirectory === false ) {
-                       $wgStyleDirectory   = "$IP/skins";
+                       $wgStyleDirectory = "$IP/skins";
                }
 
                RepoGroup::destroySingleton();
@@ -105,7 +105,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
 
                // delete the files first, then the dirs.
                self::deleteFiles(
-                       array (
+                       array(
                                "$dir/3/3a/Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
@@ -117,7 +117,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                );
 
                self::deleteDirs(
-                       array (
+                       array(
                                "$dir/3/3a",
                                "$dir/3",
                                "$dir/thumb/6/65",
index 911dc3a..774000b 100644 (file)
@@ -85,9 +85,9 @@ class GenerateJqueryMsgData extends Maintenance {
        );
 
        public function __construct() {
-                       parent::__construct();
-                       $this->mDescription = 'Create a specification for message parsing ini JSON format';
-                       // add any other options here
+               parent::__construct();
+               $this->mDescription = 'Create a specification for message parsing ini JSON format';
+               // add any other options here
        }
 
        public function execute() {
@@ -100,7 +100,7 @@ class GenerateJqueryMsgData extends Maintenance {
                $tests = array();
                foreach ( array( 'en', 'fr', 'ar', 'jp', 'zh' ) as $languageCode ) {
                        foreach ( self::$keyToTestArgs as $key => $testArgs ) {
-                               foreach ($testArgs as $args) {
+                               foreach ( $testArgs as $args ) {
                                        // Get the raw message, without any transformations.
                                        $template = wfMessage( $key )->inLanguage( $languageCode )->plain();
 
@@ -132,14 +132,14 @@ class GenerateJqueryMsgData extends Maintenance {
 
                $output =
                        "// This file stores the output from the PHP parser for various messages, arguments,\n"
-                       . "// languages, and parser modes. Intended for use by a unit test framework by looping\n"
-                       . "// through the object and comparing its parser return value with the 'result' property.\n"
-                       . '// Last generated with ' . basename( __FILE__ ) . ' at ' . gmdate( 'r' ) . "\n"
-                       // This file will contain unquoted JSON strings as javascript native object literals,
-                       // flip the quotemark convention for this file.
-                       . "/*jshint quotmark: double */\n"
-                       . "\n"
-                       . 'mediaWiki.libs.phpParserData = ' . FormatJson::encode( $phpParserData, true ) . ";\n";
+                               . "// languages, and parser modes. Intended for use by a unit test framework by looping\n"
+                               . "// through the object and comparing its parser return value with the 'result' property.\n"
+                               . '// Last generated with ' . basename( __FILE__ ) . ' at ' . gmdate( 'r' ) . "\n"
+                               // This file will contain unquoted JSON strings as javascript native object literals,
+                               // flip the quotemark convention for this file.
+                               . "/*jshint quotmark: double */\n"
+                               . "\n"
+                               . 'mediaWiki.libs.phpParserData = ' . FormatJson::encode( $phpParserData, true ) . ";\n";
 
                $fp = file_put_contents( $dataSpecFile, $output );
                if ( $fp === false ) {
index 25c42d6..3ed5514 100644 (file)
@@ -1,2 +1,2 @@
 QUnit.start();
-QUnit.assert.ok( true, 'Successfully loaded!');
+QUnit.assert.ok( true, 'Successfully loaded!' );
index 1870d5a..0e84581 100644 (file)
@@ -47,9 +47,9 @@ $wait = isset( $params['wait'] ) ? (int)$params['wait'] : 0; // seconds
 
 sleep( $wait );
 
-$css =  "
+$css = "
 /**
- * Generated " . gmdate( 'r' ) .  ".
+ * Generated " . gmdate( 'r' ) . ".
  * Waited {$wait}s.
  */
 
index 0c3d364..77db213 100644 (file)
@@ -52,7 +52,7 @@
        /**
         * CompletenessTest
         */
-       // Adds toggle checkbox to header
+        // Adds toggle checkbox to header
        QUnit.config.urlConfig.push( {
                id: 'completenesstest',
                label: 'Run CompletenessTest',
@@ -92,7 +92,7 @@
        /**
         * Test environment recommended for all QUnit test modules
         */
-       // Whether to log environment changes to the console
+        // Whether to log environment changes to the console
        QUnit.config.urlConfig.push( 'mwlogenv' );
 
        /**
                liveMessages = mw.messages.values;
 
                function freshConfigCopy( custom ) {
-                       // "deep=true" is important here.
-                       // Otherwise we just create a new object with values referring to live config.
-                       // e.g. mw.config.set( 'wgFileExtensions', [] ) would not effect liveConfig,
-                       // but mw.config.get( 'wgFileExtensions' ).push( 'png' ) would as the array
-                       // was passed by reference in $.extend's loop.
-                       return $.extend( {}, liveConfig, custom, /*deep=*/true );
+                       // Tests should mock all factors that directly influence the tested code.
+                       // For backwards compatibility though we set mw.config to a copy of the live config
+                       // and extend it with the (optionally) given custom settings for this test
+                       // (instead of starting blank with only the given custmo settings).
+                       // This is a shallow copy, so we don't end up with settings taking an array value
+                       // extended with the custom settings - setting a config property means you override it,
+                       // not extend it.
+                       return $.extend( {}, liveConfig, custom );
                }
 
                function freshMessagesCopy( custom ) {
-                       return $.extend( {}, liveMessages, custom, /*deep=*/true );
+                       return $.extend( /*deep=*/true, {}, liveMessages, custom );
                }
 
                log = QUnit.urlParams.mwlogenv ? mw.log : function () {};
                        // Whether this one fails or not, forwards it to
                        // the 'done' (resolve) callback of the alternative promise.
                        arg.always( alt.resolve );
-               });
+               } );
 
                return $.when.apply( $, altPromises );
        };
         * initializations defined above in this file.
         */
        envExecCount = 0;
-       QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment({
+       QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment( {
                setup: function () {
                        envExecCount += 1;
                        this.mwHtmlLive = mw.html;
                messages: {
                        testMsg: 'Foo.'
                }
-       }) );
+       } ) );
 
        QUnit.test( 'Setup', 3, function ( assert ) {
                assert.equal( mw.html.escape( 'foo' ), 'mocked-1', 'extra setup() callback was ran.' );
 
                mw.config.set( 'testVar', 'bar' );
                mw.messages.set( 'testMsg', 'Bar.' );
-       });
+       } );
 
        QUnit.test( 'Teardown', 3, function ( assert ) {
                assert.equal( mw.html.escape( 'foo' ), 'mocked-2', 'extra setup() callback was re-ran.' );
                assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object restored and re-applied after test()' );
                assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' );
-       });
+       } );
 
        QUnit.module( 'mediawiki.tests.qunit.testrunner-after', QUnit.newMwEnvironment() );
 
                assert.equal( mw.html.escape( '<' ), '&lt;', 'extra teardown() callback was ran.' );
                assert.equal( mw.config.get( 'testVar' ), null, 'config object restored to live in next module()' );
                assert.equal( mw.messages.get( 'testMsg' ), null, 'messages object restored to live in next module()' );
-       });
+       } );
 
 }( jQuery, mediaWiki, QUnit ) );
index feeec55..e189524 100644 (file)
@@ -53,6 +53,6 @@
                } else {
                        assert.gt( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more)' );
                }
-       });
+       } );
 
 }( jQuery ) );
index 378ea4b..e4e579b 100644 (file)
@@ -2,7 +2,7 @@
        QUnit.module( 'jquery.byteLength', QUnit.newMwEnvironment() );
 
        QUnit.test( 'Simple text', 5, function ( assert ) {
-               var     azLc = 'abcdefghijklmnopqrstuvwxyz',
+               var azLc = 'abcdefghijklmnopqrstuvwxyz',
                        azUc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                        num = '0123456789',
                        x = '*',
index 2990de2..c21844e 100644 (file)
        // Basic sendkey-implementation
        function addChars( $input, charstr ) {
                var c, len;
+
                function x( $input, i ) {
                        // Add character to the value
                        return $input.val() + charstr.charAt( i );
                }
+
                for ( c = 0, len = charstr.length; c < len; c += 1 ) {
                        $input
                                .val( x( $input, c ) )
         * The limit should be less than 20 (the sample data's length)
         */
        function byteLimitTest( options ) {
-               var opt = $.extend({
+               var opt = $.extend( {
                        description: '',
                        $input: null,
                        sample: '',
                        hasLimit: false,
                        expected: '',
                        limit: null
-               }, options);
+               }, options );
 
                QUnit.asyncTest( opt.description, opt.hasLimit ? 3 : 2, function ( assert ) {
-               setTimeout( function () {
-                       var rawVal, fn, effectiveVal;
-
-                       opt.$input.appendTo( '#qunit-fixture' );
-
-                       // Simulate pressing keys for each of the sample characters
-                       addChars( opt.$input, opt.sample );
-
-                       rawVal = opt.$input.val();
-                       fn = opt.$input.data( 'byteLimit.callback' );
-                       effectiveVal = fn ? fn( rawVal ) : rawVal;
-
-                       if ( opt.hasLimit ) {
-                               assert.ltOrEq(
-                                       $.byteLength( effectiveVal ),
-                                       opt.limit,
-                                       'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
-                               );
-                               assert.equal(
-                                       $.byteLength( rawVal ),
-                                       $.byteLength( opt.expected ),
-                                       'Not preventing keypresses too early, length has reached the expected length'
-                               );
-                               assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
-
-                       } else {
-                               assert.equal(
-                                       $.byteLength( effectiveVal ),
-                                       $.byteLength( opt.expected ),
-                                       'Unlimited scenarios are not affected, expected length reached'
-                               );
-                               assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
-                       }
-                       QUnit.start();
-               }, 10 );
+                       setTimeout( function () {
+                               var rawVal, fn, effectiveVal;
+
+                               opt.$input.appendTo( '#qunit-fixture' );
+
+                               // Simulate pressing keys for each of the sample characters
+                               addChars( opt.$input, opt.sample );
+
+                               rawVal = opt.$input.val();
+                               fn = opt.$input.data( 'byteLimit.callback' );
+                               effectiveVal = fn ? fn( rawVal ) : rawVal;
+
+                               if ( opt.hasLimit ) {
+                                       assert.ltOrEq(
+                                               $.byteLength( effectiveVal ),
+                                               opt.limit,
+                                               'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
+                                       );
+                                       assert.equal(
+                                               $.byteLength( rawVal ),
+                                               $.byteLength( opt.expected ),
+                                               'Not preventing keypresses too early, length has reached the expected length'
+                                       );
+                                       assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
+
+                               } else {
+                                       assert.equal(
+                                               $.byteLength( effectiveVal ),
+                                               $.byteLength( opt.expected ),
+                                               'Unlimited scenarios are not affected, expected length reached'
+                                       );
+                                       assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
+                               }
+                               QUnit.start();
+                       }, 10 );
                } );
        }
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Plain text input',
                $input: $( '<input type="text"/>' ),
                sample: simpleSample,
                hasLimit: false,
                expected: simpleSample
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Plain text input. Calling byteLimit with no parameters and no maxlength attribute (bug 36310)',
                $input: $( '<input type="text"/>' )
                        .byteLimit(),
                sample: simpleSample,
                hasLimit: false,
                expected: simpleSample
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using the maxlength attribute',
                $input: $( '<input type="text"/>' )
                        .attr( 'maxlength', '10' )
                hasLimit: true,
                limit: 10,
                expected: '1234567890'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 10 ),
                hasLimit: true,
                limit: 10,
                expected: '1234567890'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value, overriding maxlength attribute',
                $input: $( '<input type="text"/>' )
                        .attr( 'maxlength', '10' )
                hasLimit: true,
                limit: 15,
                expected: '123456789012345'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value (multibyte)',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 14 ),
                hasLimit: true,
                limit: 14,
                expected: '1234567890' + U_20AC + '1'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value (multibyte) overlapping a byte',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 12 ),
                hasLimit: true,
                limit: 12,
                expected: '1234567890' + '12'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Pass the limit and a callback as input filter',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 6, function ( val ) {
                hasLimit: true,
                limit: 6, // 'Sample' length
                expected: 'User:Sample'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using the maxlength attribute and pass a callback as input filter',
                $input: $( '<input type="text"/>' )
                        .attr( 'maxlength', '6' )
                hasLimit: true,
                limit: 6, // 'Sample' length
                expected: 'User:Sample'
-       });
+       } );
 
        QUnit.test( 'Confirm properties and attributes set', 4, function ( assert ) {
                var $el, $elA, $elB;
                assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' );
 
                $el.byteLimit();
-       });
+       } );
 
        QUnit.test( 'Trim from insertion when limit exceeded', 2, function ( assert ) {
                var $el;
                        .val( 'azbc' ).trigger( 'change' );
 
                assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 1), not the end' );
-       });
-
+       } );
 }( jQuery, mediaWiki ) );
index 29c6657..88bbf5c 100644 (file)
                                        rtl: true
                                }
                        },
+                       // Iceweasel 10.0.6
+                       'Mozilla/5.0 (X11; Linux i686; rv:10.0.6) Gecko/20100101 Iceweasel/10.0.6': {
+                               title: 'Iceweasel 10.0.6',
+                               platform: 'Linux',
+                               profile: {
+                                       name: 'iceweasel',
+                                       layout: 'gecko',
+                                       layoutVersion: 20100101,
+                                       platform: 'linux',
+                                       version: '10.0.6',
+                                       versionBase: '10',
+                                       versionNumber: 10
+                               },
+                               wikiEditor: {
+                                       ltr: true,
+                                       rtl: true
+                               }
+                       },
                        // Firefox 5
                        // Safari 3
                        // Safari 4
                };
                $.each( uas, function () {
                        uacount++;
-               });
+               } );
                return uas;
        }() );
 
        QUnit.test( 'profile userAgent support', uacount, function ( assert ) {
                // Generate a client profile object and compare recursively
-               var uaTest = function( rawUserAgent, data ) {
+               var uaTest = function ( rawUserAgent, data ) {
                        var ret = $.client.profile( {
                                userAgent: rawUserAgent,
                                platform: data.platform
 
        QUnit.test( 'profile return validation for current user agent', 7, function ( assert ) {
                var p = $.client.profile();
+
                function unknownOrType( val, type, summary ) {
                        assert.ok( typeof val === type || val === 'unknown', summary );
                }
                unknownOrType( p.version, 'string', 'p.version is a string (or "unknown")' );
                unknownOrType( p.versionBase, 'string', 'p.versionBase is a string (or "unknown")' );
                assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' );
-       });
+       } );
 
        // Example from WikiEditor
        // Make sure to use raw numbers, a string like "7.0" would fail on a
 
                assert.equal( typeof testMatch, 'boolean', 'test returns a boolean value' );
 
-       });
+       } );
 
        QUnit.test( 'User-agent matches against WikiEditor\'s compatibility map', uacount * 2, function ( assert ) {
-               var     $body = $( 'body' ),
+               var $body = $( 'body' ),
                        bodyClasses = $body.attr( 'class' );
 
                // Loop through and run tests
                                $body.removeClass( dir );
 
                                assert.equal( testMatch, data.wikiEditor[dir], 'testing comparison based on ' + dir + ', ' + agent );
-                       });
-               });
+                       } );
+               } );
 
                // Restore body classes
                $body.attr( 'class', bodyClasses );
-       });
+       } );
 }( jQuery ) );
index 51a892e..97e0533 100644 (file)
@@ -24,7 +24,7 @@
                assert.deepEqual( $.colorUtil.getRGB( 'lightGreen' ), [144, 238, 144], 'Color names (lightGreen)' );
                assert.deepEqual( $.colorUtil.getRGB( 'transparent' ), [255, 255, 255], 'Color names (transparent)' );
                assert.strictEqual( $.colorUtil.getRGB( 'mediaWiki' ), undefined, 'Inexisting color name' );
-       });
+       } );
 
        QUnit.test( 'rgbToHsl', 1, function ( assert ) {
                var hsl, ret;
                function dualDecimals( a ) {
                        return Math.round( a * 100 ) / 100;
                }
+
                // Re-create the rgbToHsl return array items, limited to two decimals.
                hsl = $.colorUtil.rgbToHsl( 144, 238, 144 );
                ret = [ dualDecimals( hsl[0] ), dualDecimals( hsl[1] ), dualDecimals( hsl[2] ) ];
 
                assert.deepEqual( ret, [0.33, 0.73, 0.75], 'rgb(144, 238, 144): hsl(0.33, 0.73, 0.75)' );
-       });
+       } );
 
        QUnit.test( 'hslToRgb', 1, function ( assert ) {
                var rgb, ret;
                rgb = $.colorUtil.hslToRgb( 0.3, 0.7, 0.8 );
 
                // Re-create the hslToRgb return array items, rounded to whole numbers.
-               ret = [ Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2]) ];
+               ret = [ Math.round( rgb[0] ), Math.round( rgb[1] ), Math.round( rgb[2] ) ];
 
-               assert.deepEqual( ret ,[183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' );
-       });
+               assert.deepEqual( ret[183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' );
+       } );
 
        QUnit.test( 'getColorBrightness', 2, function ( assert ) {
                var a, b;
@@ -58,5 +59,5 @@
 
                b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 );
                assert.equal( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' );
-       });
+       } );
 }( jQuery ) );
index 3e7d5ff..234b19c 100644 (file)
@@ -1,37 +1,37 @@
 ( function ( $ ) {
-       QUnit.asyncTest('jquery.delayedBind with data option', 2, function ( assert ) {
-               var $fixture = $('<div>').appendTo('#qunit-fixture'),
+       QUnit.asyncTest( 'jquery.delayedBind with data option', 2, function ( assert ) {
+               var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ),
                        data = {
                                magic: 'beeswax'
                        },
                        delay = 50;
 
-               $fixture.delayedBind(delay, 'testevent', data, function ( e ) {
-                       assert.ok( true, 'testevent fired');
-                       assert.ok( e.data === data, 'data is passed through delayedBind');
+               $fixture.delayedBind( delay, 'testevent', data, function ( e ) {
+                       assert.ok( true, 'testevent fired' );
+                       assert.ok( e.data === data, 'data is passed through delayedBind' );
                        QUnit.start();
-               });
+               } );
 
                // We'll trigger it thrice, but it should only happen once.
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
-       });
+       } );
 
-       QUnit.asyncTest('jquery.delayedBind without data option', 1, function ( assert ) {
-               var $fixture = $('<div>').appendTo('#qunit-fixture'),
+       QUnit.asyncTest( 'jquery.delayedBind without data option', 1, function ( assert ) {
+               var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ),
                        delay = 50;
 
-               $fixture.delayedBind(delay, 'testevent', function () {
-                       assert.ok(true, 'testevent fired');
+               $fixture.delayedBind( delay, 'testevent', function () {
+                       assert.ok( true, 'testevent fired' );
                        QUnit.start();
-               });
+               } );
 
                // We'll trigger it thrice, but it should only happen once.
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
-       });
+       } );
 }( jQuery ) );
index 82566c2..0b7e87e 100644 (file)
@@ -2,7 +2,7 @@
        QUnit.module( 'jquery.getAttrs', QUnit.newMwEnvironment() );
 
        QUnit.test( 'Check', 1, function ( assert ) {
-               var     attrs = {
+               var attrs = {
                                foo: 'bar',
                                'class': 'lorem'
                        },
index d75c378..906369e 100644 (file)
@@ -1,12 +1,12 @@
 ( function ( $ ) {
        QUnit.module( 'jquery.hidpi', QUnit.newMwEnvironment() );
 
-       QUnit.test( 'devicePixelRatio', function ( assert ) {
+       QUnit.test( 'devicePixelRatio', 1, function ( assert ) {
                var devicePixelRatio = $.devicePixelRatio();
                assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
-       });
+       } );
 
-       QUnit.test( 'matchSrcSet', function ( assert ) {
+       QUnit.test( 'matchSrcSet', 6, function ( assert ) {
                var srcset = 'onefive.png 1.5x, two.png 2x';
 
                // Nice exact matches
@@ -18,5 +18,5 @@
                assert.equal( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' );
                assert.equal( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
                assert.equal( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
-       });
+       } );
 }( jQuery ) );
index 3810a04..d3877e0 100644 (file)
                assert.strictEqual( $lc.length, 1, 'link is created' );
                assert.strictEqual( $lc.text(), 'link', 'the link text got added' );
        } );
-}( jQuery, mediaWiki ) ) ;
+}( jQuery, mediaWiki ) );
index 3ffcbf5..5fae065 100644 (file)
@@ -1,60 +1,57 @@
 ( function ( $ ) {
        QUnit.module( 'jquery.mwExtension', QUnit.newMwEnvironment() );
 
-       QUnit.test( 'String functions', function ( assert ) {
-
+       QUnit.test( 'String functions', 7, function ( assert ) {
                assert.equal( $.trimLeft( '  foo bar  ' ), 'foo bar  ', 'trimLeft' );
                assert.equal( $.trimRight( '  foo bar  ' ), '  foo bar', 'trimRight' );
                assert.equal( $.ucFirst( 'foo' ), 'Foo', 'ucFirst' );
 
                assert.equal( $.escapeRE( '<!-- ([{+mW+}]) $^|?>' ),
-                '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' );
+                       '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' );
                assert.equal( $.escapeRE( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ),
-                'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'escapeRE - Leave uppercase alone' );
+                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'escapeRE - Leave uppercase alone' );
                assert.equal( $.escapeRE( 'abcdefghijklmnopqrstuvwxyz' ),
-                'abcdefghijklmnopqrstuvwxyz', 'escapeRE - Leave lowercase alone' );
+                       'abcdefghijklmnopqrstuvwxyz', 'escapeRE - Leave lowercase alone' );
                assert.equal( $.escapeRE( '0123456789' ), '0123456789', 'escapeRE - Leave numbers alone' );
-       });
-
-       QUnit.test( 'Is functions', function ( assert ) {
+       } );
 
+       QUnit.test( 'Is functions', 15, function ( assert ) {
                assert.strictEqual( $.isDomElement( document.getElementById( 'qunit-header' ) ), true,
-                'isDomElement: #qunit-header Node' );
+                       'isDomElement: #qunit-header Node' );
                assert.strictEqual( $.isDomElement( document.getElementById( 'random-name' ) ), false,
-                'isDomElement: #random-name (null)' );
+                       'isDomElement: #random-name (null)' );
                assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' ) ), false,
-                'isDomElement: getElementsByTagName Array' );
+                       'isDomElement: getElementsByTagName Array' );
                assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' )[0] ), true,
-                'isDomElement: getElementsByTagName(..)[0] Node' );
+                       'isDomElement: getElementsByTagName(..)[0] Node' );
                assert.strictEqual( $.isDomElement( $( 'div' ) ), false,
-                'isDomElement: jQuery object' );
-               assert.strictEqual( $.isDomElement( $( 'div' ).get(0) ), true,
-                'isDomElement: jQuery object > Get node' );
+                       'isDomElement: jQuery object' );
+               assert.strictEqual( $.isDomElement( $( 'div' ).get( 0 ) ), true,
+                       'isDomElement: jQuery object > Get node' );
                assert.strictEqual( $.isDomElement( document.createElement( 'div' ) ), true,
-                'isDomElement: createElement' );
+                       'isDomElement: createElement' );
                assert.strictEqual( $.isDomElement( { foo: 1 } ), false,
-                'isDomElement: Object' );
+                       'isDomElement: Object' );
 
-               assert.strictEqual( $.isEmpty( 'string' ), false, 'isEmptry: "string"' );
-               assert.strictEqual( $.isEmpty( '0' ), true, 'isEmptry: "0"' );
-               assert.strictEqual( $.isEmpty( '' ), true, 'isEmptry: ""' );
-               assert.strictEqual( $.isEmpty( 1 ), false, 'isEmptry: 1' );
-               assert.strictEqual( $.isEmpty( [] ), true, 'isEmptry: []' );
-               assert.strictEqual( $.isEmpty( {} ), true, 'isEmptry: {}' );
+               assert.strictEqual( $.isEmpty( 'string' ), false, 'isEmpty: "string"' );
+               assert.strictEqual( $.isEmpty( '0' ), true, 'isEmpty: "0"' );
+               assert.strictEqual( $.isEmpty( '' ), true, 'isEmpty: ""' );
+               assert.strictEqual( $.isEmpty( 1 ), false, 'isEmpty: 1' );
+               assert.strictEqual( $.isEmpty( [] ), true, 'isEmpty: []' );
+               assert.strictEqual( $.isEmpty( {} ), true, 'isEmpty: {}' );
 
                // Documented behaviour
-               assert.strictEqual( $.isEmpty( { length: 0 } ), true, 'isEmptry: { length: 0 }' );
-       });
-
-       QUnit.test( 'Comparison functions', function ( assert ) {
+               assert.strictEqual( $.isEmpty( { length: 0 } ), true, 'isEmpty: { length: 0 }' );
+       } );
 
+       QUnit.test( 'Comparison functions', 5, function ( assert ) {
                assert.ok( $.compareArray( [0, 'a', [], [2, 'b'] ], [0, 'a', [], [2, 'b'] ] ),
-                'compareArray: Two deep arrays that are excactly the same' );
+                       'compareArray: Two deep arrays that are excactly the same' );
                assert.ok( !$.compareArray( [1], [2] ), 'compareArray: Two different arrays (false)' );
 
                assert.ok( $.compareObject( {}, {} ), 'compareObject: Two empty objects' );
                assert.ok( $.compareObject( { foo: 1 }, { foo: 1 } ), 'compareObject: Two the same objects' );
                assert.ok( !$.compareObject( { bar: true }, { baz: false } ),
-                'compareObject: Two different objects (false)' );
-       });
+                       'compareObject: Two different objects (false)' );
+       } );
 }( jQuery ) );
index e31fc63..1213793 100644 (file)
@@ -3,35 +3,33 @@
 
        QUnit.test( 'firstTabIndex', 2, function ( assert ) {
                var html, $testA, $testB;
-               html =
-       '<form>' +
-               '<input tabindex="7" />' +
-               '<input tabindex="9" />' +
-               '<textarea tabindex="2">Foobar</textarea>' +
-               '<textarea tabindex="5">Foobar</textarea>' +
-       '</form>';
+               html = '<form>' +
+                       '<input tabindex="7" />' +
+                       '<input tabindex="9" />' +
+                       '<textarea tabindex="2">Foobar</textarea>' +
+                       '<textarea tabindex="5">Foobar</textarea>' +
+                       '</form>';
 
                $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' );
                assert.strictEqual( $testA.firstTabIndex(), 2, 'First tabindex should be 2 within this context.' );
 
                $testB = $( '<div>' );
                assert.strictEqual( $testB.firstTabIndex(), null, 'Return null if none available.' );
-       });
+       } );
 
        QUnit.test( 'lastTabIndex', 2, function ( assert ) {
                var html, $testA, $testB;
-               html =
-       '<form>' +
-               '<input tabindex="7" />' +
-               '<input tabindex="9" />' +
-               '<textarea tabindex="2">Foobar</textarea>' +
-               '<textarea tabindex="5">Foobar</textarea>' +
-       '</form>';
+               html = '<form>' +
+                       '<input tabindex="7" />' +
+                       '<input tabindex="9" />' +
+                       '<textarea tabindex="2">Foobar</textarea>' +
+                       '<textarea tabindex="5">Foobar</textarea>' +
+                       '</form>';
 
                $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' );
                assert.strictEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' );
 
                $testB = $( '<div>' );
                assert.strictEqual( $testB.lastTabIndex(), null, 'Return null if none available.' );
-       });
+       } );
 }( jQuery ) );
index 0000f0c..deff5b0 100644 (file)
@@ -8,7 +8,7 @@
                wgContentLanguage: 'en'
        };
 
-       QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment({ config: config }) );
+       QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment( { config: config } ) );
 
        /**
         * Create an HTML table from an array of row arrays containing text strings.
@@ -18,7 +18,7 @@
         * @param {String[][]} data
         * @return jQuery
         */
-       function tableCreate(  header, data ) {
+       function tableCreate( header, data ) {
                var i,
                        $table = $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ),
                        $thead = $table.find( 'thead' ),
@@ -28,7 +28,7 @@
                $.each( header, function ( i, str ) {
                        var $th = $( '<th>' );
                        $th.text( str ).appendTo( $tr );
-               });
+               } );
                $tr.appendTo( $thead );
 
                for ( i = 0; i < data.length; i++ ) {
@@ -37,7 +37,7 @@
                        $.each( data[i], function ( j, str ) {
                                var $td = $( '<td>' );
                                $td.text( str ).appendTo( $tr );
-                       });
+                       } );
                        $tr.appendTo( $tbody );
                }
                return $table;
        function tableExtract( $table ) {
                var data = [];
 
-               $table.find( 'tbody' ).find( 'tr' ).each( function( i, tr ) {
+               $table.find( 'tbody' ).find( 'tr' ).each( function ( i, tr ) {
                        var row = [];
-                       $( tr ).find( 'td,th' ).each( function( i, td ) {
+                       $( tr ).find( 'td,th' ).each( function ( i, td ) {
                                row.push( $( td ).text() );
-                       });
+                       } );
                        data.push( row );
-               });
+               } );
                return data;
        }
 
                        // to asynchronous, we'll need a timeout or a callback here.
                        var extracted = tableExtract( $table );
                        assert.deepEqual( extracted, expected, msg );
-               });
+               } );
        }
 
-       function reversed(arr) {
+       function reversed( arr ) {
                // Clone array
-               var arr2 = arr.slice(0);
+               var arr2 = arr.slice( 0 );
 
                arr2.reverse();
 
        }
 
        // Sample data set using planets named and their radius
-       var header  = [ 'Planet' , 'Radius (km)'],
+       var header = [ 'Planet' , 'Radius (km)'],
                mercury = [ 'Mercury', '2439.7' ],
-               venus   = [ 'Venus'  , '6051.8' ],
-               earth   = [ 'Earth'  , '6371.0' ],
-               mars    = [ 'Mars'   , '3390.0' ],
-               jupiter = [ 'Jupiter',  '69911' ],
-               saturn  = [ 'Saturn' ,  '58232' ];
+               venus = [ 'Venus'  , '6051.8' ],
+               earth = [ 'Earth'  , '6371.0' ],
+               mars = [ 'Mars'   , '3390.0' ],
+               jupiter = [ 'Jupiter', '69911' ],
+               saturn = [ 'Saturn' , '58232' ];
 
        // Initial data set
-       var planets         = [mercury, venus, earth, mars, jupiter, saturn];
-       var ascendingName   = [earth, jupiter, mars, mercury, saturn, venus];
+       var planets = [mercury, venus, earth, mars, jupiter, saturn];
+       var ascendingName = [earth, jupiter, mars, mercury, saturn, venus];
        var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter];
 
        tableTest(
                planets,
                ascendingName,
                function ( $table ) {
-                       $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
+                       $table.tablesorter( { sortList: [
+                               { 0: 'asc' }
+                       ] } );
                }
        );
        tableTest(
                'Basic planet table: sorting initially - descending by radius',
                header,
                planets,
-               reversed(ascendingRadius),
+               reversed( ascendingRadius ),
                function ( $table ) {
-                       $table.tablesorter( { sortList: [ { 1: 'desc' } ] } );
+                       $table.tablesorter( { sortList: [
+                               { 1: 'desc' }
+                       ] } );
                }
        );
        tableTest(
                'Basic planet table: descending by name',
                header,
                planets,
-               reversed(ascendingName),
+               reversed( ascendingName ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click().click();
                'Basic planet table: descending radius',
                header,
                planets,
-               reversed(ascendingRadius),
+               reversed( ascendingRadius ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(1)' ).click().click();
                asc,
                function ( $table ) {
                        $table.tablesorter(
-                               { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+                               { sortList: [
+                                       { 0: 'asc' },
+                                       { 1: 'asc' }
+                               ] }
                        );
                }
        );
                function ( $table ) {
                        $table.tablesorter();
                        $table.data( 'tablesorter' ).sort(
-                               [ { 0: 'desc' }, { 1: 'asc' } ]
+                               [
+                                       { 0: 'desc' },
+                                       { 1: 'asc' }
+                               ]
                        );
                }
        );
                asc,
                function ( $table ) {
                        $table.tablesorter(
-                               { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+                               { sortList: [
+                                       { 0: 'asc' },
+                                       { 1: 'asc' }
+                               ] }
                        );
                        $table.data( 'tablesorter' ).sort(
-                               [ { 0: 'desc' }, { 1: 'asc' } ]
+                               [
+                                       { 0: 'desc' },
+                                       { 1: 'asc' }
+                               ]
                        );
                        $table.data( 'tablesorter' ).sort();
                }
        QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) {
                var $table = tableCreate( header, initial );
                $table.tablesorter(
-                       { sortList: [ { 0: 'desc' }, { 1: 'asc' } ] }
+                       { sortList: [
+                               { 0: 'desc' },
+                               { 1: 'asc' }
+                       ] }
                );
                $table.data( 'tablesorter' ).sort( [] );
 
        tableTest(
                'Bug 28775: German-style (dmy) short numeric dates',
                ['Date'],
-               [ // German-style dates are day-month-year
+               [
+                       // German-style dates are day-month-year
                        ['11.11.2011'],
                        ['01.11.2011'],
                        ['02.10.2011'],
                        ['03.08.2011'],
                        ['09.11.2011']
                ],
-               [ // Sorted by ascending date
+               [
+                       // Sorted by ascending date
                        ['03.08.2011'],
                        ['02.10.2011'],
                        ['01.11.2011'],
        tableTest(
                'Bug 28775: American-style (mdy) short numeric dates',
                ['Date'],
-               [ // American-style dates are month-day-year
+               [
+                       // American-style dates are month-day-year
                        ['11.11.2011'],
                        ['01.11.2011'],
                        ['02.10.2011'],
                        ['03.08.2011'],
                        ['09.11.2011']
                ],
-               [ // Sorted by ascending date
+               [
+                       // Sorted by ascending date
                        ['01.11.2011'],
                        ['02.10.2011'],
                        ['03.08.2011'],
                'Bug 17141: IPv4 address sorting (reverse)',
                ['IP'],
                ipv4,
-               reversed(ipv4Sorted),
+               reversed( ipv4Sorted ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click().click();
                                'ä': 'ae',
                                'ö': 'oe',
                                'ß': 'ss',
-                               'ü':'ue'
+                               'ü': 'ue'
                        } );
 
                        $table.tablesorter();
                        3,
                        'Rowspan not exploded'
                );
-       });
+       } );
 
-       var planetsRowspan = [ [ 'Earth', '6051.8' ], jupiter, [ 'Mars', '6051.8' ], mercury, saturn, venus ];
+       var planetsRowspan = [
+               [ 'Earth', '6051.8' ],
+               jupiter,
+               [ 'Mars', '6051.8' ],
+               mercury,
+               saturn,
+               venus
+       ];
        var planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ];
 
        tableTest(
                        //   This covers the removed cell in the 4th and 5th row.
                        $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
 
-                       $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
+                       $table.tablesorter( { sortList: [
+                               { 0: 'asc' }
+                       ] } );
                }
        );
        tableTest(
                }
        );
 
-       var ascendingNameLegacy = ascendingName.slice(0);
+       var ascendingNameLegacy = ascendingName.slice( 0 );
        ascendingNameLegacy[4] = ascendingNameLegacy[5];
        ascendingNameLegacy.pop();
 
                header,
                planets,
                ascendingNameLegacy,
-               function( $table ) {
+               function ( $table ) {
                        $table.find( 'tr:last' ).addClass( 'sortbottom' );
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click();
                var $table;
                $table = $(
                        '<table class="sortable">' +
-                       '<caption>CAPTION</caption>' +
-                       '<tr><th>THEAD</th></tr>' +
-                       '<tr><td>1</td></tr>' +
-                       '<tr class="sortbottom"><td>text</td></tr>' +
-                       '</table>'
+                               '<caption>CAPTION</caption>' +
+                               '<tr><th>THEAD</th></tr>' +
+                               '<tr><td>1</td></tr>' +
+                               '<tr class="sortbottom"><td>text</td></tr>' +
+                               '</table>'
                );
                $table.tablesorter();
                $table.find( '.headerSort:eq(0)' ).click();
                var $table;
                $table = $(
                        '<table class="sortable">' +
-                       '<caption>CAPTION</caption>' +
-                       '<tr><th>THEAD</th></tr>' +
-                       '<tr><td>A</td></tr>' +
-                       '<tr><td>B</td></tr>' +
-                       '<tr class="sortbottom"><td>TFOOT</td></tr>' +
-                       '</table>'
-                       );
+                               '<caption>CAPTION</caption>' +
+                               '<tr><th>THEAD</th></tr>' +
+                               '<tr><td>A</td></tr>' +
+                               '<tr><td>B</td></tr>' +
+                               '<tr class="sortbottom"><td>TFOOT</td></tr>' +
+                               '</table>'
+               );
                $table.tablesorter();
 
                assert.equal(
-                       $table.children( ).get( 0 ).nodeName,
+                       $table.children().get( 0 ).nodeName,
                        'CAPTION',
                        'First element after <thead> must be <caption> (bug 32047)'
                );
-       });
+       } );
 
        QUnit.test( 'data-sort-value attribute, when available, should override sorting position', function ( assert ) {
                var $table, data;
                                '<tr><td data-sort-value="Bananna">Ferret</td></tr>' +
                                '<tr><td data-sort-value="Drupe">Elephant</td></tr>' +
                                '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' +
-                       '</tbody></table>'
+                               '</tbody></table>'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
 
                data = [];
-               $table.find( 'tbody > tr' ).each( function( i, tr ) {
-                       $( tr ).find( 'td' ).each( function( i, td ) {
+               $table.find( 'tbody > tr' ).each( function ( i, tr ) {
+                       $( tr ).find( 'td' ).each( function ( i, td ) {
                                data.push( {
                                        data: $( td ).data( 'sortValue' ),
                                        text: $( td ).text()
                                } );
-                       });
-               });
+                       } );
+               } );
 
                assert.deepEqual( data, [
                        {
                                data: 'Apple',
                                text: 'Bird'
-                       }, {
+                       },
+                       {
                                data: 'Bananna',
                                text: 'Ferret'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'Cheetah'
-                       }, {
+                       },
+                       {
                                data: 'Cherry',
                                text: 'Dolphin'
-                       }, {
+                       },
+                       {
                                data: 'Drupe',
                                text: 'Elephant'
                        }
                                '<tr><td>B</td></tr>' +
                                '<tr><td>G</td></tr>' +
                                '<tr><td data-sort-value="F">C</td></tr>' +
-                       '</tbody></table>'
+                               '</tbody></table>'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
 
                                        data: $( td ).data( 'sortValue' ),
                                        text: $( td ).text()
                                } );
-                       });
-               });
+                       } );
+               } );
 
                assert.deepEqual( data, [
                        {
                                data: undefined,
                                text: 'B'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'D'
-                       }, {
+                       },
+                       {
                                data: 'E',
                                text: 'A'
-                       }, {
+                       },
+                       {
                                data: 'F',
                                text: 'C'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'G'
                        }
                                '<tr><td>B</td></tr>' +
                                '<tr><td data-sort-value="2">G</td></tr>' +
                                '<tr><td>C</td></tr>' +
-                       '</tbody></table>'
+                               '</tbody></table>'
                );
                // initialize table sorter and sort once
                $table
                $table.find( '.headerSort:eq(0)' ).click();
 
                data = [];
-               $table.find( 'tbody > tr' ).each( function( i, tr ) {
-                       $( tr ).find( 'td' ).each( function( i, td ) {
+               $table.find( 'tbody > tr' ).each( function ( i, tr ) {
+                       $( tr ).find( 'td' ).each( function ( i, td ) {
                                data.push( {
                                        data: $( td ).data( 'sortValue' ),
                                        text: $( td ).text()
                                } );
-                       });
-               });
+                       } );
+               } );
 
                assert.deepEqual( data, [
                        {
                                data: 1,
                                text: 'B'
-                       }, {
+                       },
+                       {
                                data: 2,
                                text: 'G'
-                       }, {
+                       },
+                       {
                                data: 3,
                                text: 'A'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'C'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'D'
                        }
                ], 'Order matches expected order, using the current sortValue in $.data()' );
 
-       });
+       } );
 
        var numbers = [
                [ '12'    ],
 
        tableTest( 'bug 8115: sort numbers with commas (ascending)',
                ['Numbers'], numbers, numbersAsc,
-               function( $table ) {
+               function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click();
                }
        );
 
        tableTest( 'bug 8115: sort numbers with commas (descending)',
-               ['Numbers'], numbers, reversed(numbersAsc),
-               function( $table ) {
+               ['Numbers'], numbers, reversed( numbersAsc ),
+               function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click().click();
                }
                var $table;
                $table = $(
                        '<table class="sortable" id="mw-bug-32888">' +
-                       '<tr><th>header<table id="mw-bug-32888-2">'+
+                               '<tr><th>header<table id="mw-bug-32888-2">' +
                                '<tr><th>1</th><th>2</th></tr>' +
-                       '</table></th></tr>' +
-                       '<tr><td>A</td></tr>' +
-                       '<tr><td>B</td></tr>' +
-                       '</table>'
-                       );
+                               '</table></th></tr>' +
+                               '<tr><td>A</td></tr>' +
+                               '<tr><td>B</td></tr>' +
+                               '</table>'
+               );
                $table.tablesorter();
 
                assert.equal(
-                       $table.find('> thead:eq(0) > tr > th.headerSort').length,
+                       $table.find( '> thead:eq(0) > tr > th.headerSort' ).length,
                        1,
                        'Child tables inside a headercell should not interfere with sortable headers (bug 32888)'
                );
                assert.equal(
-                       $( '#mw-bug-32888-2' ).find('th.headerSort').length,
+                       $( '#mw-bug-32888-2' ).find( 'th.headerSort' ).length,
                        0,
                        'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)'
                );
-       });
+       } );
 
 
        var correctDateSorting1 = [
                }
        );
 
+       QUnit.test( 'Sorting images using alt text', function ( assert ) {
+               var $table = $(
+                       '<table class="sortable">' +
+                               '<tr><th>THEAD</th></tr>' +
+                               '<tr><td><img alt="2"/></td></tr>' +
+                               '<tr><td>1</td></tr>' +
+                               '</table>'
+               );
+               $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+               assert.equal(
+                       $table.find( 'td' ).first().text(),
+                       '1',
+                       'Applied correct sorting order'
+               );
+       } );
+
+       QUnit.test( 'Sorting images using alt text (complex)', function ( assert ) {
+               var $table = $(
+                       '<table class="sortable">' +
+                               '<tr><th>THEAD</th></tr>' +
+                               '<tr><td><img alt="D" />A</td></tr>' +
+                               '<tr><td>CC</td></tr>' +
+                               '<tr><td><a><img alt="A" /></a>F</tr>' +
+                               '<tr><td><img alt="A" /><strong>E</strong></tr>' +
+                               '<tr><td><strong><img alt="A" />D</strong></tr>' +
+                               '<tr><td><img alt="A" />C</tr>' +
+                               '</table>'
+               );
+               $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+               assert.equal(
+                       $table.find( 'td' ).text(),
+                       'CDEFCCA',
+                       'Applied correct sorting order'
+               );
+       } );
+
+       QUnit.test( 'Sorting images using alt text (with format autodetection)', function ( assert ) {
+               var $table = $(
+                       '<table class="sortable">' +
+                               '<tr><th>THEAD</th></tr>' +
+                               '<tr><td><img alt="1" />7</td></tr>' +
+                               '<tr><td>1<img alt="6" /></td></tr>' +
+                               '<tr><td>5</td></tr>' +
+                               '<tr><td>4</td></tr>' +
+                               '</table>'
+               );
+               $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+               assert.equal(
+                       $table.find( 'td' ).text(),
+                       '4517',
+                       'Applied correct sorting order'
+               );
+       } );
 }( jQuery, mediaWiki ) );
index 1795b95..ce03b69 100644 (file)
         *   params {object} add'l parameters for $().textSelection( 'encapsulateText' )
         */
        function encapsulateTest( options ) {
-               var opt = $.extend({
+               var opt = $.extend( {
                        description: '',
                        before: {},
                        after: {},
                        replace: {}
-               }, options);
+               }, options );
 
-               opt.before = $.extend({
+               opt.before = $.extend( {
                        text: '',
                        start: 0,
                        end: 0
-               }, opt.before);
-               opt.after = $.extend({
+               }, opt.before );
+               opt.after = $.extend( {
                        text: '',
                        selected: null
-               }, opt.after);
+               }, opt.after );
 
                QUnit.test( opt.description, function ( assert ) {
                        /*jshint onevar: false */
                        //$textarea.textSelection( 'setContents', opt.before.text); // this method is actually missing atm...
                        $textarea.val( opt.before.text ); // won't work with the WikiEditor iframe?
 
-                       var     start = opt.before.start,
+                       var start = opt.before.start,
                                end = opt.before.end;
                        if ( window.opera ) {
                                // Compensate for Opera's craziness converting \n to \r\n and counting that as two chars
-                               var     newLinesBefore = opt.before.text.substring( 0, start ).split( '\n' ).length - 1,
+                               var newLinesBefore = opt.before.text.substring( 0, start ).split( '\n' ).length - 1,
                                        newLinesInside = opt.before.text.substring( start, end ).split( '\n' ).length - 1;
                                start += newLinesBefore;
                                end += newLinesBefore + newLinesInside;
@@ -98,7 +98,7 @@
                        splitlines: true
                };
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'Adding sig to end of text',
                before: {
                        text: 'Wikilove dude! ',
                        selected: ''
                },
                replace: sig
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'Adding bold to empty',
                before: {
                        text: '',
                        selected: 'Bold text' // selected because it's the default
                },
                replace: bold
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'Adding bold to existing text',
                before: {
                        text: 'Now is the time for all good men to come to the aid of their country',
                        selected: '' // empty because it's not the default'
                },
                replace: bold
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'ownline option: adding new h2',
                before: {
-                       text:'Before\nAfter',
+                       text: 'Before\nAfter',
                        start: 7,
                        end: 7
                },
                        selected: 'Heading 2'
                },
                replace: h2
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'ownline option: turn a whole line into new h2',
                before: {
-                       text:'Before\nMy heading\nAfter',
+                       text: 'Before\nMy heading\nAfter',
                        start: 7,
                        end: 17
                },
                        selected: ''
                },
                replace: h2
-       });
+       } );
 
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'ownline option: turn a partial line into new h2',
                before: {
-                       text:'BeforeMy headingAfter',
+                       text: 'BeforeMy headingAfter',
                        start: 6,
                        end: 16
                },
                        selected: ''
                },
                replace: h2
-       });
+       } );
 
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'splitlines option: no selection, insert new list item',
                before: {
                        text: 'Before\nAfter',
                        text: 'Before\n* Bulleted list item\nAfter'
                },
                replace: ulist
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'splitlines option: single partial line selection, insert new list item',
                before: {
                        text: 'BeforeMy List ItemAfter',
                        text: 'Before\n* My List Item\nAfter'
                },
                replace: ulist
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'splitlines option: multiple lines',
                before: {
                        text: 'Before\nFirst\nSecond\nThird\nAfter',
                        text: 'Before\n* First\n* Second\n* Third\nAfter'
                },
                replace: ulist
-       });
+       } );
 
 
        function caretTest( options ) {
                        $( '#qunit-fixture' ).append( $textarea );
 
                        if ( options.mode === 'set' ) {
-                               $textarea.textSelection('setSelection', {
+                               $textarea.textSelection( 'setSelection', {
                                        start: options.start,
                                        end: options.end
-                               });
+                               } );
                        }
 
                        function among( actual, expected, message ) {
                                if ( $.isArray( expected ) ) {
-                                       assert.ok( $.inArray( actual, expected ) !== -1 , message + ' (got ' + actual + '; expected one of ' + expected.join(', ') + ')' );
+                                       assert.ok( $.inArray( actual, expected ) !== -1, message + ' (got ' + actual + '; expected one of ' + expected.join( ', ' ) + ')' );
                                } else {
                                        assert.equal( actual, expected, message );
                                }
                        }
 
-                       pos = $textarea.textSelection( 'getCaretPosition', { startAndEnd: true });
-                       among(pos[0], options.start, 'Caret start should be where we set it.');
-                       among(pos[1], options.end, 'Caret end should be where we set it.');
-               });
+                       pos = $textarea.textSelection( 'getCaretPosition', { startAndEnd: true } );
+                       among( pos[0], options.start, 'Caret start should be where we set it.' );
+                       among( pos[1], options.end, 'Caret end should be where we set it.' );
+               } );
        }
 
        caretSample = 'Some big text that we like to work with. Nothing fancy... you know what I mean?';
 
        /*
-       // @broken: Disabled per bug 34820
-       caretTest({
-               description: 'getCaretPosition with original/empty selection - bug 31847 with IE 6/7/8',
-               text: caretSample,
-               start: [0, caretSample.length], // Opera and Firefox (prior to FF 6.0) default caret to the end of the box (caretSample.length)
-               end: [0, caretSample.length], // Other browsers default it to the beginning (0), so check both.
-               mode: 'get'
-       });
-       */
+        // @broken: Disabled per bug 34820
+        caretTest({
+        description: 'getCaretPosition with original/empty selection - bug 31847 with IE 6/7/8',
+        text: caretSample,
+        start: [0, caretSample.length], // Opera and Firefox (prior to FF 6.0) default caret to the end of the box (caretSample.length)
+        end: [0, caretSample.length], // Other browsers default it to the beginning (0), so check both.
+        mode: 'get'
+        });
+        */
 
-       caretTest({
+       caretTest( {
                description: 'set/getCaretPosition with forced empty selection',
                text: caretSample,
                start: 7,
                end: 7,
                mode: 'set'
-       });
+       } );
 
-       caretTest({
+       caretTest( {
                description: 'set/getCaretPosition with small selection',
                text: caretSample,
                start: 6,
                end: 11,
                mode: 'set'
-       });
+       } );
 }( jQuery ) );
index ec7179e..2bed9b9 100644 (file)
@@ -23,6 +23,6 @@
                                assert.equal( $res.find( 'b' ).text(), 'Hello world', 'Bold tag wraps the entire, same, text' );
 
                                QUnit.start();
-                       });
-       });
+                       } );
+       } );
 }( mediaWiki, jQuery ) );
index 50bbfd7..9eda75c 100644 (file)
                d1 = api.get( {} )
                        .done( function ( data ) {
                                assert.deepEqual( data, [], 'If request succeeds without errors, resolve deferred' );
-                       });
+                       } );
 
-               d2 = api.get({
-                               action: 'doesntexist'
-                       })
+               d2 = api.get( {
+                       action: 'doesntexist'
+               )
                        .fail( function ( errorCode ) {
                                assert.equal( errorCode, 'unknown_action', 'API error (e.g. "unknown_action") should reject the deferred' );
-                       });
+                       } );
 
                d3 = api.post( {} )
                        .done( function ( data ) {
                                assert.deepEqual( data, [], 'Simple POST request' );
-                       });
+                       } );
 
                // After all are completed, continue the test suite.
                QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
                        QUnit.start();
-               });
-       });
+               } );
+       } );
 
        QUnit.asyncTest( 'Deprecated callback methods', function ( assert ) {
                var api, d1, d2, d3;
 
                d1 = api.get( {}, function () {
                        assert.ok( true, 'Function argument treated as success callback.' );
-               });
+               } );
 
                d2 = api.get( {}, {
                        ok: function () {
                                assert.ok( true, '"ok" property treated as success callback.' );
                        }
-               });
+               } );
 
-               d3 = api.get({
-                               action: 'doesntexist'
-                       }, {
+               d3 = api.get( {
+                       action: 'doesntexist'
+               }, {
                        err: function () {
                                assert.ok( true, '"err" property treated as error callback.' );
                        }
-               });
+               } );
 
                QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
                        QUnit.start();
-               });
-       });
+               } );
+       } );
 }( mediaWiki ) );
index d7b0cb7..9389651 100644 (file)
@@ -7,23 +7,21 @@
                var selectHtml, $env, $options;
 
                // from Special:Recentchanges
-               selectHtml =
-               '<select id="namespace" name="namespace" class="namespaceselector">'
-               + '<option value="" selected="selected">all</option>'
-               + '<option value="0">(Main)</option>'
-               + '<option value="1">Talk</option>'
-               + '<option value="2">User</option>'
-               + '<option value="3">User talk</option>'
-               + '<option value="4">ProjectName</option>'
-               + '<option value="5">ProjectName talk</option>'
-               + '</select>'
-               + '<input name="invert" type="checkbox" value="1" id="nsinvert" title="no title" />'
-               + '<label for="nsinvert" title="no title">Invert selection</label>'
-               + '<input name="associated" type="checkbox" value="1" id="nsassociated" title="no title" />'
-               + '<label for="nsassociated" title="no title">Associated namespace</label>'
-               + '<input type="submit" value="Go" />'
-               + '<input type="hidden" value="Special:RecentChanges" name="title" />'
-               ;
+               selectHtml = '<select id="namespace" name="namespace" class="namespaceselector">'
+                       + '<option value="" selected="selected">all</option>'
+                       + '<option value="0">(Main)</option>'
+                       + '<option value="1">Talk</option>'
+                       + '<option value="2">User</option>'
+                       + '<option value="3">User talk</option>'
+                       + '<option value="4">ProjectName</option>'
+                       + '<option value="5">ProjectName talk</option>'
+                       + '</select>'
+                       + '<input name="invert" type="checkbox" value="1" id="nsinvert" title="no title" />'
+                       + '<label for="nsinvert" title="no title">Invert selection</label>'
+                       + '<input name="associated" type="checkbox" value="1" id="nsassociated" title="no title" />'
+                       + '<label for="nsassociated" title="no title">Associated namespace</label>'
+                       + '<input type="submit" value="Go" />'
+                       + '<input type="hidden" value="Special:RecentChanges" name="title" />';
 
                $env = $( '<div>' ).html( selectHtml ).appendTo( 'body' );
 
@@ -42,8 +40,8 @@
 
                // select second option...
                $options = $( '#namespace' ).find( 'option' );
-               $options.eq(0).removeProp( 'selected' );
-               $options.eq(1).prop( 'selected', true );
+               $options.eq( 0 ).removeProp( 'selected' );
+               $options.eq( 1 ).prop( 'selected', true );
                $( '#namespace' ).change();
 
                // ... and checkboxes should be enabled again
@@ -51,8 +49,8 @@
                assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
 
                // select first option ( 'all' namespace)...
-               $options.eq(1).removeProp( 'selected' );
-               $options.eq(0).prop( 'selected', true );
+               $options.eq( 1 ).removeProp( 'selected' );
+               $options.eq( 0 ).prop( 'selected', true );
                $( '#namespace' ).change();
 
                // ... and checkboxes should now be disabled
@@ -61,5 +59,5 @@
 
                // DOM cleanup
                $env.remove();
-       });
+       } );
 }( mediaWiki, jQuery ) );
index 52f0538..30a31ef 100644 (file)
 ( function ( mw ) {
+       // mw.Title relies on these three config vars
+       // Restore them after each test run
+       var config = {
+               wgFormattedNamespaces: {
+                       '-2': 'Media',
+                       '-1': 'Special',
+                       0: '',
+                       1: 'Talk',
+                       2: 'User',
+                       3: 'User talk',
+                       4: 'Wikipedia',
+                       5: 'Wikipedia talk',
+                       6: 'File',
+                       7: 'File talk',
+                       8: 'MediaWiki',
+                       9: 'MediaWiki talk',
+                       10: 'Template',
+                       11: 'Template talk',
+                       12: 'Help',
+                       13: 'Help talk',
+                       14: 'Category',
+                       15: 'Category talk',
+                       // testing custom / localized namespace
+                       100: 'Penguins'
+               },
+               wgNamespaceIds: {
+                       /*jshint camelcase: false */
+                       media: -2,
+                       special: -1,
+                       '': 0,
+                       talk: 1,
+                       user: 2,
+                       user_talk: 3,
+                       wikipedia: 4,
+                       wikipedia_talk: 5,
+                       file: 6,
+                       file_talk: 7,
+                       mediawiki: 8,
+                       mediawiki_talk: 9,
+                       template: 10,
+                       template_talk: 11,
+                       help: 12,
+                       help_talk: 13,
+                       category: 14,
+                       category_talk: 15,
+                       image: 6,
+                       image_talk: 7,
+                       project: 4,
+                       project_talk: 5,
+                       /* testing custom / alias */
+                       penguins: 100,
+                       antarctic_waterfowl: 100
+               },
+               wgCaseSensitiveNamespaces: []
+       };
+
+       QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment( { config: config } ) );
+
+       QUnit.test( 'Transformation', 8, function ( assert ) {
+               var title;
+
+               title = new mw.Title( 'File:quux pif.jpg' );
+               assert.equal( title.getName(), 'Quux_pif' );
+
+               title = new mw.Title( 'File:Glarg_foo_glang.jpg' );
+               assert.equal( title.getNameText(), 'Glarg foo glang' );
+
+               title = new mw.Title( 'User:ABC.DEF' );
+               assert.equal( title.toText(), 'User:ABC.DEF' );
+               assert.equal( title.getNamespaceId(), 2 );
+               assert.equal( title.getNamespacePrefix(), 'User:' );
+
+               title = new mw.Title( 'uSEr:hAshAr' );
+               assert.equal( title.toText(), 'User:HAshAr' );
+               assert.equal( title.getNamespaceId(), 2 );
+
+               title = new mw.Title( '   MediaWiki:  Foo   bar   .js   ' );
+               // Don't ask why, it's the way the backend works. One space is kept of each set
+               assert.equal( title.getName(), 'Foo_bar_.js', 'Merge multiple spaces to a single space.' );
+       } );
+
+       QUnit.test( 'Main text for filename', 8, function ( assert ) {
+               var title = new mw.Title( 'File:foo_bar.JPG' );
+
+               assert.equal( title.getNamespaceId(), 6 );
+               assert.equal( title.getNamespacePrefix(), 'File:' );
+               assert.equal( title.getName(), 'Foo_bar' );
+               assert.equal( title.getNameText(), 'Foo bar' );
+               assert.equal( title.getMain(), 'Foo_bar.JPG' );
+               assert.equal( title.getMainText(), 'Foo bar.JPG' );
+               assert.equal( title.getExtension(), 'JPG' );
+               assert.equal( title.getDotExtension(), '.JPG' );
+       } );
+
+       QUnit.test( 'Namespace detection and conversion', 6, function ( assert ) {
+               var title;
+
+               title = new mw.Title( 'something.PDF', 6 );
+               assert.equal( title.toString(), 'File:Something.PDF' );
+
+               title = new mw.Title( 'NeilK', 3 );
+               assert.equal( title.toString(), 'User_talk:NeilK' );
+               assert.equal( title.toText(), 'User talk:NeilK' );
+
+               title = new mw.Title( 'Frobisher', 100 );
+               assert.equal( title.toString(), 'Penguins:Frobisher' );
+
+               title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' );
+               assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
+
+               title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' );
+               assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
+       } );
+
+       QUnit.test( 'Throw error on invalid title', 1, function ( assert ) {
+               assert.throws( function () {
+                       return new mw.Title( '' );
+               }, 'Throw error on empty string' );
+       } );
+
+       QUnit.test( 'Case-sensivity', 3, function ( assert ) {
+               var title;
+
+               // Default config
+               mw.config.set( 'wgCaseSensitiveNamespaces', [] );
+
+               title = new mw.Title( 'article' );
+               assert.equal( title.toString(), 'Article', 'Default config: No sensitive namespaces by default. First-letter becomes uppercase' );
+
+               // $wgCapitalLinks = false;
+               mw.config.set( 'wgCaseSensitiveNamespaces', [0, -2, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15] );
+
+               title = new mw.Title( 'article' );
+               assert.equal( title.toString(), 'article', '$wgCapitalLinks=false: Article namespace is sensitive, first-letter case stays lowercase' );
+
+               title = new mw.Title( 'john', 2 );
+               assert.equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' );
+       } );
+
+       QUnit.test( 'toString / toText', 2, function ( assert ) {
+               var title = new mw.Title( 'Some random page' );
+
+               assert.equal( title.toString(), title.getPrefixedDb() );
+               assert.equal( title.toText(), title.getPrefixedText() );
+       } );
 
-// mw.Title relies on these three config vars
-// Restore them after each test run
-var config = {
-       wgFormattedNamespaces: {
-               '-2': 'Media',
-               '-1': 'Special',
-               0: '',
-               1: 'Talk',
-               2: 'User',
-               3: 'User talk',
-               4: 'Wikipedia',
-               5: 'Wikipedia talk',
-               6: 'File',
-               7: 'File talk',
-               8: 'MediaWiki',
-               9: 'MediaWiki talk',
-               10: 'Template',
-               11: 'Template talk',
-               12: 'Help',
-               13: 'Help talk',
-               14: 'Category',
-               15: 'Category talk',
-               // testing custom / localized namespace
-               100: 'Penguins'
-       },
-       wgNamespaceIds: {
-               /*jshint camelcase: false */
-               media: -2,
-               special: -1,
-               '': 0,
-               talk: 1,
-               user: 2,
-               user_talk: 3,
-               wikipedia: 4,
-               wikipedia_talk: 5,
-               file: 6,
-               file_talk: 7,
-               mediawiki: 8,
-               mediawiki_talk: 9,
-               template: 10,
-               template_talk: 11,
-               help: 12,
-               help_talk: 13,
-               category: 14,
-               category_talk: 15,
-               image: 6,
-               image_talk: 7,
-               project: 4,
-               project_talk: 5,
-               /* testing custom / alias */
-               penguins: 100,
-               antarctic_waterfowl: 100
-       },
-       wgCaseSensitiveNamespaces: []
-};
-
-QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment({ config: config }) );
-
-
-QUnit.test( 'Transformation', 8, function ( assert ) {
-       var title;
-
-       title = new mw.Title( 'File:quux pif.jpg' );
-       assert.equal( title.getName(), 'Quux_pif' );
-
-       title = new mw.Title( 'File:Glarg_foo_glang.jpg' );
-       assert.equal( title.getNameText(), 'Glarg foo glang' );
-
-       title = new mw.Title( 'User:ABC.DEF' );
-       assert.equal( title.toText(), 'User:ABC.DEF' );
-       assert.equal( title.getNamespaceId(), 2 );
-       assert.equal( title.getNamespacePrefix(), 'User:' );
-
-       title = new mw.Title( 'uSEr:hAshAr' );
-       assert.equal( title.toText(), 'User:HAshAr' );
-       assert.equal( title.getNamespaceId(), 2 );
-
-       title = new mw.Title( '   MediaWiki:  Foo   bar   .js   ' );
-       // Don't ask why, it's the way the backend works. One space is kept of each set
-       assert.equal( title.getName(), 'Foo_bar_.js', 'Merge multiple spaces to a single space.' );
-});
-
-QUnit.test( 'Main text for filename', 8, function ( assert ) {
-       var title = new mw.Title( 'File:foo_bar.JPG' );
-
-       assert.equal( title.getNamespaceId(), 6 );
-       assert.equal( title.getNamespacePrefix(), 'File:' );
-       assert.equal( title.getName(), 'Foo_bar' );
-       assert.equal( title.getNameText(), 'Foo bar' );
-       assert.equal( title.getMain(), 'Foo_bar.JPG' );
-       assert.equal( title.getMainText(), 'Foo bar.JPG' );
-       assert.equal( title.getExtension(), 'JPG' );
-       assert.equal( title.getDotExtension(), '.JPG' );
-});
-
-QUnit.test( 'Namespace detection and conversion', 6, function ( assert ) {
-       var title;
-
-       title = new mw.Title( 'something.PDF', 6 );
-       assert.equal( title.toString(), 'File:Something.PDF' );
-
-       title = new mw.Title( 'NeilK', 3 );
-       assert.equal( title.toString(), 'User_talk:NeilK' );
-       assert.equal( title.toText(), 'User talk:NeilK' );
-
-       title = new mw.Title( 'Frobisher', 100 );
-       assert.equal( title.toString(), 'Penguins:Frobisher' );
-
-       title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' );
-       assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
-
-       title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' );
-       assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
-});
-
-QUnit.test( 'Throw error on invalid title', 1, function ( assert ) {
-       assert.throws(function () {
-               return new mw.Title( '' );
-       }, 'Throw error on empty string' );
-});
-
-QUnit.test( 'Case-sensivity', 3, function ( assert ) {
-       var title;
-
-       // Default config
-       mw.config.set( 'wgCaseSensitiveNamespaces', [] );
-
-       title = new mw.Title( 'article' );
-       assert.equal( title.toString(), 'Article', 'Default config: No sensitive namespaces by default. First-letter becomes uppercase' );
-
-       // $wgCapitalLinks = false;
-       mw.config.set( 'wgCaseSensitiveNamespaces', [0, -2, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15] );
-
-       title = new mw.Title( 'article' );
-       assert.equal( title.toString(), 'article', '$wgCapitalLinks=false: Article namespace is sensitive, first-letter case stays lowercase' );
-
-       title = new mw.Title( 'john', 2 );
-       assert.equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' );
-});
+       QUnit.test( 'getExtension', 7, function ( assert ) {
+               function extTest( pagename, ext, description ) {
+                       var title = new mw.Title( pagename );
+                       assert.equal( title.getExtension(), ext, description || pagename );
+               }
 
-QUnit.test( 'toString / toText', 2, function ( assert ) {
-       var title = new mw.Title( 'Some random page' );
+               extTest( 'MediaWiki:Vector.js', 'js' );
+               extTest( 'User:Example/common.css', 'css' );
+               extTest( 'File:Example.longextension', 'longextension', 'Extension parsing not limited (bug 36151)' );
+               extTest( 'Example/information.json', 'json', 'Extension parsing not restricted from any namespace' );
+               extTest( 'Foo.', null, 'Trailing dot is not an extension' );
+               extTest( 'Foo..', null, 'Trailing dots are not an extension' );
+               extTest( 'Foo.a.', null, 'Page name with dots and ending in a dot does not have an extension' );
 
-       assert.equal( title.toString(), title.getPrefixedDb() );
-       assert.equal( title.toText(), title.getPrefixedText() );
-});
+               // @broken: Throws an exception
+               // extTest( '.NET', null, 'Leading dot is (or is not?) an extension' );
+       } );
 
-QUnit.test( 'getExtension', 7, function ( assert ) {
+       QUnit.test( 'exists', 3, function ( assert ) {
+               var title;
 
-       function extTest( pagename, ext, description ) {
-               var title = new mw.Title( pagename );
-               assert.equal( title.getExtension(), ext, description || pagename );
-       }
+               // Empty registry, checks default to null
 
-       extTest( 'MediaWiki:Vector.js', 'js' );
-       extTest( 'User:Example/common.css', 'css' );
-       extTest( 'File:Example.longextension', 'longextension', 'Extension parsing not limited (bug 36151)' );
-       extTest( 'Example/information.json', 'json', 'Extension parsing not restricted from any namespace' );
-       extTest( 'Foo.', null, 'Trailing dot is not an extension' );
-       extTest( 'Foo..', null, 'Trailing dots are not an extension' );
-       extTest( 'Foo.a.', null, 'Page name with dots and ending in a dot does not have an extension' );
+               title = new mw.Title( 'Some random page', 4 );
+               assert.strictEqual( title.exists(), null, 'Return null with empty existance registry' );
 
-       // @broken: Throws an exception
-       // extTest( '.NET', null, 'Leading dot is (or is not?) an extension' );
-});
+               // Basic registry, checks default to boolean
+               mw.Title.exist.set( ['Does_exist', 'User_talk:NeilK', 'Wikipedia:Sandbox_rules'], true );
+               mw.Title.exist.set( ['Does_not_exist', 'User:John', 'Foobar'], false );
 
-QUnit.test( 'exists', 3, function ( assert ) {
-       var title;
+               title = new mw.Title( 'Project:Sandbox rules' );
+               assert.assertTrue( title.exists(), 'Return true for page titles marked as existing' );
+               title = new mw.Title( 'Foobar' );
+               assert.assertFalse( title.exists(), 'Return false for page titles marked as nonexistent' );
 
-       // Empty registry, checks default to null
+       } );
 
-       title = new mw.Title( 'Some random page', 4 );
-       assert.strictEqual( title.exists(), null, 'Return null with empty existance registry' );
+       QUnit.test( 'getUrl', 2, function ( assert ) {
+               var title;
 
-       // Basic registry, checks default to boolean
-       mw.Title.exist.set( ['Does_exist', 'User_talk:NeilK', 'Wikipedia:Sandbox_rules'], true );
-       mw.Title.exist.set( ['Does_not_exist', 'User:John', 'Foobar'], false );
+               // Config
+               mw.config.set( 'wgArticlePath', '/wiki/$1' );
 
-       title = new mw.Title( 'Project:Sandbox rules' );
-       assert.assertTrue( title.exists(), 'Return true for page titles marked as existing' );
-       title = new mw.Title( 'Foobar' );
-       assert.assertFalse( title.exists(), 'Return false for page titles marked as nonexistent' );
+               title = new mw.Title( 'Foobar' );
+               assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionally, toString passing to wikiGetlink' );
 
-});
+               title = new mw.Title( 'John Doe', 3 );
+               assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
+       } );
 
-QUnit.test( 'getUrl', 2, function ( assert ) {
-       var title;
-
-       // Config
-       mw.config.set( 'wgArticlePath', '/wiki/$1' );
-
-       title = new mw.Title( 'Foobar' );
-       assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionally, toString passing to wikiGetlink' );
-
-       title = new mw.Title( 'John Doe', 3 );
-       assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
-});
-
-}( mediaWiki ) );
\ No newline at end of file
+}( mediaWiki ) );
index 9eb2efc..9913f5e 100644 (file)
@@ -1,5 +1,5 @@
 ( function ( mw, $ ) {
-       QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment({
+       QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment( {
                setup: function () {
                        this.mwUriOrg = mw.Uri;
                        mw.Uri = mw.UriRelative( 'http://example.org/w/index.php' );
@@ -8,7 +8,7 @@
                        mw.Uri = this.mwUriOrg;
                        delete this.mwUriOrg;
                }
-       }) );
+       } ) );
 
        $.each( [true, false], function ( i, strictMode ) {
                QUnit.test( 'Basic construction and properties (' + ( strictMode ? '' : 'non-' ) + 'strict mode)', 2, function ( assert ) {
@@ -16,7 +16,7 @@
                        uriString = 'http://www.ietf.org/rfc/rfc2396.txt';
                        uri = new mw.Uri( uriString, {
                                strictMode: strictMode
-                       });
+                       } );
 
                        assert.deepEqual(
                                {
                                },
                                'construct composite components of URI on request'
                        );
-
-               });
-       });
+               } );
+       } );
 
        QUnit.test( 'Constructor( String[, Object ] )', 10, function ( assert ) {
                var uri;
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: true
-               });
+               } );
 
                // Strict comparison to assert that numerical values stay strings
                assert.strictEqual( uri.query.n, '1', 'Simple parameter with overrideKeys:true' );
@@ -73,7 +72,7 @@
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: false
-               });
+               } );
 
                assert.strictEqual( uri.query.n, '1', 'Simple parameter with overrideKeys:false' );
                assert.strictEqual( uri.query.m[0], 'foo', 'Order of multi-value parameters with overrideKeys:true' );
                        function () {
                                return new mw.Uri( 'foo.com/bar/baz', {
                                        strictMode: true
-                               });
+                               } );
                        },
                        function ( e ) {
                                return e.message === 'Bad constructor arguments';
 
                uri = new mw.Uri( 'foo.com/bar/baz', {
                        strictMode: false
-               });
+               } );
                assert.equal( uri.toString(), 'http://foo.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
-       });
+       } );
 
        QUnit.test( 'Constructor( Object )', 3, function ( assert ) {
-               var uri = new mw.Uri({
+               var uri = new mw.Uri( {
                        protocol: 'http',
                        host: 'www.foo.local',
                        path: '/this'
-               });
+               } );
                assert.equal( uri.toString(), 'http://www.foo.local/this', 'Basic properties' );
 
-               uri = new mw.Uri({
+               uri = new mw.Uri( {
                        protocol: 'http',
                        host: 'www.foo.local',
                        path: '/this',
                        query: { hi: 'there' },
                        fragment: 'blah'
-               });
+               } );
                assert.equal( uri.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' );
 
                assert.throws(
                        function () {
-                               return new mw.Uri({
+                               return new mw.Uri( {
                                        protocol: 'http',
                                        host: 'www.foo.local'
-                               });
+                               } );
                        },
                        function ( e ) {
                                return e.message === 'Bad constructor arguments';
                uri = uriBase.clone();
                uri.query.foo = 'bar';
                assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' );
-               uri.extend({
+               uri.extend( {
                        foo: 'quux',
                        pif: 'paf'
-               });
+               } );
                assert.ok( uri.toString().indexOf( 'foo=quux' ) >= 0, 'extend query arguments' );
                assert.ok( uri.toString().indexOf( 'foo=bar' ) === -1, 'extend query arguments' );
-               assert.ok( uri.toString().indexOf( 'pif=paf' ) >= 0 , 'extend query arguments' );
+               assert.ok( uri.toString().indexOf( 'pif=paf' ) >= 0, 'extend query arguments' );
        } );
 
        QUnit.test( '.getQueryString()', 2, function ( assert ) {
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: true
-               });
+               } );
 
                uri.query.n = [ 'x', 'y', 'z' ];
 
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: false
-               });
+               } );
 
                // Change query values
                uri.query.n = [ 'x', 'y', 'z' ];
index b745fb4..779a0ed 100644 (file)
                        [ 1, [ 'one', 'other' ], 'one', 'Hungarian plural test- 1 is one' ],
                        [ 2, [ 'one', 'other' ], 'other', 'Hungarian plural test- 2 is other' ]
                ],
+               hy: [
+                       [ 0, [ 'one', 'other' ], 'other', 'Armenian plural test- 0 is other' ],
+                       [ 1, [ 'one', 'other' ], 'one', 'Armenian plural test- 1 is one' ],
+                       [ 2, [ 'one', 'other' ], 'other', 'Armenian plural test- 2 is other' ]
+               ],
                ar: [
                        [ 0, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'zero', 'Arabic plural test - 0 is zero' ],
                        [ 1, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'one', 'Arabic plural test - 1 is one' ],
index d7c73e5..95a16c8 100644 (file)
 ( function ( mw, $ ) {
+       var mwLanguageCache = {}, oldGetOuterHtml, formatnumTests, specialCharactersPageName,
+               expectedListUsers, expectedEntrypoints;
 
-var mwLanguageCache = {}, oldGetOuterHtml, formatnumTests;
-
-QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
-       setup: function () {
-               this.orgMwLangauge = mw.language;
-               mw.language = $.extend( true, {}, this.orgMwLangauge );
-               oldGetOuterHtml = $.fn.getOuterHtml;
-               $.fn.getOuterHtml = function () {
-                       var $div = $( '<div>' ), html;
-                       $div.append( $( this ).eq( 0 ).clone() );
-                       html = $div.html();
-                       $div.empty();
-                       $div = undefined;
-                       return html;
-               };
-       },
-       teardown: function () {
-               mw.language = this.orgMwLangauge;
-               $.fn.getOuterHtml = oldGetOuterHtml;
-       }
-}) );
+       QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
+               setup: function () {
+                       this.orgMwLangauge = mw.language;
+                       mw.language = $.extend( true, {}, this.orgMwLangauge );
+                       oldGetOuterHtml = $.fn.getOuterHtml;
+                       $.fn.getOuterHtml = function () {
+                               var $div = $( '<div>' ), html;
+                               $div.append( $( this ).eq( 0 ).clone() );
+                               html = $div.html();
+                               $div.empty();
+                               $div = undefined;
+                               return html;
+                       };
+
+                       // Messages that are reused in multiple tests
+                       mw.messages.set( {
+                               // The values for gender are not significant,
+                               // what matters is which of the values is choosen by the parser
+                               'gender-msg': '$1: {{GENDER:$2|blue|pink|green}}',
+
+                               'plural-msg': 'Found $1 {{PLURAL:$1|item|items}}',
+
+                               // Assume the grammar form grammar_case_foo is not valid in any language
+                               'grammar-msg': 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}',
+
+                               'formatnum-msg': '{{formatnum:$1}}',
+
+                               'portal-url': 'Project:Community portal',
+                               'see-portal-url': '{{Int:portal-url}} is an important community page.',
+
+                               'jquerymsg-test-statistics-users': '注册[[Special:ListUsers|用户]]',
 
-function getMwLanguage( langCode, cb ) {
-       if ( mwLanguageCache[langCode] !== undefined ) {
+                               'jquerymsg-test-version-entrypoints-index-php': '[https://www.mediawiki.org/wiki/Manual:index.php index.php]',
+
+                               'external-link-replace': 'Foo [$1 bar]'
+                       } );
+
+                       specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
+
+                       expectedListUsers = '注册' + $( '<a>' ).attr( {
+                               title: 'Special:ListUsers',
+                               href: mw.util.wikiGetlink( 'Special:ListUsers' )
+                       } ).text( '用户' ).getOuterHtml();
+
+                       expectedEntrypoints = '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>';
+               },
+               teardown: function () {
+                       mw.language = this.orgMwLangauge;
+                       $.fn.getOuterHtml = oldGetOuterHtml;
+               }
+       } ) );
+
+       function getMwLanguage( langCode, cb ) {
+               if ( mwLanguageCache[langCode] !== undefined ) {
+                       mwLanguageCache[langCode].add( cb );
+                       return;
+               }
+               mwLanguageCache[langCode] = $.Callbacks( 'once memory' );
                mwLanguageCache[langCode].add( cb );
-               return;
+               $.ajax( {
+                       url: mw.util.wikiScript( 'load' ),
+                       data: {
+                               skin: mw.config.get( 'skin' ),
+                               lang: langCode,
+                               debug: mw.config.get( 'debug' ),
+                               modules: [
+                                       'mediawiki.language.data',
+                                       'mediawiki.language'
+                               ].join( '|' ),
+                               only: 'scripts'
+                       },
+                       dataType: 'script'
+               } ).done(function () {
+                               mwLanguageCache[langCode].fire( mw.language );
+                       } ).fail( function () {
+                               mwLanguageCache[langCode].fire( false );
+                       } );
        }
-       mwLanguageCache[langCode] = $.Callbacks( 'once memory' );
-       mwLanguageCache[langCode].add( cb );
-       $.ajax({
-               url: mw.util.wikiScript( 'load' ),
-               data: {
-                       skin: mw.config.get( 'skin' ),
-                       lang: langCode,
-                       debug: mw.config.get( 'debug' ),
-                       modules: [
-                               'mediawiki.language.data',
-                               'mediawiki.language'
-                       ].join( '|' ),
-                       only: 'scripts'
-               },
-               dataType: 'script'
-       }).done( function () {
-               mwLanguageCache[langCode].fire( mw.language );
-       }).fail( function () {
-               mwLanguageCache[langCode].fire( false );
-       });
-}
-
-QUnit.test( 'Replace', 9, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction();
-
-       mw.messages.set( 'simple', 'Foo $1 baz $2' );
-
-       assert.equal( parser( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' );
-       assert.equal( parser( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' );
-       assert.equal( parser( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' );
-
-       mw.messages.set( 'plain-input', '<foo foo="foo">x$1y&lt;</foo>z' );
-
-       assert.equal(
-               parser( 'plain-input', 'bar' ),
-               '&lt;foo foo="foo"&gt;xbary&amp;lt;&lt;/foo&gt;z',
-               'Input is not considered html'
-       );
-
-       mw.messages.set( 'plain-replace', 'Foo $1' );
-
-       assert.equal(
-               parser( 'plain-replace', '<bar bar="bar">&gt;</bar>' ),
-               'Foo &lt;bar bar="bar"&gt;&amp;gt;&lt;/bar&gt;',
-               'Replacement is not considered html'
-       );
-
-       mw.messages.set( 'object-replace', 'Foo $1' );
-
-       assert.equal(
-               parser( 'object-replace', $( '<div class="bar">&gt;</div>' ) ),
-               'Foo <div class="bar">&gt;</div>',
-               'jQuery objects are preserved as raw html'
-       );
-
-       assert.equal(
-               parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).get( 0 ) ),
-               'Foo <div class="bar">&gt;</div>',
-               'HTMLElement objects are preserved as raw html'
-       );
-
-       assert.equal(
-               parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).toArray() ),
-               'Foo <div class="bar">&gt;</div>',
-               'HTMLElement[] arrays are preserved as raw html'
-       );
-
-       mw.messages.set( 'wikilink-replace', 'Foo [$1 bar]' );
-       assert.equal(
-               parser( 'wikilink-replace', 'http://example.org/?x=y&z' ),
-               'Foo <a href="http://example.org/?x=y&amp;z">bar</a>',
-               'Href is not double-escaped in wikilink function'
-       );
-} );
-
-QUnit.test( 'Plural', 3, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction();
-
-       mw.messages.set( 'plural-msg', 'Found $1 {{PLURAL:$1|item|items}}' );
-       assert.equal( parser( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' );
-       assert.equal( parser( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' );
-       assert.equal( parser( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
-} );
-
-QUnit.test( 'Gender', 11, function ( assert ) {
-       // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg
-       // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian
-       var user = mw.user,
-               parser = mw.jqueryMsg.getMessageFunction();
-
-       // The values here are not significant,
-       // what matters is which of the values is choosen by the parser
-       mw.messages.set( 'gender-msg', '$1: {{GENDER:$2|blue|pink|green}}' );
-
-       user.options.set( 'gender', 'male' );
-       assert.equal(
-               parser( 'gender-msg', 'Bob', 'male' ),
-               'Bob: blue',
-               'Masculine from string "male"'
-       );
-       assert.equal(
-               parser( 'gender-msg', 'Bob', user ),
-               'Bob: blue',
-               'Masculine from mw.user object'
-       );
-
-       user.options.set( 'gender', 'unknown' );
-       assert.equal(
-               parser( 'gender-msg', 'Foo', user ),
-               'Foo: green',
-               'Neutral from mw.user object' );
-       assert.equal(
-               parser( 'gender-msg', 'Alice', 'female' ),
-               'Alice: pink',
-               'Feminine from string "female"' );
-       assert.equal(
-               parser( 'gender-msg', 'User' ),
-               'User: green',
-               'Neutral when no parameter given' );
-       assert.equal(
-               parser( 'gender-msg', 'User', 'unknown' ),
-               'User: green',
-               'Neutral from string "unknown"'
-       );
-
-       mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
-
-       assert.equal(
-               parser( 'gender-msg-one-form', 'male', 10 ),
-               'User: 10 edits',
-               'Gender neutral and plural form'
-       );
-       assert.equal(
-               parser( 'gender-msg-one-form', 'female', 1 ),
-               'User: 1 edit',
-               'Gender neutral and singular form'
-       );
-
-       mw.messages.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' );
-       assert.equal(
-               parser( 'gender-msg-lowercase', 'male' ),
-               'he is awesome',
-               'Gender masculine'
-       );
-       assert.equal(
-               parser( 'gender-msg-lowercase', 'female' ),
-               'she is awesome',
-               'Gender feminine'
-       );
-
-       mw.messages.set( 'gender-msg-wrong', '{{gender}} test' );
-       assert.equal(
-               parser( 'gender-msg-wrong', 'female' ),
-               ' test',
-               'Invalid syntax should result in {{gender}} simply being stripped away'
-       );
-} );
-
-QUnit.test( 'Grammar', 2, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction();
-
-       // Assume the grammar form grammar_case_foo is not valid in any language
-       mw.messages.set( 'grammar-msg', 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}' );
-       assert.equal( parser( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar Test with sitename' );
-
-       mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' );
-       assert.equal( parser( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ' , 'Grammar Test with wrong grammar template syntax' );
-} );
-
-QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
-       mw.messages.set( mw.libs.phpParserData.messages );
-       $.each( mw.libs.phpParserData.tests, function ( i, test ) {
-               QUnit.stop();
-               getMwLanguage( test.lang, function ( langClass ) {
-                       QUnit.start();
-                       if ( !langClass ) {
-                               assert.ok( false, 'Language "' + test.lang + '" failed to load' );
-                               return;
-                       }
-                       mw.config.set( 'wgUserLanguage', test.lang ) ;
-                       var parser = new mw.jqueryMsg.parser( { language: langClass } );
-                       assert.equal(
-                               parser.parse( test.key, test.args ).html(),
-                               test.result,
-                               test.name
-                       );
+
+       QUnit.test( 'Replace', 7, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction();
+
+               mw.messages.set( 'simple', 'Foo $1 baz $2' );
+
+               assert.equal( parser( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' );
+               assert.equal( parser( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' );
+               assert.equal( parser( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' );
+
+               /* Temporarily disabling until 2013-03 --Kaldari
+               mw.messages.set( 'plain-input', '<foo foo="foo">x$1y&lt;</foo>z' );
+
+               assert.equal(
+                       parser( 'plain-input', 'bar' ),
+                       '&lt;foo foo="foo"&gt;xbary&amp;lt;&lt;/foo&gt;z',
+                       'Input is not considered html'
+               );
+
+               mw.messages.set( 'plain-replace', 'Foo $1' );
+
+               assert.equal(
+                       parser( 'plain-replace', '<bar bar="bar">&gt;</bar>' ),
+                       'Foo &lt;bar bar="bar"&gt;&amp;gt;&lt;/bar&gt;',
+                       'Replacement is not considered html'
+               );
+               */
+
+               mw.messages.set( 'object-replace', 'Foo $1' );
+
+               assert.equal(
+                       parser( 'object-replace', $( '<div class="bar">&gt;</div>' ) ),
+                       'Foo <div class="bar">&gt;</div>',
+                       'jQuery objects are preserved as raw html'
+               );
+
+               assert.equal(
+                       parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).get( 0 ) ),
+                       'Foo <div class="bar">&gt;</div>',
+                       'HTMLElement objects are preserved as raw html'
+               );
+
+               assert.equal(
+                       parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).toArray() ),
+                       'Foo <div class="bar">&gt;</div>',
+                       'HTMLElement[] arrays are preserved as raw html'
+               );
+
+               assert.equal(
+                       parser( 'external-link-replace', 'http://example.org/?x=y&z' ),
+                       'Foo <a href="http://example.org/?x=y&amp;z">bar</a>',
+                       'Href is not double-escaped in wikilink function'
+               );
+       } );
+
+       QUnit.test( 'Plural', 3, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction();
+
+               assert.equal( parser( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' );
+               assert.equal( parser( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' );
+               assert.equal( parser( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
+       } );
+
+       QUnit.test( 'Gender', 11, function ( assert ) {
+               // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg
+               // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian
+               var user = mw.user,
+                       parser = mw.jqueryMsg.getMessageFunction();
+
+               user.options.set( 'gender', 'male' );
+               assert.equal(
+                       parser( 'gender-msg', 'Bob', 'male' ),
+                       'Bob: blue',
+                       'Masculine from string "male"'
+               );
+               assert.equal(
+                       parser( 'gender-msg', 'Bob', user ),
+                       'Bob: blue',
+                       'Masculine from mw.user object'
+               );
+
+               user.options.set( 'gender', 'unknown' );
+               assert.equal(
+                       parser( 'gender-msg', 'Foo', user ),
+                       'Foo: green',
+                       'Neutral from mw.user object' );
+               assert.equal(
+                       parser( 'gender-msg', 'Alice', 'female' ),
+                       'Alice: pink',
+                       'Feminine from string "female"' );
+               assert.equal(
+                       parser( 'gender-msg', 'User' ),
+                       'User: green',
+                       'Neutral when no parameter given' );
+               assert.equal(
+                       parser( 'gender-msg', 'User', 'unknown' ),
+                       'User: green',
+                       'Neutral from string "unknown"'
+               );
+
+               mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
+
+               assert.equal(
+                       parser( 'gender-msg-one-form', 'male', 10 ),
+                       'User: 10 edits',
+                       'Gender neutral and plural form'
+               );
+               assert.equal(
+                       parser( 'gender-msg-one-form', 'female', 1 ),
+                       'User: 1 edit',
+                       'Gender neutral and singular form'
+               );
+
+               mw.messages.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' );
+               assert.equal(
+                       parser( 'gender-msg-lowercase', 'male' ),
+                       'he is awesome',
+                       'Gender masculine'
+               );
+               assert.equal(
+                       parser( 'gender-msg-lowercase', 'female' ),
+                       'she is awesome',
+                       'Gender feminine'
+               );
+
+               mw.messages.set( 'gender-msg-wrong', '{{gender}} test' );
+               assert.equal(
+                       parser( 'gender-msg-wrong', 'female' ),
+                       ' test',
+                       'Invalid syntax should result in {{gender}} simply being stripped away'
+               );
+       } );
+
+       QUnit.test( 'Grammar', 2, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction();
+
+               assert.equal( parser( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar Test with sitename' );
+
+               mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' );
+               assert.equal( parser( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ', 'Grammar Test with wrong grammar template syntax' );
+       } );
+
+       QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
+               mw.messages.set( mw.libs.phpParserData.messages );
+               $.each( mw.libs.phpParserData.tests, function ( i, test ) {
+                       QUnit.stop();
+                       getMwLanguage( test.lang, function ( langClass ) {
+                               QUnit.start();
+                               if ( !langClass ) {
+                                       assert.ok( false, 'Language "' + test.lang + '" failed to load' );
+                                       return;
+                               }
+                               mw.config.set( 'wgUserLanguage', test.lang );
+                               var parser = new mw.jqueryMsg.parser( { language: langClass } );
+                               assert.equal(
+                                       parser.parse( test.key, test.args ).html(),
+                                       test.result,
+                                       test.name
+                               );
+                       } );
                } );
        } );
-});
-
-QUnit.test( 'Wikilink', 6, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction(),
-               expectedListUsers,
-               expectedDisambiguationsText,
-               expectedMultipleBars,
-               expectedSpecialCharacters,
-               specialCharactersPageName;
-
-       /*
-        The below three are all identical to or based on real messages.  For disambiguations-text,
-        the bold was removed because it is not yet implemented.
-       */
-
-       mw.messages.set( 'statistics-users', '注册[[Special:ListUsers|用户]]' );
-
-       expectedListUsers = '注册' + $( '<a>' ).attr( {
-               title: 'Special:ListUsers',
-               href: mw.util.wikiGetlink( 'Special:ListUsers' )
-       } ).text( '用户' ).getOuterHtml();
-
-       assert.equal(
-               parser( 'statistics-users' ),
-               expectedListUsers,
-               'Piped wikilink'
-       );
-
-       expectedDisambiguationsText = 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from ' +
-               $( '<a>' ).attr( {
-                       title: 'MediaWiki:Disambiguationspage',
-                       href: mw.util.wikiGetlink( 'MediaWiki:Disambiguationspage' )
-               } ).text( 'MediaWiki:Disambiguationspage' ).getOuterHtml() + '.';
-       mw.messages.set( 'disambiguations-text', 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from [[MediaWiki:Disambiguationspage]].' );
-       assert.equal(
-               parser( 'disambiguations-text' ),
-               expectedDisambiguationsText,
-               'Wikilink without pipe'
-       );
-
-       mw.messages.set( 'version-entrypoints-index-php', '[https://www.mediawiki.org/wiki/Manual:index.php index.php]' );
-       assert.equal(
-               parser( 'version-entrypoints-index-php' ),
-               '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>',
-               'External link'
-       );
-
-       // Pipe trick is not supported currently, but should not parse as text either.
-       mw.messages.set( 'pipe-trick', '[[Tampa, Florida|]]' );
-       assert.equal(
-               parser( 'pipe-trick' ),
-               'pipe-trick: Parse error at position 0 in input: [[Tampa, Florida|]]',
-               'Pipe trick should return error string.'
-       );
-
-       expectedMultipleBars = $( '<a>' ).attr( {
-               title: 'Main Page',
-               href: mw.util.wikiGetlink( 'Main Page' )
-       } ).text( 'Main|Page' ).getOuterHtml();
-       mw.messages.set( 'multiple-bars', '[[Main Page|Main|Page]]' );
-       assert.equal(
-               parser( 'multiple-bars' ),
-               expectedMultipleBars,
-               'Bar in anchor'
-       );
-
-       specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
-       expectedSpecialCharacters = $( '<a>' ).attr( {
-               title: specialCharactersPageName,
-               href: mw.util.wikiGetlink( specialCharactersPageName )
-       } ).text( specialCharactersPageName ).getOuterHtml();
-
-       mw.messages.set( 'special-characters', '[[' + specialCharactersPageName + ']]' );
-       assert.equal(
-               parser( 'special-characters' ),
-               expectedSpecialCharacters,
-               'Special characters'
-       );
-});
-
-QUnit.test( 'Int', 4, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction(),
-           newarticletextSource = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the [[{{Int:Helppage}}|help page]] for more info). If you are here by mistake, click your browser\'s back button.',
-               expectedNewarticletext;
-
-       mw.messages.set( 'helppage', 'Help:Contents' );
-
-       expectedNewarticletext = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the ' +
-               $( '<a>' ).attr( {
-                       title: mw.msg( 'helppage' ),
-                       href: mw.util.wikiGetlink( mw.msg( 'helppage' ) )
-               } ).text( 'help page' ).getOuterHtml() + ' for more info). If you are here by mistake, click your browser\'s back button.';
-
-       mw.messages.set( 'newarticletext', newarticletextSource );
-
-       assert.equal(
-               parser( 'newarticletext' ),
-               expectedNewarticletext,
-               'Link with nested message'
-       );
-
-       mw.messages.set( 'portal-url', 'Project:Community portal' );
-       mw.messages.set( 'see-portal-url', '{{Int:portal-url}} is an important community page.' );
-       assert.equal(
-               parser( 'see-portal-url' ),
-               'Project:Community portal is an important community page.',
-               'Nested message'
-       );
-
-       mw.messages.set( 'newarticletext-lowercase',
-               newarticletextSource.replace( 'Int:Helppage', 'int:helppage' ) );
-
-       assert.equal(
-               parser( 'newarticletext-lowercase' ),
-               expectedNewarticletext,
-               'Link with nested message, lowercase include'
-       );
-
-       mw.messages.set( 'uses-missing-int', '{{int:doesnt-exist}}' );
-
-       assert.equal(
-               parser( 'uses-missing-int' ),
-               '[doesnt-exist]',
-               'int: where nested message does not exist'
-       );
-});
-
-// Tests that getMessageFunction is used for messages with curly braces or square brackets,
-// but not otherwise.
-QUnit.test( 'mw.msg()', 8, function ( assert ) {
-       // Should be
-       var map, oldGMF, outerCalled, innerCalled;
-
-       map = new mw.Map();
-       map.set( {
-               'curly-brace': '{{int:message}}',
-               'single-square-bracket': '[https://www.mediawiki.org/ MediaWiki]',
-               'double-square-bracket': '[[Some page]]',
-               'regular': 'Other message'
+
+       QUnit.test( 'Links', 6, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction(),
+                       expectedDisambiguationsText,
+                       expectedMultipleBars,
+                       expectedSpecialCharacters;
+
+               /*
+                The below three are all identical to or based on real messages.  For disambiguations-text,
+                the bold was removed because it is not yet implemented.
+                */
+
+               assert.equal(
+                       parser( 'jquerymsg-test-statistics-users' ),
+                       expectedListUsers,
+                       'Piped wikilink'
+               );
+
+               expectedDisambiguationsText = 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from ' +
+                       $( '<a>' ).attr( {
+                               title: 'MediaWiki:Disambiguationspage',
+                               href: mw.util.wikiGetlink( 'MediaWiki:Disambiguationspage' )
+                       } ).text( 'MediaWiki:Disambiguationspage' ).getOuterHtml() + '.';
+               mw.messages.set( 'disambiguations-text', 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from [[MediaWiki:Disambiguationspage]].' );
+               assert.equal(
+                       parser( 'disambiguations-text' ),
+                       expectedDisambiguationsText,
+                       'Wikilink without pipe'
+               );
+
+               assert.equal(
+                       parser( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       expectedEntrypoints,
+                       'External link'
+               );
+
+               // Pipe trick is not supported currently, but should not parse as text either.
+               mw.messages.set( 'pipe-trick', '[[Tampa, Florida|]]' );
+               assert.equal(
+                       parser( 'pipe-trick' ),
+                       'pipe-trick: Parse error at position 0 in input: [[Tampa, Florida|]]',
+                       'Pipe trick should return error string.'
+               );
+
+               expectedMultipleBars = $( '<a>' ).attr( {
+                       title: 'Main Page',
+                       href: mw.util.wikiGetlink( 'Main Page' )
+               } ).text( 'Main|Page' ).getOuterHtml();
+               mw.messages.set( 'multiple-bars', '[[Main Page|Main|Page]]' );
+               assert.equal(
+                       parser( 'multiple-bars' ),
+                       expectedMultipleBars,
+                       'Bar in anchor'
+               );
+
+               expectedSpecialCharacters = $( '<a>' ).attr( {
+                       title: specialCharactersPageName,
+                       href: mw.util.wikiGetlink( specialCharactersPageName )
+               } ).text( specialCharactersPageName ).getOuterHtml();
+
+               mw.messages.set( 'special-characters', '[[' + specialCharactersPageName + ']]' );
+               assert.equal(
+                       parser( 'special-characters' ),
+                       expectedSpecialCharacters,
+                       'Special characters'
+               );
        } );
 
-       oldGMF = mw.jqueryMsg.getMessageFunction;
+// Tests that {{-transformation vs. general parsing are done as requested
+       QUnit.test( 'Curly brace transformation', 14, function ( assert ) {
+               var formatText, formatParse, oldUserLang;
+
+               oldUserLang = mw.config.get( 'wgUserLanguage' );
 
-       mw.jqueryMsg.getMessageFunction = function() {
-               outerCalled = true;
-               return function() {
-                       innerCalled = true;
+               formatText = mw.jqueryMsg.getMessageFunction( {
+                       format: 'text'
+               } );
+
+               formatParse = mw.jqueryMsg.getMessageFunction( {
+                       format: 'parse'
+               } );
+
+               // When the expected result is the same in both modes
+               function assertBothModes( parserArguments, expectedResult, assertMessage ) {
+                       assert.equal( formatText.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'text\'' );
+                       assert.equal( formatParse.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'parse\'' );
+               }
+
+               assertBothModes( ['gender-msg', 'Bob', 'male'], 'Bob: blue', 'gender is resolved' );
+
+               assertBothModes( ['plural-msg', 5], 'Found 5 items', 'plural is resolved' );
+
+               assertBothModes( ['grammar-msg'], 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'grammar is resolved' );
+
+               mw.config.set( 'wgUserLanguage', 'en' );
+               assertBothModes( ['formatnum-msg', '987654321.654321'], '987654321.654321', 'formatnum is resolved' );
+
+               // Test non-{{ wikitext, where behavior differs
+
+               // Wikilink
+               assert.equal(
+                       formatText( 'jquerymsg-test-statistics-users' ),
+                       mw.messages.get( 'jquerymsg-test-statistics-users' ),
+                       'Internal link message unchanged when format is \'text\''
+               );
+               assert.equal(
+                       formatParse( 'jquerymsg-test-statistics-users' ),
+                       expectedListUsers,
+                       'Internal link message parsed when format is \'parse\''
+               );
+
+               // External link
+               assert.equal(
+                       formatText( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       mw.messages.get( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       'External link message unchanged when format is \'text\''
+               );
+               assert.equal(
+                       formatParse( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       expectedEntrypoints,
+                       'External link message processed when format is \'parse\''
+               );
+
+               // External link with parameter
+               assert.equal(
+                       formatText( 'external-link-replace', 'http://example.com' ),
+                       'Foo [http://example.com bar]',
+                       'External link message only substitutes parameter when format is \'text\''
+               );
+               assert.equal(
+                       formatParse( 'external-link-replace', 'http://example.com' ),
+                       'Foo <a href="http://example.com">bar</a>',
+                       'External link message processed when format is \'parse\''
+               );
+
+               mw.config.set( 'wgUserLanguage', oldUserLang );
+       } );
+
+       QUnit.test( 'Int', 4, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction(),
+                       newarticletextSource = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the [[{{Int:Helppage}}|help page]] for more info). If you are here by mistake, click your browser\'s back button.',
+                       expectedNewarticletext;
+
+               mw.messages.set( 'helppage', 'Help:Contents' );
+
+               expectedNewarticletext = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the ' +
+                       $( '<a>' ).attr( {
+                               title: mw.msg( 'helppage' ),
+                               href: mw.util.wikiGetlink( mw.msg( 'helppage' ) )
+                       } ).text( 'help page' ).getOuterHtml() + ' for more info). If you are here by mistake, click your browser\'s back button.';
+
+               mw.messages.set( 'newarticletext', newarticletextSource );
+
+               assert.equal(
+                       parser( 'newarticletext' ),
+                       expectedNewarticletext,
+                       'Link with nested message'
+               );
+
+               assert.equal(
+                       parser( 'see-portal-url' ),
+                       'Project:Community portal is an important community page.',
+                       'Nested message'
+               );
+
+               mw.messages.set( 'newarticletext-lowercase',
+                       newarticletextSource.replace( 'Int:Helppage', 'int:helppage' ) );
+
+               assert.equal(
+                       parser( 'newarticletext-lowercase' ),
+                       expectedNewarticletext,
+                       'Link with nested message, lowercase include'
+               );
+
+               mw.messages.set( 'uses-missing-int', '{{int:doesnt-exist}}' );
+
+               assert.equal(
+                       parser( 'uses-missing-int' ),
+                       '[doesnt-exist]',
+                       'int: where nested message does not exist'
+               );
+       } );
+
+// Tests that getMessageFunction is used for non-plain messages with curly braces or
+// square brackets, but not otherwise.
+       QUnit.test( 'mw.Message.prototype.parser monkey-patch', 22, function ( assert ) {
+               var oldGMF, outerCalled, innerCalled;
+
+               mw.messages.set( {
+                       'curly-brace': '{{int:message}}',
+                       'single-square-bracket': '[https://www.mediawiki.org/ MediaWiki]',
+                       'double-square-bracket': '[[Some page]]',
+                       'regular': 'Other message'
+               } );
+
+               oldGMF = mw.jqueryMsg.getMessageFunction;
+
+               mw.jqueryMsg.getMessageFunction = function () {
+                       outerCalled = true;
+                       return function () {
+                               innerCalled = true;
+                       };
                };
-       };
-
-       function verifyGetMessageFunction( key, shouldCall ) {
-               outerCalled = false;
-               innerCalled = false;
-               ( new mw.Message( map, key ) ).parser();
-               assert.strictEqual( outerCalled, shouldCall, 'Outer function called for ' + key );
-               assert.strictEqual( innerCalled, shouldCall, 'Inner function called for ' + key );
-       }
 
-       verifyGetMessageFunction( 'curly-brace', true );
-       verifyGetMessageFunction( 'single-square-bracket', true );
-       verifyGetMessageFunction( 'double-square-bracket', true );
-       verifyGetMessageFunction( 'regular', false );
-
-       mw.jqueryMsg.getMessageFunction = oldGMF;
-} );
-
-formatnumTests = [
-       {
-               lang: 'en',
-               number: 987654321.654321,
-               result: '987654321.654321',
-               description: 'formatnum test for English, decimal seperator'
-       },
-       {
-               lang: 'ar',
-               number: 987654321.654321,
-               result: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
-               description: 'formatnum test for Arabic, with decimal seperator'
-       },
-       {
-               lang: 'ar',
-               number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
-               result: 987654321,
-               integer: true,
-               description: 'formatnum test for Arabic, with decimal seperator, reverse'
-       },
-       {
-               lang: 'ar',
-               number: -12.89,
-               result: '-١٢٫٨٩',
-               description: 'formatnum test for Arabic, negative number'
-       },
-       {
-               lang: 'ar',
-               number: '-١٢٫٨٩',
-               result: -12,
-               integer: true,
-               description: 'formatnum test for Arabic, negative number, reverse'
-       },
-       {
-               lang: 'nl',
-               number: 987654321.654321,
-               result: '987654321,654321',
-               description: 'formatnum test for Nederlands, decimal seperator'
-       },
-       {
-               lang: 'nl',
-               number: -12.89,
-               result: '-12,89',
-               description: 'formatnum test for Nederlands, negative number'
-       },
-       {
-               lang: 'nl',
-               number: 'invalidnumber',
-               result: 'invalidnumber',
-               description: 'formatnum test for Nederlands, invalid number'
-       }
-];
-
-QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
-       mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
-       mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
-       $.each( formatnumTests, function ( i, test ) {
-               QUnit.stop();
-               getMwLanguage( test.lang, function ( langClass ) {
-                       QUnit.start();
-                       if ( !langClass ) {
-                               assert.ok( false, 'Language "' + test.lang + '" failed to load' );
-                               return;
-                       }
-                       mw.messages.set(test.message );
-                       mw.config.set( 'wgUserLanguage', test.lang ) ;
-                       var parser = new mw.jqueryMsg.parser( { language: langClass } );
-                       assert.equal(
-                               parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
-                                       [ test.number ] ).html(),
-                               test.result,
-                               test.description
-                       );
+               function verifyGetMessageFunction( key, format, shouldCall ) {
+                       var message;
+                       outerCalled = false;
+                       innerCalled = false;
+                       message = mw.message( key );
+                       message[format]();
+                       assert.strictEqual( outerCalled, shouldCall, 'Outer function called for ' + key );
+                       assert.strictEqual( innerCalled, shouldCall, 'Inner function called for ' + key );
+               }
+
+               verifyGetMessageFunction( 'curly-brace', 'parse', true );
+               verifyGetMessageFunction( 'curly-brace', 'plain', false );
+
+               verifyGetMessageFunction( 'single-square-bracket', 'parse', true );
+               verifyGetMessageFunction( 'single-square-bracket', 'plain', false );
+
+               verifyGetMessageFunction( 'double-square-bracket', 'parse', true );
+               verifyGetMessageFunction( 'double-square-bracket', 'plain', false );
+
+               verifyGetMessageFunction( 'regular', 'parse', false );
+               verifyGetMessageFunction( 'regular', 'plain', false );
+
+               verifyGetMessageFunction( 'jquerymsg-test-pagetriage-del-talk-page-notify-summary', 'plain', false );
+               verifyGetMessageFunction( 'jquerymsg-test-categorytree-collapse-bullet', 'plain', false );
+               verifyGetMessageFunction( 'jquerymsg-test-wikieditor-toolbar-help-content-signature-result', 'plain', false );
+
+               mw.jqueryMsg.getMessageFunction = oldGMF;
+       } );
+
+       formatnumTests = [
+               {
+                       lang: 'en',
+                       number: 987654321.654321,
+                       result: '987654321.654321',
+                       description: 'formatnum test for English, decimal seperator'
+               },
+               {
+                       lang: 'ar',
+                       number: 987654321.654321,
+                       result: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
+                       description: 'formatnum test for Arabic, with decimal seperator'
+               },
+               {
+                       lang: 'ar',
+                       number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
+                       result: 987654321,
+                       integer: true,
+                       description: 'formatnum test for Arabic, with decimal seperator, reverse'
+               },
+               {
+                       lang: 'ar',
+                       number: -12.89,
+                       result: '-١٢٫٨٩',
+                       description: 'formatnum test for Arabic, negative number'
+               },
+               {
+                       lang: 'ar',
+                       number: '-١٢٫٨٩',
+                       result: -12,
+                       integer: true,
+                       description: 'formatnum test for Arabic, negative number, reverse'
+               },
+               {
+                       lang: 'nl',
+                       number: 987654321.654321,
+                       result: '987654321,654321',
+                       description: 'formatnum test for Nederlands, decimal seperator'
+               },
+               {
+                       lang: 'nl',
+                       number: -12.89,
+                       result: '-12,89',
+                       description: 'formatnum test for Nederlands, negative number'
+               },
+               {
+                       lang: 'nl',
+                       number: 'invalidnumber',
+                       result: 'invalidnumber',
+                       description: 'formatnum test for Nederlands, invalid number'
+               }
+       ];
+
+       QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
+               mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
+               $.each( formatnumTests, function ( i, test ) {
+                       QUnit.stop();
+                       getMwLanguage( test.lang, function ( langClass ) {
+                               QUnit.start();
+                               if ( !langClass ) {
+                                       assert.ok( false, 'Language "' + test.lang + '" failed to load' );
+                                       return;
+                               }
+                               mw.messages.set( test.message );
+                               mw.config.set( 'wgUserLanguage', test.lang );
+                               var parser = new mw.jqueryMsg.parser( { language: langClass } );
+                               assert.equal(
+                                       parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
+                                               [ test.number ] ).html(),
+                                       test.result,
+                                       test.description
+                               );
+                       } );
                } );
        } );
-});
 
 }( mediaWiki, jQuery ) );
index bc6fafe..3328ce3 100644 (file)
@@ -14,7 +14,7 @@
                assert.deepEqual( ŝablono, orig, 'ŝablono' );
                assert.deepEqual( \u015dablono, orig, '\\u015dablono' );
                assert.deepEqual( \u015Dablono, orig, '\\u015Dablono' );
-       });
+       } );
 
        /*
        // Not that we need this. ;)
                }
 
                for ( n = 0; n < maxn; n++ ) {
-                       expected = repeat('\n', n) + 'some text';
+                       expected = repeat( '\n', n ) + 'some text';
 
-                       $textarea = $('<textarea>\n' + expected + '</textarea>');
+                       $textarea = $( '<textarea>\n' + expected + '</textarea>' );
                        assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (HTML contained ' + (n + 1) + ')' );
 
-                       $textarea = $('<textarea>').val( expected );
+                       $textarea = $( '<textarea>' ).val( expected );
                        assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (from DOM set with ' + n + ')' );
                }
-       });
+       } );
 }( jQuery ) );
index 869ebe4..9ca434f 100644 (file)
@@ -1,6 +1,7 @@
 ( function ( mw, $ ) {
+       'use strict';
 
-       QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment({
+       QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment( {
                setup: function () {
                        this.liveLangData = mw.language.data.values;
                        mw.language.data.values = $.extend( true, {}, this.liveLangData );
@@ -8,12 +9,12 @@
                teardown: function () {
                        mw.language.data.values = this.liveLangData;
                }
-       }) );
+       } ) );
 
        QUnit.test( 'mw.language getData and setData', 2, function ( assert ) {
                mw.language.setData( 'en', 'testkey', 'testvalue' );
-               assert.equal(  mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
-               assert.equal(  mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
+               assert.equal( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
+               assert.equal( mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
        } );
 
        function grammarTest( langCode, test ) {
                QUnit.test( 'Grammar test for lang=' + langCode, function ( assert ) {
                        QUnit.expect( test.length );
 
-                       for ( var i = 0 ; i < test.length; i++ ) {
+                       for ( var i = 0; i < test.length; i++ ) {
                                assert.equal(
                                        mw.language.convertGrammar( test[i].word, test[i].grammarForm ),
                                        test[i].expected,
                                        test[i].description
                                );
                        }
-               });
+               } );
        }
 
+       // These tests run only for the current UI language.
        var grammarTests = {
                bs: [
                        {
                                word: 'тесть',
                                grammarForm: 'genitive',
                                expected: 'тестя',
-                               description: 'Grammar test for genitive case'
+                               description: 'Grammar test for genitive case, тесть -> тестя'
                        },
                        {
                                word: 'привилегия',
                                grammarForm: 'genitive',
                                expected: 'привилегии',
-                               description: 'Grammar test for genitive case'
+                               description: 'Grammar test for genitive case, привилегия -> привилегии'
                        },
                        {
                                word: 'установка',
                                grammarForm: 'genitive',
                                expected: 'установки',
-                               description: 'Grammar test for genitive case'
+                               description: 'Grammar test for genitive case, установка -> установки'
                        },
                        {
                                word: 'похоти',
                                grammarForm: 'genitive',
                                expected: 'похотей',
-                               description: 'Grammar test for genitive case'
+                               description: 'Grammar test for genitive case, похоти -> похотей'
                        },
                        {
                                word: 'доводы',
                                grammarForm: 'genitive',
                                expected: 'доводов',
-                               description: 'Grammar test for genitive case'
+                               description: 'Grammar test for genitive case, доводы -> доводов'
                        },
                        {
                                word: 'песчаник',
                                grammarForm: 'genitive',
                                expected: 'песчаника',
-                               description: 'Grammar test for genitive case'
+                               description: 'Grammar test for genitive case, песчаник -> песчаника'
+                       },
+                       {
+                               word: 'данные',
+                               grammarForm: 'genitive',
+                               expected: 'данных',
+                               description: 'Grammar test for genitive case, данные -> данных'
+                       },
+                       {
+                               word: 'тесть',
+                               grammarForm: 'prepositional',
+                               expected: 'тесте',
+                               description: 'Grammar test for prepositional case, тесть -> тесте'
+                       },
+                       {
+                               word: 'привилегия',
+                               grammarForm: 'prepositional',
+                               expected: 'привилегии',
+                               description: 'Grammar test for prepositional case, привилегия -> привилегии'
+                       },
+                       {
+                               word: 'установка',
+                               grammarForm: 'prepositional',
+                               expected: 'установке',
+                               description: 'Grammar test for prepositional case, установка -> установке'
+                       },
+                       {
+                               word: 'похоти',
+                               grammarForm: 'prepositional',
+                               expected: 'похотях',
+                               description: 'Grammar test for prepositional case, похоти -> похотях'
+                       },
+                       {
+                               word: 'доводы',
+                               grammarForm: 'prepositional',
+                               expected: 'доводах',
+                               description: 'Grammar test for prepositional case, доводы -> доводах'
+                       },
+                       {
+                               word: 'песчаник',
+                               grammarForm: 'prepositional',
+                               expected: 'песчанике',
+                               description: 'Grammar test for prepositional case, песчаник -> песчанике'
+                       },
+                       {
+                               word: 'данные',
+                               grammarForm: 'prepositional',
+                               expected: 'данных',
+                               description: 'Grammar test for prepositional case, данные -> данных'
                        }
                ],
 
-
                hu: [
                        {
                                word: 'Wikipédiá',
                if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
                        grammarTest( langCode, test );
                }
-       });
+       } );
 }( mediaWiki, jQuery ) );
index dc7bd0a..9b540a8 100644 (file)
 ( function ( mw, $ ) {
+       var specialCharactersPageName;
+
+       // Since QUnitTestResources.php loads both mediawiki and mediawiki.jqueryMsg as
+       // dependencies, this only tests the monkey-patched behavior with the two of them combined.
+
+       // See mediawiki.jqueryMsg.test.js for unit tests for jqueryMsg-specific functionality.
+
+       QUnit.module( 'mediawiki', QUnit.newMwEnvironment( {
+               setup: function () {
+                       // Messages used in multiple tests
+                       mw.messages.set( {
+                               'other-message': 'Other Message',
+                               'mediawiki-test-pagetriage-del-talk-page-notify-summary': 'Notifying author of deletion nomination for [[$1]]',
+                               'gender-plural-msg': '{{GENDER:$1|he|she|they}} {{PLURAL:$2|is|are}} awesome',
+                               'grammar-msg': 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}',
+                               'formatnum-msg': '{{formatnum:$1}}',
+                               'int-msg': 'Some {{int:other-message}}'
+                       } );
 
-QUnit.module( 'mediawiki', QUnit.newMwEnvironment() );
-
-QUnit.test( 'Initial check', 8, function ( assert ) {
-       assert.ok( window.jQuery, 'jQuery defined' );
-       assert.ok( window.$, '$j defined' );
-       assert.ok( window.$j, '$j defined' );
-       assert.strictEqual( window.$, window.jQuery, '$ alias to jQuery' );
-       assert.strictEqual( window.$j, window.jQuery, '$j alias to jQuery' );
-
-       assert.ok( window.mediaWiki, 'mediaWiki defined' );
-       assert.ok( window.mw, 'mw defined' );
-       assert.strictEqual( window.mw, window.mediaWiki, 'mw alias to mediaWiki' );
-});
-
-QUnit.test( 'mw.Map', 17, function ( assert ) {
-       var arry, conf, funky, globalConf, nummy, someValues;
-
-       assert.ok( mw.Map, 'mw.Map defined' );
-
-       conf = new mw.Map();
-       // Dummy variables
-       funky = function () {};
-       arry = [];
-       nummy = 7;
-
-       // Tests for input validation
-       assert.strictEqual( conf.get( 'inexistantKey' ), null, 'Map.get returns null if selection was a string and the key was not found' );
-       assert.strictEqual( conf.set( 'myKey', 'myValue' ), true, 'Map.set returns boolean true if a value was set for a valid key string' );
-       assert.strictEqual( conf.set( funky, 'Funky' ), false, 'Map.set returns boolean false if key was invalid (Function)' );
-       assert.strictEqual( conf.set( arry, 'Arry' ), false, 'Map.set returns boolean false if key was invalid (Array)' );
-       assert.strictEqual( conf.set( nummy, 'Nummy' ), false, 'Map.set returns boolean false if key was invalid (Number)' );
-       assert.equal( conf.get( 'myKey' ), 'myValue', 'Map.get returns a single value value correctly' );
-       assert.strictEqual( conf.get( nummy ), null, 'Map.get ruturns null if selection was invalid (Number)' );
-       assert.strictEqual( conf.get( funky ), null, 'Map.get ruturns null if selection was invalid (Function)' );
-
-       // Multiple values at once
-       someValues = {
-               'foo': 'bar',
-               'lorem': 'ipsum',
-               'MediaWiki': true
-       };
-       assert.strictEqual( conf.set( someValues ), true, 'Map.set returns boolean true if multiple values were set by passing an object' );
-       assert.deepEqual( conf.get( ['foo', 'lorem'] ), {
-               'foo': 'bar',
-               'lorem': 'ipsum'
-       }, 'Map.get returns multiple values correctly as an object' );
-
-       assert.deepEqual( conf.get( ['foo', 'notExist'] ), {
-               'foo': 'bar',
-               'notExist': null
-       }, 'Map.get return includes keys that were not found as null values' );
-
-       assert.strictEqual( conf.exists( 'foo' ), true, 'Map.exists returns boolean true if a key exists' );
-       assert.strictEqual( conf.exists( 'notExist' ), false, 'Map.exists returns boolean false if a key does not exists' );
-
-       // Interacting with globals and accessing the values object
-       assert.strictEqual( conf.get(), conf.values, 'Map.get returns the entire values object by reference (if called without arguments)' );
-
-       conf.set( 'globalMapChecker', 'Hi' );
-
-       assert.ok( false === 'globalMapChecker' in window, 'new mw.Map did not store its values in the global window object by default' );
-
-       globalConf = new mw.Map( true );
-       globalConf.set( 'anotherGlobalMapChecker', 'Hello' );
-
-       assert.ok( 'anotherGlobalMapChecker' in window, 'new mw.Map( true ) did store its values in the global window object' );
-
-       // Whitelist this global variable for QUnit's 'noglobal' mode
-       if ( QUnit.config.noglobals ) {
-               QUnit.config.pollution.push( 'anotherGlobalMapChecker' );
-       }
-});
-
-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', 20, function ( assert ) {
-       var goodbye, hello, pluralMessage;
-
-       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' );
-
-       assert.equal( hello.format, 'plain', 'Message property "format" defaults to "plain"' );
-       assert.strictEqual( hello.map, mw.messages, 'Message property "map" defaults to the global instance in mw.messages' );
-       assert.equal( hello.key, 'hello', 'Message property "key" (currect key)' );
-       assert.deepEqual( hello.parameters, [], 'Message property "parameters" defaults to an empty array' );
-
-       // Todo
-       assert.ok( hello.params, 'Message prototype "params"' );
-
-       hello.format = 'plain';
-       assert.equal( hello.toString(), 'Hello <b>awesome</b> world', 'Message.toString returns the message as a string with the current "format"' );
-
-       assert.equal( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; world', 'Message.escaped returns the escaped message' );
-       assert.equal( hello.format, 'escaped', 'Message.escaped correctly updated the "format" property' );
-
-       hello.parse();
-       assert.equal( hello.format, 'parse', 'Message.parse correctly updated the "format" property' );
-
-       hello.plain();
-       assert.equal( hello.format, 'plain', 'Message.plain correctly updated the "format" property' );
-
-       assert.strictEqual( hello.exists(), true, 'Message.exists returns true for existing messages' );
-
-       goodbye = mw.message( 'goodbye' );
-       assert.strictEqual( goodbye.exists(), false, 'Message.exists returns false for nonexistent messages' );
-
-       assert.equal( goodbye.plain(), '<goodbye>', 'Message.toString returns plain <key> if format is "plain" and key does not exist' );
-       // bug 30684
-       assert.equal( goodbye.escaped(), '&lt;goodbye&gt;', 'Message.toString returns properly escaped &lt;key&gt; if format is "escaped" and key does not exist' );
-
-       assert.ok( mw.messages.set( 'pluraltestmsg', 'There {{PLURAL:$1|is|are}} $1 {{PLURAL:$1|result|results}}' ), 'mw.messages.set: Register' );
-       pluralMessage = mw.message( 'pluraltestmsg' , 6 );
-       assert.equal( pluralMessage.plain(), 'There are 6 results', 'plural get resolved when format is plain' );
-       assert.equal( pluralMessage.parse(), 'There are 6 results', 'plural get resolved when format is parse' );
-
-});
-
-QUnit.test( 'mw.msg', 11, 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.ok( mw.messages.set( 'plural-item' , 'Found $1 {{PLURAL:$1|item|items}}' ) );
-       assert.equal( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' );
-       assert.equal( mw.msg( 'plural-item', 0 ), 'Found 0 items', 'Apply plural for count 0' );
-       assert.equal( mw.msg( 'plural-item', 1 ), 'Found 1 item', 'Apply plural for count 1' );
-
-       assert.ok( mw.messages.set('gender-plural-msg' , '{{GENDER:$1|he|she|they}} {{PLURAL:$2|is|are}} awesome' ) );
-       assert.equal( mw.msg( 'gender-plural-msg', 'male', 1 ), 'he is awesome', 'Gender test for male, plural count 1' );
-       assert.equal( mw.msg( 'gender-plural-msg', 'female', '1' ), 'she is awesome', 'Gender test for female, plural count 1' );
-       assert.equal( mw.msg( 'gender-plural-msg', 'unknown', 10 ), 'they are awesome', 'Gender test for neutral, plural count 10' );
-
-});
-
-/**
- * The sync style load test (for @import). This is, in a way, also an open bug for
- * ResourceLoader ("execute js after styles are loaded"), but browsers don't offer a
- * way to get a callback from when a stylesheet is loaded (that is, including any
- * @import rules inside). To work around this, we'll have a little time loop to check
- * if the styles apply.
- * Note: This test originally used new Image() and onerror to get a callback
- * when the url is loaded, but that is fragile since it doesn't monitor the
- * same request as the css @import, and Safari 4 has issues with
- * onerror/onload not being fired at all in weird cases like this.
- */
-function assertStyleAsync( assert, $element, prop, val, fn ) {
-       var styleTestStart,
-               el = $element.get( 0 ),
-               styleTestTimeout = ( QUnit.config.testTimeout - 200 ) || 5000;
-
-       function isCssImportApplied() {
-               // Trigger reflow, repaint, redraw, whatever (cross-browser)
-               var x = $element.css( 'height' );
-               x = el.innerHTML;
-               el.className = el.className;
-               x = document.documentElement.clientHeight;
-
-               return $element.css( prop ) === val;
-       }
+                       // For formatnum tests
+                       mw.config.set( 'wgUserLanguage', 'en' );
+
+                       specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
+               }
+       } ) );
+
+       QUnit.test( 'Initial check', 8, function ( assert ) {
+               assert.ok( window.jQuery, 'jQuery defined' );
+               assert.ok( window.$, '$j defined' );
+               assert.ok( window.$j, '$j defined' );
+               assert.strictEqual( window.$, window.jQuery, '$ alias to jQuery' );
+               assert.strictEqual( window.$j, window.jQuery, '$j alias to jQuery' );
+
+               assert.ok( window.mediaWiki, 'mediaWiki defined' );
+               assert.ok( window.mw, 'mw defined' );
+               assert.strictEqual( window.mw, window.mediaWiki, 'mw alias to mediaWiki' );
+       } );
+
+       QUnit.test( 'mw.Map', 17, function ( assert ) {
+               var arry, conf, funky, globalConf, nummy, someValues;
+
+               assert.ok( mw.Map, 'mw.Map defined' );
+
+               conf = new mw.Map();
+               // Dummy variables
+               funky = function () {};
+               arry = [];
+               nummy = 7;
+
+               // Tests for input validation
+               assert.strictEqual( conf.get( 'inexistantKey' ), null, 'Map.get returns null if selection was a string and the key was not found' );
+               assert.strictEqual( conf.set( 'myKey', 'myValue' ), true, 'Map.set returns boolean true if a value was set for a valid key string' );
+               assert.strictEqual( conf.set( funky, 'Funky' ), false, 'Map.set returns boolean false if key was invalid (Function)' );
+               assert.strictEqual( conf.set( arry, 'Arry' ), false, 'Map.set returns boolean false if key was invalid (Array)' );
+               assert.strictEqual( conf.set( nummy, 'Nummy' ), false, 'Map.set returns boolean false if key was invalid (Number)' );
+               assert.equal( conf.get( 'myKey' ), 'myValue', 'Map.get returns a single value value correctly' );
+               assert.strictEqual( conf.get( nummy ), null, 'Map.get ruturns null if selection was invalid (Number)' );
+               assert.strictEqual( conf.get( funky ), null, 'Map.get ruturns null if selection was invalid (Function)' );
+
+               // Multiple values at once
+               someValues = {
+                       'foo': 'bar',
+                       'lorem': 'ipsum',
+                       'MediaWiki': true
+               };
+               assert.strictEqual( conf.set( someValues ), true, 'Map.set returns boolean true if multiple values were set by passing an object' );
+               assert.deepEqual( conf.get( ['foo', 'lorem'] ), {
+                       'foo': 'bar',
+                       'lorem': 'ipsum'
+               }, 'Map.get returns multiple values correctly as an object' );
+
+               assert.deepEqual( conf.get( ['foo', 'notExist'] ), {
+                       'foo': 'bar',
+                       'notExist': null
+               }, 'Map.get return includes keys that were not found as null values' );
+
+               assert.strictEqual( conf.exists( 'foo' ), true, 'Map.exists returns boolean true if a key exists' );
+               assert.strictEqual( conf.exists( 'notExist' ), false, 'Map.exists returns boolean false if a key does not exists' );
+
+               // Interacting with globals and accessing the values object
+               assert.strictEqual( conf.get(), conf.values, 'Map.get returns the entire values object by reference (if called without arguments)' );
+
+               conf.set( 'globalMapChecker', 'Hi' );
+
+               assert.ok( false === 'globalMapChecker' in window, 'new mw.Map did not store its values in the global window object by default' );
+
+               globalConf = new mw.Map( true );
+               globalConf.set( 'anotherGlobalMapChecker', 'Hello' );
+
+               assert.ok( 'anotherGlobalMapChecker' in window, 'new mw.Map( true ) did store its values in the global window object' );
+
+               // Whitelist this global variable for QUnit's 'noglobal' mode
+               if ( QUnit.config.noglobals ) {
+                       QUnit.config.pollution.push( 'anotherGlobalMapChecker' );
+               }
+       } );
+
+       QUnit.test( 'mw.config', 1, function ( assert ) {
+               assert.ok( mw.config instanceof mw.Map, 'mw.config instance of mw.Map' );
+       } );
 
-       function styleTestLoop() {
-               var styleTestSince = new Date().getTime() - styleTestStart;
-               // If it is passing or if we timed out, run the real test and stop the loop
-               if ( isCssImportApplied() || styleTestSince > styleTestTimeout ) {
-                       assert.equal( $element.css( prop ), val,
-                               'style "' + prop + ': ' + val + '" from url is applied (after ' + styleTestSince + 'ms)'
-                       );
+       QUnit.test( 'mw.message & mw.messages', 54, function ( assert ) {
+               var goodbye, hello;
 
-                       if ( fn ) {
-                               fn();
+               // Convenience method for asserting the same result for multiple formats
+               function assertMultipleFormats( messageArguments, formats, expectedResult, assertMessage ) {
+                       var len = formats.length, format, i;
+                       for ( i = 0; i < len; i++ ) {
+                               format = formats[i];
+                               assert.equal( mw.message.apply( null, messageArguments )[format](), expectedResult, assertMessage + ' when format is ' + format );
                        }
+               }
+
+               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' );
+
+               // https://bugzilla.wikimedia.org/show_bug.cgi?id=44459
+               assert.equal( hello.format, 'text', 'Message property "format" defaults to "text"' );
+
+               assert.strictEqual( hello.map, mw.messages, 'Message property "map" defaults to the global instance in mw.messages' );
+               assert.equal( hello.key, 'hello', 'Message property "key" (currect key)' );
+               assert.deepEqual( hello.parameters, [], 'Message property "parameters" defaults to an empty array' );
+
+               // Todo
+               assert.ok( hello.params, 'Message prototype "params"' );
+
+               hello.format = 'plain';
+               assert.equal( hello.toString(), 'Hello <b>awesome</b> world', 'Message.toString returns the message as a string with the current "format"' );
+
+               assert.equal( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; world', 'Message.escaped returns the escaped message' );
+               assert.equal( hello.format, 'escaped', 'Message.escaped correctly updated the "format" property' );
+
+               assert.ok( mw.messages.set( 'escaped-with-curly-brace', '"{{SITENAME}}" is the home of {{int:other-message}}' ) );
+               assert.equal( mw.message( 'escaped-with-curly-brace' ).escaped(), mw.html.escape( '"' + mw.config.get( 'wgSiteName' ) + '" is the home of Other Message' ), 'Escaped format works correctly for curly brace message' );
+
+               assert.ok( mw.messages.set( 'escaped-with-square-brackets', 'Visit the [[Project:Community portal|community portal]] & [[Project:Help desk|help desk]]' ) );
+               assert.equal( mw.message( 'escaped-with-square-brackets' ).escaped(), 'Visit the [[Project:Community portal|community portal]] &amp; [[Project:Help desk|help desk]]', 'Escaped format works correctly for square bracket message' );
+
+               hello.parse();
+               assert.equal( hello.format, 'parse', 'Message.parse correctly updated the "format" property' );
+
+               hello.plain();
+               assert.equal( hello.format, 'plain', 'Message.plain correctly updated the "format" property' );
+
+               hello.text();
+               assert.equal( hello.format, 'text', 'Message.text correctly updated the "format" property' );
+
+               assert.strictEqual( hello.exists(), true, 'Message.exists returns true for existing messages' );
+
+               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' );
+
+               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' );
+               assert.equal( mw.message( 'plural-test-msg', 6 ).plain(), 'There {{PLURAL:6|is|are}} 6 {{PLURAL:6|result|results}}', 'Parameter is substituted but plural is not resolved in plain' );
+
+               assertMultipleFormats( ['mediawiki-test-pagetriage-del-talk-page-notify-summary'], ['plain', 'text'], mw.messages.get( 'mediawiki-test-pagetriage-del-talk-page-notify-summary' ), 'Double square brackets with no parameters unchanged' );
 
-                       return;
+               assertMultipleFormats( ['mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName], ['plain', 'text'], 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets with one parameter' );
+
+               assert.equal( mw.message( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ).escaped(), 'Notifying author of deletion nomination for [[' + mw.html.escape( specialCharactersPageName ) + ']]', 'Double square brackets with one parameter, when escaped' );
+
+
+               assert.ok( mw.messages.set( 'mediawiki-test-categorytree-collapse-bullet', '[<b>−</b>]' ), 'mw.messages.set: Register' );
+               assert.equal( mw.message( 'mediawiki-test-categorytree-collapse-bullet' ).plain(), mw.messages.get( 'mediawiki-test-categorytree-collapse-bullet' ), 'Single square brackets unchanged in plain mode' );
+
+               assert.ok( mw.messages.set( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result', '<a href=\'#\' title=\'{{#special:mypage}}\'>Username</a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk</a>)' ) );
+               assert.equal( mw.message( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ).plain(), mw.messages.get( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ), 'HTML message with curly braces is not changed in plain mode' );
+
+               assertMultipleFormats( ['gender-plural-msg', 'male', 1], ['text', 'parse', 'escaped'], 'he is awesome', 'Gender and plural are resolved' );
+               assert.equal( mw.message( 'gender-plural-msg', 'male', 1 ).plain(), '{{GENDER:male|he|she|they}} {{PLURAL:1|is|are}} awesome', 'Parameters are substituted, but gender and plural are not resolved in plain mode' );
+
+               assert.equal( mw.message( 'grammar-msg' ).plain(), mw.messages.get( 'grammar-msg' ), 'Grammar is not resolved in plain mode' );
+               assertMultipleFormats( ['grammar-msg'], ['text', 'parse'], 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar is resolved' );
+               assert.equal( mw.message( 'grammar-msg' ).escaped(), 'Przeszukaj ' + mw.html.escape( mw.config.get( 'wgSiteName' ) ), 'Grammar is resolved in escaped mode' );
+
+               assertMultipleFormats( ['formatnum-msg', '987654321.654321'], ['text', 'parse', 'escaped'], '987654321.654321', 'formatnum is resolved' );
+               assert.equal( mw.message( 'formatnum-msg' ).plain(), mw.messages.get( 'formatnum-msg' ), 'formatnum is not resolved in plain mode' );
+
+               assertMultipleFormats( ['int-msg'], ['text', 'parse', 'escaped'], 'Some Other Message', 'int is resolved' );
+               assert.equal( mw.message( 'int-msg' ).plain(), mw.messages.get( 'int-msg' ), 'int is not resolved in plain mode' );
+       } );
+
+       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.ok( mw.messages.set( 'plural-item', 'Found $1 {{PLURAL:$1|item|items}}' ) );
+               assert.equal( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' );
+               assert.equal( mw.msg( 'plural-item', 0 ), 'Found 0 items', 'Apply plural for count 0' );
+               assert.equal( mw.msg( 'plural-item', 1 ), 'Found 1 item', 'Apply plural for count 1' );
+
+               assert.equal( mw.msg( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ), 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets in mw.msg one parameter' );
+
+               assert.equal( mw.msg( 'gender-plural-msg', 'male', 1 ), 'he is awesome', 'Gender test for male, plural count 1' );
+               assert.equal( mw.msg( 'gender-plural-msg', 'female', '1' ), 'she is awesome', 'Gender test for female, plural count 1' );
+               assert.equal( mw.msg( 'gender-plural-msg', 'unknown', 10 ), 'they are awesome', 'Gender test for neutral, plural count 10' );
+
+               assert.equal( mw.msg( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar is resolved' );
+
+               assert.equal( mw.msg( 'formatnum-msg', '987654321.654321' ), '987654321.654321', 'formatnum is resolved' );
+
+               assert.equal( mw.msg( 'int-msg' ), 'Some Other Message', 'int is resolved' );
+       } );
+
+       /**
+        * The sync style load test (for @import). This is, in a way, also an open bug for
+        * ResourceLoader ("execute js after styles are loaded"), but browsers don't offer a
+        * way to get a callback from when a stylesheet is loaded (that is, including any
+        * @import rules inside). To work around this, we'll have a little time loop to check
+        * if the styles apply.
+        * Note: This test originally used new Image() and onerror to get a callback
+        * when the url is loaded, but that is fragile since it doesn't monitor the
+        * same request as the css @import, and Safari 4 has issues with
+        * onerror/onload not being fired at all in weird cases like this.
+        */
+       function assertStyleAsync( assert, $element, prop, val, fn ) {
+               var styleTestStart,
+                       el = $element.get( 0 ),
+                       styleTestTimeout = ( QUnit.config.testTimeout - 200 ) || 5000;
+
+               function isCssImportApplied() {
+                       // Trigger reflow, repaint, redraw, whatever (cross-browser)
+                       var x = $element.css( 'height' );
+                       x = el.innerHTML;
+                       el.className = el.className;
+                       x = document.documentElement.clientHeight;
+
+                       return $element.css( prop ) === val;
                }
-               // Otherwise, keep polling
-               setTimeout( styleTestLoop, 150 );
-       }
 
-       // Start the loop
-       styleTestStart = new Date().getTime();
-       styleTestLoop();
-}
-
-function urlStyleTest( selector, prop, val ) {
-       return QUnit.fixurl(
-               mw.config.get( 'wgScriptPath' ) +
-                       '/tests/qunit/data/styleTest.css.php?' +
-                       $.param( {
-                               selector: selector,
-                               prop: prop,
-                               val: val
-                       } )
-       );
-}
-
-QUnit.asyncTest( 'mw.loader', 2, function ( assert ) {
-       var isAwesomeDone;
-
-       mw.loader.testCallback = function () {
-               QUnit.start();
-               assert.strictEqual( isAwesomeDone, undefined, 'Implementing module is.awesome: isAwesomeDone should still be undefined');
-               isAwesomeDone = true;
-       };
-
-       mw.loader.implement( 'test.callback', [QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/callMwLoaderTestCallback.js' )], {}, {} );
-
-       mw.loader.using( 'test.callback', function () {
-
-               // /sample/awesome.js declares the "mw.loader.testCallback" function
-               // which contains a call to start() and ok()
-               assert.strictEqual( isAwesomeDone, true, 'test.callback module should\'ve caused isAwesomeDone to be true' );
-               delete mw.loader.testCallback;
-
-       }, function () {
-               QUnit.start();
-               assert.ok( false, 'Error callback fired while loader.using "test.callback" module' );
-       });
-});
-
-QUnit.test( 'mw.loader.implement( styles={ "css": [text, ..] } )', 2, function ( assert ) {
-       var $element = $( '<div class="mw-test-implement-a"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element.css( 'float' ),
-               'right',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.a',
-               function () {
-                       assert.equal(
-                               $element.css( 'float' ),
-                               'right',
-                               'style is applied'
-                       );
-               },
-               {
-                       'all': '.mw-test-implement-a { float: right; }'
-               },
-               {}
-       );
-
-       mw.loader.load([
-               'test.implement.a'
-       ]);
-} );
-
-QUnit.asyncTest( 'mw.loader.implement( styles={ "url": { <media>: [url, ..] } } )', 7, function ( assert ) {
-       var $element1 = $( '<div class="mw-test-implement-b1"></div>' ).appendTo( '#qunit-fixture' ),
-               $element2 = $( '<div class="mw-test-implement-b2"></div>' ).appendTo( '#qunit-fixture' ),
-               $element3 = $( '<div class="mw-test-implement-b3"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element1.css( 'text-align' ),
-               'center',
-               'style is clear'
-       );
-       assert.notEqual(
-               $element2.css( 'float' ),
-               'left',
-               'style is clear'
-       );
-       assert.notEqual(
-               $element3.css( 'text-align' ),
-               'right',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.b',
-               function () {
-                       // Note: QUnit.start() must only be called when the entire test is
-                       // complete. So, make sure that we don't start until *both*
-                       // assertStyleAsync calls have completed.
-                       var pending = 2;
-                       assertStyleAsync( assert, $element2, 'float', 'left', function () {
-                               assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
-
-                               pending--;
-                               if ( pending === 0 ) {
-                                       QUnit.start();
-                               }
-                       } );
-                       assertStyleAsync( assert, $element3, 'float', 'right', function () {
-                               assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
+               function styleTestLoop() {
+                       var styleTestSince = new Date().getTime() - styleTestStart;
+                       // If it is passing or if we timed out, run the real test and stop the loop
+                       if ( isCssImportApplied() || styleTestSince > styleTestTimeout ) {
+                               assert.equal( $element.css( prop ), val,
+                                       'style "' + prop + ': ' + val + '" from url is applied (after ' + styleTestSince + 'ms)'
+                               );
 
-                               pending--;
-                               if ( pending === 0 ) {
-                                       QUnit.start();
+                               if ( fn ) {
+                                       fn();
                                }
-                       } );
-               },
-               {
-                       'url': {
-                               'print': [urlStyleTest( '.mw-test-implement-b1', 'text-align', 'center' )],
-                               'screen': [
-                                       // bug 40834: Make sure it actually works with more than 1 stylesheet reference
-                                       urlStyleTest( '.mw-test-implement-b2', 'float', 'left' ),
-                                       urlStyleTest( '.mw-test-implement-b3', 'float', 'right' )
-                               ]
+
+                               return;
                        }
-               },
-               {}
-       );
+                       // Otherwise, keep polling
+                       setTimeout( styleTestLoop, 150 );
+               }
+
+               // Start the loop
+               styleTestStart = new Date().getTime();
+               styleTestLoop();
+       }
+
+       function urlStyleTest( selector, prop, val ) {
+               return QUnit.fixurl(
+                       mw.config.get( 'wgScriptPath' ) +
+                               '/tests/qunit/data/styleTest.css.php?' +
+                               $.param( {
+                                       selector: selector,
+                                       prop: prop,
+                                       val: val
+                               } )
+               );
+       }
 
-       mw.loader.load([
-               'test.implement.b'
-       ]);
-} );
+       QUnit.asyncTest( 'mw.loader', 2, function ( assert ) {
+               var isAwesomeDone;
+
+               mw.loader.testCallback = function () {
+                       QUnit.start();
+                       assert.strictEqual( isAwesomeDone, undefined, 'Implementing module is.awesome: isAwesomeDone should still be undefined' );
+                       isAwesomeDone = true;
+               };
+
+               mw.loader.implement( 'test.callback', [QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/callMwLoaderTestCallback.js' )], {}, {} );
+
+               mw.loader.using( 'test.callback', function () {
+
+                       // /sample/awesome.js declares the "mw.loader.testCallback" function
+                       // which contains a call to start() and ok()
+                       assert.strictEqual( isAwesomeDone, true, 'test.callback module should\'ve caused isAwesomeDone to be true' );
+                       delete mw.loader.testCallback;
+
+               }, function () {
+                       QUnit.start();
+                       assert.ok( false, 'Error callback fired while loader.using "test.callback" module' );
+               } );
+       } );
+
+       QUnit.test( 'mw.loader.implement( styles={ "css": [text, ..] } )', 2, function ( assert ) {
+               var $element = $( '<div class="mw-test-implement-a"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element.css( 'float' ),
+                       'right',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.a',
+                       function () {
+                               assert.equal(
+                                       $element.css( 'float' ),
+                                       'right',
+                                       'style is applied'
+                               );
+                       },
+                       {
+                               'all': '.mw-test-implement-a { float: right; }'
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.a'
+               ] );
+       } );
+
+       QUnit.asyncTest( 'mw.loader.implement( styles={ "url": { <media>: [url, ..] } } )', 7, function ( assert ) {
+               var $element1 = $( '<div class="mw-test-implement-b1"></div>' ).appendTo( '#qunit-fixture' ),
+                       $element2 = $( '<div class="mw-test-implement-b2"></div>' ).appendTo( '#qunit-fixture' ),
+                       $element3 = $( '<div class="mw-test-implement-b3"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element1.css( 'text-align' ),
+                       'center',
+                       'style is clear'
+               );
+               assert.notEqual(
+                       $element2.css( 'float' ),
+                       'left',
+                       'style is clear'
+               );
+               assert.notEqual(
+                       $element3.css( 'text-align' ),
+                       'right',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.b',
+                       function () {
+                               // Note: QUnit.start() must only be called when the entire test is
+                               // complete. So, make sure that we don't start until *both*
+                               // assertStyleAsync calls have completed.
+                               var pending = 2;
+                               assertStyleAsync( assert, $element2, 'float', 'left', function () {
+                                       assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
+
+                                       pending--;
+                                       if ( pending === 0 ) {
+                                               QUnit.start();
+                                       }
+                               } );
+                               assertStyleAsync( assert, $element3, 'float', 'right', function () {
+                                       assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
+
+                                       pending--;
+                                       if ( pending === 0 ) {
+                                               QUnit.start();
+                                       }
+                               } );
+                       },
+                       {
+                               'url': {
+                                       'print': [urlStyleTest( '.mw-test-implement-b1', 'text-align', 'center' )],
+                                       'screen': [
+                                               // bug 40834: Make sure it actually works with more than 1 stylesheet reference
+                                               urlStyleTest( '.mw-test-implement-b2', 'float', 'left' ),
+                                               urlStyleTest( '.mw-test-implement-b3', 'float', 'right' )
+                                       ]
+                               }
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.b'
+               ] );
+       } );
 
 // Backwards compatibility
-QUnit.test( 'mw.loader.implement( styles={ <media>: text } ) (back-compat)', 2, function ( assert ) {
-       var $element = $( '<div class="mw-test-implement-c"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element.css( 'float' ),
-               'right',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.c',
-               function () {
-                       assert.equal(
-                               $element.css( 'float' ),
-                               'right',
-                               'style is applied'
-                       );
-               },
-               {
-                       'all': '.mw-test-implement-c { float: right; }'
-               },
-               {}
-       );
-
-       mw.loader.load([
-               'test.implement.c'
-       ]);
-} );
+       QUnit.test( 'mw.loader.implement( styles={ <media>: text } ) (back-compat)', 2, function ( assert ) {
+               var $element = $( '<div class="mw-test-implement-c"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element.css( 'float' ),
+                       'right',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.c',
+                       function () {
+                               assert.equal(
+                                       $element.css( 'float' ),
+                                       'right',
+                                       'style is applied'
+                               );
+                       },
+                       {
+                               'all': '.mw-test-implement-c { float: right; }'
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.c'
+               ] );
+       } );
 
 // Backwards compatibility
-QUnit.asyncTest( 'mw.loader.implement( styles={ <media>: [url, ..] } ) (back-compat)', 4, function ( assert ) {
-       var $element = $( '<div class="mw-test-implement-d"></div>' ).appendTo( '#qunit-fixture' ),
-               $element2 = $( '<div class="mw-test-implement-d2"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element.css( 'float' ),
-               'right',
-               'style is clear'
-       );
-       assert.notEqual(
-               $element2.css( 'text-align' ),
-               'center',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.d',
-               function () {
-                       assertStyleAsync( assert, $element, 'float', 'right', function () {
-
-                               assert.notEqual( $element2.css( 'text-align' ), 'center', 'print style is not applied (bug 40500)' );
+       QUnit.asyncTest( 'mw.loader.implement( styles={ <media>: [url, ..] } ) (back-compat)', 4, function ( assert ) {
+               var $element = $( '<div class="mw-test-implement-d"></div>' ).appendTo( '#qunit-fixture' ),
+                       $element2 = $( '<div class="mw-test-implement-d2"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element.css( 'float' ),
+                       'right',
+                       'style is clear'
+               );
+               assert.notEqual(
+                       $element2.css( 'text-align' ),
+                       'center',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.d',
+                       function () {
+                               assertStyleAsync( assert, $element, 'float', 'right', function () {
+
+                                       assert.notEqual( $element2.css( 'text-align' ), 'center', 'print style is not applied (bug 40500)' );
 
-                               QUnit.start();
-                       } );
-               },
-               {
-                       'all': [urlStyleTest( '.mw-test-implement-d', 'float', 'right' )],
-                       'print': [urlStyleTest( '.mw-test-implement-d2', 'text-align', 'center' )]
-               },
-               {}
-       );
-
-       mw.loader.load([
-               'test.implement.d'
-       ]);
-} );
+                                       QUnit.start();
+                               } );
+                       },
+                       {
+                               'all': [urlStyleTest( '.mw-test-implement-d', 'float', 'right' )],
+                               'print': [urlStyleTest( '.mw-test-implement-d2', 'text-align', 'center' )]
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.d'
+               ] );
+       } );
 
 // @import (bug 31676)
-QUnit.asyncTest( 'mw.loader.implement( styles has @import)', 5, function ( assert ) {
-       var isJsExecuted, $element;
+       QUnit.asyncTest( 'mw.loader.implement( styles has @import)', 5, function ( assert ) {
+               var isJsExecuted, $element;
 
-       mw.loader.implement(
-               'test.implement.import',
-               function () {
-                       assert.strictEqual( isJsExecuted, undefined, 'javascript not executed multiple times' );
-                       isJsExecuted = true;
+               mw.loader.implement(
+                       'test.implement.import',
+                       function () {
+                               assert.strictEqual( isJsExecuted, undefined, 'javascript not executed multiple times' );
+                               isJsExecuted = true;
 
-                       assert.equal( mw.loader.getState( 'test.implement.import' ), 'ready', 'module state is "ready" while implement() is executing javascript' );
+                               assert.equal( mw.loader.getState( 'test.implement.import' ), 'ready', 'module state is "ready" while implement() is executing javascript' );
 
-                       $element = $( '<div class="mw-test-implement-import">Foo bar</div>' ).appendTo( '#qunit-fixture' );
+                               $element = $( '<div class="mw-test-implement-import">Foo bar</div>' ).appendTo( '#qunit-fixture' );
 
-                       assert.equal( mw.msg( 'test-foobar' ), 'Hello Foobar, $1!', 'Messages are loaded before javascript execution' );
+                               assert.equal( mw.msg( 'test-foobar' ), 'Hello Foobar, $1!', 'Messages are loaded before javascript execution' );
 
-                       assertStyleAsync( assert, $element, 'float', 'right', function () {
-                               assert.equal( $element.css( 'text-align' ),'center',
-                                       'CSS styles after the @import rule are working'
-                               );
+                               assertStyleAsync( assert, $element, 'float', 'right', function () {
+                                       assert.equal( $element.css( 'text-align' ), 'center',
+                                               'CSS styles after the @import rule are working'
+                                       );
 
-                               QUnit.start();
-                       } );
-               },
-               {
-                       'css': [
-                               '@import url(\''
-                               + urlStyleTest( '.mw-test-implement-import', 'float', 'right' )
-                               + '\');\n'
-                               + '.mw-test-implement-import { text-align: center; }'
-                       ]
-               },
-               {
-                       'test-foobar': 'Hello Foobar, $1!'
-               }
-       );
-
-       mw.loader.load( 'test.implement' );
-
-});
-
-QUnit.asyncTest( 'mw.loader.implement( only messages )' , 2, function ( assert ) {
-       assert.assertFalse( mw.messages.exists( 'bug_29107' ), 'Verify that the test message doesn\'t exist yet' );
-
-       mw.loader.implement( 'test.implement.msgs', [], {}, { 'bug_29107': 'loaded' } );
-       mw.loader.using( 'test.implement.msgs', function() {
-               QUnit.start();
-               assert.ok( mw.messages.exists( 'bug_29107' ), 'Bug 29107: messages-only module should implement ok' );
-       }, function() {
-               QUnit.start();
-               assert.ok( false, 'Error callback fired while implementing "test.implement.msgs" module' );
-       });
-});
-
-QUnit.test( 'mw.loader erroneous indirect dependency', 3, function ( assert ) {
-       mw.loader.register( [
-               ['test.module1', '0'],
-               ['test.module2', '0', ['test.module1']],
-               ['test.module3', '0', ['test.module2']]
-       ] );
-       mw.loader.implement( 'test.module1', function () { throw new Error( 'expected' ); }, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module1' ), 'error', 'Expected "error" state for test.module1' );
-       assert.strictEqual( mw.loader.getState( 'test.module2' ), 'error', 'Expected "error" state for test.module2' );
-       assert.strictEqual( mw.loader.getState( 'test.module3' ), 'error', 'Expected "error" state for test.module3' );
-} );
-
-QUnit.test( 'mw.loader out-of-order implementation', 9, function ( assert ) {
-       mw.loader.register( [
-               ['test.module4', '0'],
-               ['test.module5', '0', ['test.module4']],
-               ['test.module6', '0', ['test.module5']]
-       ] );
-       mw.loader.implement( 'test.module4', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
-       assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
-       assert.strictEqual( mw.loader.getState( 'test.module6' ), 'registered', 'Expected "registered" state for test.module6' );
-       mw.loader.implement( 'test.module6', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
-       assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
-       assert.strictEqual( mw.loader.getState( 'test.module6' ), 'loaded', 'Expected "loaded" state for test.module6' );
-       mw.loader.implement( 'test.module5', function() {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
-       assert.strictEqual( mw.loader.getState( 'test.module5' ), 'ready', 'Expected "ready" state for test.module5' );
-       assert.strictEqual( mw.loader.getState( 'test.module6' ), 'ready', 'Expected "ready" state for test.module6' );
-} );
-
-QUnit.test( 'mw.loader missing dependency', 13, function ( assert ) {
-       mw.loader.register( [
-               ['test.module7', '0'],
-               ['test.module8', '0', ['test.module7']],
-               ['test.module9', '0', ['test.module8']]
-       ] );
-       mw.loader.implement( 'test.module8', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module7' ), 'registered', 'Expected "registered" state for test.module7' );
-       assert.strictEqual( mw.loader.getState( 'test.module8' ), 'loaded', 'Expected "loaded" state for test.module8' );
-       assert.strictEqual( mw.loader.getState( 'test.module9' ), 'registered', 'Expected "registered" state for test.module9' );
-       mw.loader.state( 'test.module7', 'missing' );
-       assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
-       assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
-       assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
-       mw.loader.implement( 'test.module9', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
-       assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
-       assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
-       mw.loader.using(
-               ['test.module7'],
-               function () {
-                       assert.ok( false, 'Success fired despite missing dependency' );
-                       assert.ok( true , 'QUnit expected() count dummy' );
-               },
-               function ( e, dependencies ) {
-                       assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
-                       assert.deepEqual( dependencies, ['test.module7'], 'Error callback called with module test.module7' );
-               }
-       );
-       mw.loader.using(
-               ['test.module9'],
-               function () {
-                       assert.ok( false, 'Success fired despite missing dependency' );
-                       assert.ok( true , 'QUnit expected() count dummy' );
-               },
-               function ( e, dependencies ) {
-                       assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
-                       dependencies.sort();
-                       assert.deepEqual(
-                               dependencies,
-                               ['test.module7', 'test.module8', 'test.module9'],
-                               'Error callback called with all three modules as dependencies'
-                       );
-               }
-       );
-} );
-
-QUnit.asyncTest( 'mw.loader dependency handling', 5, function ( assert ) {
-       mw.loader.addSource(
-               'testloader',
-               {
-                       loadScript: QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/load.mock.php' )
-               }
-       );
-
-       mw.loader.register( [
-               // [module, version, dependencies, group, source]
-               ['testMissing', '1', [], null, 'testloader'],
-               ['testUsesMissing', '1', ['testMissing'], null, 'testloader'],
-               ['testUsesNestedMissing', '1', ['testUsesMissing'], null, 'testloader']
-       ] );
-
-       function verifyModuleStates() {
-               assert.equal( mw.loader.getState( 'testMissing' ), 'missing', 'Module not known to server must have state "missing"' );
-               assert.equal( mw.loader.getState( 'testUsesMissing' ), 'error', 'Module with missing dependency must have state "error"' );
-               assert.equal( mw.loader.getState( 'testUsesNestedMissing' ), 'error', 'Module with indirect missing dependency must have state "error"' );
-       }
-
-       mw.loader.using( ['testUsesNestedMissing'],
-               function () {
-                       assert.ok( false, 'Error handler should be invoked.' );
-                       assert.ok( true ); // Dummy to reach QUnit expect()
+                                       QUnit.start();
+                               } );
+                       },
+                       {
+                               'css': [
+                                       '@import url(\''
+                                               + urlStyleTest( '.mw-test-implement-import', 'float', 'right' )
+                                               + '\');\n'
+                                               + '.mw-test-implement-import { text-align: center; }'
+                               ]
+                       },
+                       {
+                               'test-foobar': 'Hello Foobar, $1!'
+                       }
+               );
 
-                       verifyModuleStates();
+               mw.loader.load( 'test.implement' );
 
-                       QUnit.start();
-               },
-               function ( e, badmodules ) {
-                       assert.ok( true, 'Error handler should be invoked.' );
-                       // As soon as server spits out state('testMissing', 'missing');
-                       // it will bubble up and trigger the error callback.
-                       // Therefor the badmodules array is not testUsesMissing or testUsesNestedMissing.
-                       assert.deepEqual( badmodules, ['testMissing'], 'Bad modules as expected.' );
+       } );
 
-                       verifyModuleStates();
+       QUnit.asyncTest( 'mw.loader.implement( only messages )', 2, function ( assert ) {
+               assert.assertFalse( mw.messages.exists( 'bug_29107' ), 'Verify that the test message doesn\'t exist yet' );
 
+               mw.loader.implement( 'test.implement.msgs', [], {}, { 'bug_29107': 'loaded' } );
+               mw.loader.using( 'test.implement.msgs', function () {
                        QUnit.start();
+                       assert.ok( mw.messages.exists( 'bug_29107' ), 'Bug 29107: messages-only module should implement ok' );
+               }, function () {
+                       QUnit.start();
+                       assert.ok( false, 'Error callback fired while implementing "test.implement.msgs" module' );
+               } );
+       } );
+
+       QUnit.test( 'mw.loader erroneous indirect dependency', 3, function ( assert ) {
+               mw.loader.register( [
+                       ['test.module1', '0'],
+                       ['test.module2', '0', ['test.module1']],
+                       ['test.module3', '0', ['test.module2']]
+               ] );
+               mw.loader.implement( 'test.module1', function () {
+                       throw new Error( 'expected' );
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module1' ), 'error', 'Expected "error" state for test.module1' );
+               assert.strictEqual( mw.loader.getState( 'test.module2' ), 'error', 'Expected "error" state for test.module2' );
+               assert.strictEqual( mw.loader.getState( 'test.module3' ), 'error', 'Expected "error" state for test.module3' );
+       } );
+
+       QUnit.test( 'mw.loader out-of-order implementation', 9, function ( assert ) {
+               mw.loader.register( [
+                       ['test.module4', '0'],
+                       ['test.module5', '0', ['test.module4']],
+                       ['test.module6', '0', ['test.module5']]
+               ] );
+               mw.loader.implement( 'test.module4', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+               assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
+               assert.strictEqual( mw.loader.getState( 'test.module6' ), 'registered', 'Expected "registered" state for test.module6' );
+               mw.loader.implement( 'test.module6', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+               assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
+               assert.strictEqual( mw.loader.getState( 'test.module6' ), 'loaded', 'Expected "loaded" state for test.module6' );
+               mw.loader.implement( 'test.module5', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+               assert.strictEqual( mw.loader.getState( 'test.module5' ), 'ready', 'Expected "ready" state for test.module5' );
+               assert.strictEqual( mw.loader.getState( 'test.module6' ), 'ready', 'Expected "ready" state for test.module6' );
+       } );
+
+       QUnit.test( 'mw.loader missing dependency', 13, function ( assert ) {
+               mw.loader.register( [
+                       ['test.module7', '0'],
+                       ['test.module8', '0', ['test.module7']],
+                       ['test.module9', '0', ['test.module8']]
+               ] );
+               mw.loader.implement( 'test.module8', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module7' ), 'registered', 'Expected "registered" state for test.module7' );
+               assert.strictEqual( mw.loader.getState( 'test.module8' ), 'loaded', 'Expected "loaded" state for test.module8' );
+               assert.strictEqual( mw.loader.getState( 'test.module9' ), 'registered', 'Expected "registered" state for test.module9' );
+               mw.loader.state( 'test.module7', 'missing' );
+               assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
+               assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
+               assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
+               mw.loader.implement( 'test.module9', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
+               assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
+               assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
+               mw.loader.using(
+                       ['test.module7'],
+                       function () {
+                               assert.ok( false, 'Success fired despite missing dependency' );
+                               assert.ok( true, 'QUnit expected() count dummy' );
+                       },
+                       function ( e, dependencies ) {
+                               assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
+                               assert.deepEqual( dependencies, ['test.module7'], 'Error callback called with module test.module7' );
+                       }
+               );
+               mw.loader.using(
+                       ['test.module9'],
+                       function () {
+                               assert.ok( false, 'Success fired despite missing dependency' );
+                               assert.ok( true, 'QUnit expected() count dummy' );
+                       },
+                       function ( e, dependencies ) {
+                               assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
+                               dependencies.sort();
+                               assert.deepEqual(
+                                       dependencies,
+                                       ['test.module7', 'test.module8', 'test.module9'],
+                                       'Error callback called with all three modules as dependencies'
+                               );
+                       }
+               );
+       } );
+
+       QUnit.asyncTest( 'mw.loader dependency handling', 5, function ( assert ) {
+               mw.loader.addSource(
+                       'testloader',
+                       {
+                               loadScript: QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/load.mock.php' )
+                       }
+               );
+
+               mw.loader.register( [
+                       // [module, version, dependencies, group, source]
+                       ['testMissing', '1', [], null, 'testloader'],
+                       ['testUsesMissing', '1', ['testMissing'], null, 'testloader'],
+                       ['testUsesNestedMissing', '1', ['testUsesMissing'], null, 'testloader']
+               ] );
+
+               function verifyModuleStates() {
+                       assert.equal( mw.loader.getState( 'testMissing' ), 'missing', 'Module not known to server must have state "missing"' );
+                       assert.equal( mw.loader.getState( 'testUsesMissing' ), 'error', 'Module with missing dependency must have state "error"' );
+                       assert.equal( mw.loader.getState( 'testUsesNestedMissing' ), 'error', 'Module with indirect missing dependency must have state "error"' );
                }
-       );
-} );
 
-QUnit.asyncTest( 'mw.loader( "//protocol-relative" ) (bug 30825)', 2, function ( assert ) {
-       // This bug was actually already fixed in 1.18 and later when discovered in 1.17.
-       // Test is for regressions!
+               mw.loader.using( ['testUsesNestedMissing'],
+                       function () {
+                               assert.ok( false, 'Error handler should be invoked.' );
+                               assert.ok( true ); // Dummy to reach QUnit expect()
 
-       // Forge an URL to the test callback script
-       var target = QUnit.fixurl(
-               mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/qunitOkCall.js'
-       );
+                               verifyModuleStates();
 
-       // Confirm that mw.loader.load() works with protocol-relative URLs
-       target = target.replace( /https?:/, '' );
+                               QUnit.start();
+                       },
+                       function ( e, badmodules ) {
+                               assert.ok( true, 'Error handler should be invoked.' );
+                               // As soon as server spits out state('testMissing', 'missing');
+                               // it will bubble up and trigger the error callback.
+                               // Therefor the badmodules array is not testUsesMissing or testUsesNestedMissing.
+                               assert.deepEqual( badmodules, ['testMissing'], 'Bad modules as expected.' );
 
-       assert.equal( target.substr( 0, 2 ), '//',
-               'URL must be relative to test relative URLs!'
-       );
+                               verifyModuleStates();
 
-       // Async!
-       // The target calls QUnit.start
-       mw.loader.load( target );
-});
+                               QUnit.start();
+                       }
+               );
+       } );
 
-QUnit.test( 'mw.html', 13, function ( assert ) {
-       assert.throws( function () {
-               mw.html.escape();
-       }, TypeError, 'html.escape throws a TypeError if argument given is not a string' );
+       QUnit.asyncTest( 'mw.loader( "//protocol-relative" ) (bug 30825)', 2, function ( assert ) {
+               // This bug was actually already fixed in 1.18 and later when discovered in 1.17.
+               // Test is for regressions!
 
-       assert.equal( mw.html.escape( '<mw awesome="awesome" value=\'test\' />' ),
-               '&lt;mw awesome=&quot;awesome&quot; value=&#039;test&#039; /&gt;', 'escape() escapes special characters to html entities' );
+               // Forge an URL to the test callback script
+               var target = QUnit.fixurl(
+                       mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/qunitOkCall.js'
+               );
 
-       assert.equal( mw.html.element(),
-               '<undefined/>', 'element() always returns a valid html string (even without arguments)' );
+               // Confirm that mw.loader.load() works with protocol-relative URLs
+               target = target.replace( /https?:/, '' );
 
-       assert.equal( mw.html.element( 'div' ), '<div/>', 'element() Plain DIV (simple)' );
+               assert.equal( target.substr( 0, 2 ), '//',
+                       'URL must be relative to test relative URLs!'
+               );
 
-       assert.equal( mw.html.element( 'div', {}, '' ), '<div></div>', 'element() Basic DIV (simple)' );
+               // Async!
+               // The target calls QUnit.start
+               mw.loader.load( target );
+       } );
 
-       assert.equal(
-               mw.html.element(
-                       'div', {
-                               id: 'foobar'
-                       }
-               ),
-               '<div id="foobar"/>',
-               'html.element DIV (attribs)' );
-
-       assert.equal( mw.html.element( 'p', null, 12 ), '<p>12</p>', 'Numbers are valid content and should be casted to a string' );
-
-       assert.equal( mw.html.element( 'p', { title: 12 }, '' ), '<p title="12"></p>', 'Numbers are valid attribute values' );
-
-       // Example from https://www.mediawiki.org/wiki/ResourceLoader/Default_modules#mediaWiki.html
-       assert.equal(
-               mw.html.element(
-                       'div',
-                       {},
-                       new mw.html.Raw(
-                               mw.html.element( 'img', { src: '<' } )
-                       )
-               ),
-               '<div><img src="&lt;"/></div>',
-               'Raw inclusion of another element'
-       );
-
-       assert.equal(
-               mw.html.element(
-                       'option', {
-                               selected: true
-                       }, 'Foo'
-               ),
-               '<option selected="selected">Foo</option>',
-               'Attributes may have boolean values. True copies the attribute name to the value.'
-       );
-
-       assert.equal(
-               mw.html.element(
-                       'option', {
-                               value: 'foo',
-                               selected: false
-                       }, 'Foo'
-               ),
-               '<option value="foo">Foo</option>',
-               'Attributes may have boolean values. False keeps the attribute from output.'
-       );
-
-       assert.equal( mw.html.element( 'div',
+       QUnit.test( 'mw.html', 13, function ( assert ) {
+               assert.throws( function () {
+                       mw.html.escape();
+               }, TypeError, 'html.escape throws a TypeError if argument given is not a string' );
+
+               assert.equal( mw.html.escape( '<mw awesome="awesome" value=\'test\' />' ),
+                       '&lt;mw awesome=&quot;awesome&quot; value=&#039;test&#039; /&gt;', 'escape() escapes special characters to html entities' );
+
+               assert.equal( mw.html.element(),
+                       '<undefined/>', 'element() always returns a valid html string (even without arguments)' );
+
+               assert.equal( mw.html.element( 'div' ), '<div/>', 'element() Plain DIV (simple)' );
+
+               assert.equal( mw.html.element( 'div', {}, '' ), '<div></div>', 'element() Basic DIV (simple)' );
+
+               assert.equal(
+                       mw.html.element(
+                               'div', {
+                                       id: 'foobar'
+                               }
+                       ),
+                       '<div id="foobar"/>',
+                       'html.element DIV (attribs)' );
+
+               assert.equal( mw.html.element( 'p', null, 12 ), '<p>12</p>', 'Numbers are valid content and should be casted to a string' );
+
+               assert.equal( mw.html.element( 'p', { title: 12 }, '' ), '<p title="12"></p>', 'Numbers are valid attribute values' );
+
+               // Example from https://www.mediawiki.org/wiki/ResourceLoader/Default_modules#mediaWiki.html
+               assert.equal(
+                       mw.html.element(
+                               'div',
+                               {},
+                               new mw.html.Raw(
+                                       mw.html.element( 'img', { src: '<' } )
+                               )
+                       ),
+                       '<div><img src="&lt;"/></div>',
+                       'Raw inclusion of another element'
+               );
+
+               assert.equal(
+                       mw.html.element(
+                               'option', {
+                                       selected: true
+                               }, 'Foo'
+                       ),
+                       '<option selected="selected">Foo</option>',
+                       'Attributes may have boolean values. True copies the attribute name to the value.'
+               );
+
+               assert.equal(
+                       mw.html.element(
+                               'option', {
+                                       value: 'foo',
+                                       selected: false
+                               }, 'Foo'
+                       ),
+                       '<option value="foo">Foo</option>',
+                       'Attributes may have boolean values. False keeps the attribute from output.'
+               );
+
+               assert.equal( mw.html.element( 'div',
                        null, 'a' ),
-               '<div>a</div>',
-               'html.element DIV (content)' );
+                       '<div>a</div>',
+                       'html.element DIV (content)' );
 
-       assert.equal( mw.html.element( 'a',
+               assert.equal( mw.html.element( 'a',
                        { href: 'http://mediawiki.org/w/index.php?title=RL&action=history' }, 'a' ),
-               '<a href="http://mediawiki.org/w/index.php?title=RL&amp;action=history">a</a>',
-               'html.element DIV (attribs + content)' );
+                       '<a href="http://mediawiki.org/w/index.php?title=RL&amp;action=history">a</a>',
+                       'html.element DIV (attribs + content)' );
 
-});
+       } );
 
 }( mediaWiki, jQuery ) );
index a9bbbf7..875ab91 100644 (file)
@@ -1,55 +1,53 @@
 ( function ( mw, $ ) {
-
-QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment() );
-
-QUnit.test( 'options', 1, function ( assert ) {
-       assert.ok( mw.user.options instanceof mw.Map, 'options instance of mw.Map' );
-});
-
-QUnit.test( 'user status', 9, function ( assert ) {
-       /**
-        * Tests can be run under three different conditions:
-        *   1) From tests/qunit/index.html, user will be anonymous.
-        *   2) Logged in on [[Special:JavaScriptTest/qunit]]
-        *   3) Anonymously at the same special page.
-        */
-
-       // Forge an anonymous user:
-       mw.config.set( 'wgUserName', null );
-
-       assert.strictEqual( mw.user.getName(), null, 'user.getName() returns null when anonymous' );
-       assert.strictEqual( mw.user.name(), null, 'user.name() compatibility' );
-       assert.assertTrue( mw.user.isAnon(), 'user.isAnon() returns true when anonymous' );
-       assert.assertTrue( mw.user.anonymous(), 'user.anonymous() compatibility' );
-
-       // Not part of startUp module
-       mw.config.set( 'wgUserName', 'John' );
-
-       assert.equal( mw.user.getName(), 'John', 'user.getName() returns username when logged-in' );
-       assert.equal( mw.user.name(), 'John', 'user.name() compatibility' );
-       assert.assertFalse( mw.user.isAnon(), 'user.isAnon() returns false when logged-in' );
-       assert.assertFalse( mw.user.anonymous(), 'user.anonymous() compatibility' );
-
-       assert.equal( mw.user.id(), 'John', 'user.id Returns username when logged-in' );
-});
-
-QUnit.asyncTest( 'getGroups', 3, function ( assert ) {
-       mw.user.getGroups( function ( groups ) {
-               // First group should always be '*'
-               assert.equal( $.type( groups ), 'array', 'Callback gets an array' );
-               assert.notStrictEqual( $.inArray( '*', groups ), -1, '"*"" is in the list' );
-               // Sort needed because of different methods if creating the arrays,
-               // only the content matters.
-               assert.deepEqual( groups.sort(), mw.config.get( 'wgUserGroups' ).sort(), 'Array contains all groups, just like wgUserGroups' );
-               QUnit.start();
-       });
-});
-
-QUnit.asyncTest( 'getRights', 1, function ( assert ) {
-       mw.user.getRights( function ( rights ) {
-               assert.equal( $.type( rights ), 'array', 'Callback gets an array' );
-               QUnit.start();
-       });
-});
-
+       QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment() );
+
+       QUnit.test( 'options', 1, function ( assert ) {
+               assert.ok( mw.user.options instanceof mw.Map, 'options instance of mw.Map' );
+       } );
+
+       QUnit.test( 'user status', 9, function ( assert ) {
+               /**
+                * Tests can be run under three different conditions:
+                *   1) From tests/qunit/index.html, user will be anonymous.
+                *   2) Logged in on [[Special:JavaScriptTest/qunit]]
+                *   3) Anonymously at the same special page.
+                */
+
+               // Forge an anonymous user:
+               mw.config.set( 'wgUserName', null );
+
+               assert.strictEqual( mw.user.getName(), null, 'user.getName() returns null when anonymous' );
+               assert.strictEqual( mw.user.name(), null, 'user.name() compatibility' );
+               assert.assertTrue( mw.user.isAnon(), 'user.isAnon() returns true when anonymous' );
+               assert.assertTrue( mw.user.anonymous(), 'user.anonymous() compatibility' );
+
+               // Not part of startUp module
+               mw.config.set( 'wgUserName', 'John' );
+
+               assert.equal( mw.user.getName(), 'John', 'user.getName() returns username when logged-in' );
+               assert.equal( mw.user.name(), 'John', 'user.name() compatibility' );
+               assert.assertFalse( mw.user.isAnon(), 'user.isAnon() returns false when logged-in' );
+               assert.assertFalse( mw.user.anonymous(), 'user.anonymous() compatibility' );
+
+               assert.equal( mw.user.id(), 'John', 'user.id Returns username when logged-in' );
+       } );
+
+       QUnit.asyncTest( 'getGroups', 3, function ( assert ) {
+               mw.user.getGroups( function ( groups ) {
+                       // First group should always be '*'
+                       assert.equal( $.type( groups ), 'array', 'Callback gets an array' );
+                       assert.notStrictEqual( $.inArray( '*', groups ), -1, '"*"" is in the list' );
+                       // Sort needed because of different methods if creating the arrays,
+                       // only the content matters.
+                       assert.deepEqual( groups.sort(), mw.config.get( 'wgUserGroups' ).sort(), 'Array contains all groups, just like wgUserGroups' );
+                       QUnit.start();
+               } );
+       } );
+
+       QUnit.asyncTest( 'getRights', 1, function ( assert ) {
+               mw.user.getRights( function ( rights ) {
+                       assert.equal( $.type( rights ), 'array', 'Callback gets an array' );
+                       QUnit.start();
+               } );
+       } );
 }( mediaWiki, jQuery ) );
index c4212df..bba3160 100644 (file)
@@ -3,11 +3,11 @@
 
        QUnit.test( 'rawurlencode', 1, function ( assert ) {
                assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
-       });
+       } );
 
        QUnit.test( 'wikiUrlencode', 1, function ( assert ) {
                assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
-       });
+       } );
 
        QUnit.test( 'wikiGetlink', 3, function ( assert ) {
                // Not part of startUp module
 
                href = mw.util.wikiGetlink();
                assert.equal( href, '/wiki/Foobar', 'Default title; Get link for current page ("Foobar")' );
-       });
+       } );
 
        QUnit.test( 'wikiScript', 4, function ( assert ) {
-               mw.config.set({
+               mw.config.set( {
                        'wgScript': '/w/i.php', // customized wgScript for bug 39103
                        'wgLoadScript': '/w/l.php', // customized wgLoadScript for bug 39103
                        'wgScriptPath': '/w',
                        'wgScriptExtension': '.php'
-               });
+               } );
 
                assert.equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ),
                        'wikiScript() returns wgScript'
@@ -43,7 +43,7 @@
                        'wikiScript( load ) returns wgLoadScript'
                );
                assert.equal( mw.util.wikiScript( 'api' ), '/w/api.php', 'API path' );
-       });
+       } );
 
        QUnit.test( 'addCSS', 3, function ( assert ) {
                var $el, style;
@@ -57,7 +57,7 @@
 
                // Clean up
                $( style.ownerNode ).remove();
-       });
+       } );
 
        QUnit.asyncTest( 'toggleToc', 4, function ( assert ) {
                var tocHtml, $toggleLink;
 
                assert.strictEqual( mw.util.toggleToc(), null, 'Return null if there is no table of contents on the page.' );
 
-               tocHtml =
-                       '<table id="toc" class="toc"><tr><td>' +
-                               '<div id="toctitle">' +
-                                       '<h2>Contents</h2>' +
-                                       '<span class="toctoggle">&nbsp;[<a href="#" class="internal" id="togglelink">Hide</a>&nbsp;]</span>' +
-                               '</div>' +
-                               '<ul><li></li></ul>' +
+               tocHtml = '<table id="toc" class="toc"><tr><td>' +
+                       '<div id="toctitle">' +
+                       '<h2>Contents</h2>' +
+                       '<span class="toctoggle">&nbsp;[<a href="#" class="internal" id="togglelink">Hide</a>&nbsp;]</span>' +
+                       '</div>' +
+                       '<ul><li></li></ul>' +
                        '</td></tr></table>';
-               $(tocHtml).appendTo( '#qunit-fixture' ),
-               $toggleLink = $( '#togglelink' );
+               $( tocHtml ).appendTo( '#qunit-fixture' ),
+                       $toggleLink = $( '#togglelink' );
 
                assert.strictEqual( $toggleLink.length, 1, 'Toggle link is appended to the page.' );
 
                actionA();
-       });
+       } );
 
        QUnit.test( 'getParamValue', 5, function ( assert ) {
-               var     url;
+               var url;
 
                url = 'http://example.org/?foo=wrong&foo=right#&foo=bad';
                assert.equal( mw.util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
                url = 'http://example.org/#&foo=bad';
                assert.strictEqual( mw.util.getParamValue( 'foo', url ), null, 'Ignore hash if param is not in querystring but in hash (bug 27427)' );
 
-               url = 'example.org?' + $.param({ 'TEST': 'a b+c' });
+               url = 'example.org?' + $.param( { 'TEST': 'a b+c' } );
                assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c', 'Bug 30441: getParamValue must understand "+" encoding of space' );
 
-               url = 'example.org?' + $.param({ 'TEST': 'a b+c d' }); // check for sloppy code from r95332 :)
+               url = 'example.org?' + $.param( { 'TEST': 'a b+c d' } ); // check for sloppy code from r95332 :)
                assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c d', 'Bug 30441: getParamValue must understand "+" encoding of space (multiple spaces)' );
-       });
+       } );
 
        QUnit.test( 'tooltipAccessKey', 3, function ( assert ) {
                assert.equal( typeof mw.util.tooltipAccessKeyPrefix, 'string', 'mw.util.tooltipAccessKeyPrefix must be a string' );
                assert.ok( mw.util.tooltipAccessKeyRegexp instanceof RegExp, 'mw.util.tooltipAccessKeyRegexp instance of RegExp' );
                assert.ok( mw.util.updateTooltipAccessKeys, 'mw.util.updateTooltipAccessKeys' );
-       });
+       } );
 
        QUnit.test( '$content', 2, function ( assert ) {
                assert.ok( mw.util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
                assert.strictEqual( mw.util.$content.length, 1, 'mw.util.$content must have length of 1' );
-       });
-
+       } );
 
        /**
         * Portlet names are prefixed with 'p-test' to avoid conflict with core
                assert.equal( $tbMW.next().attr( 'id' ), 't-rl', 'Link is in the correct position (by passing nextnode)' );
 
                cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux' );
-               $cuQuux = $(cuQuux);
+               $cuQuux = $( cuQuux );
 
                assert.equal(
                        $( '#p-test-custom #c-barmenu ul li' ).length,
 
                caFoo = mw.util.addPortletLink( 'p-test-views', '#', 'Foo' );
 
-               assert.strictEqual( $tbMW.find( 'span').length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
-               assert.strictEqual( $( caFoo ).find( 'span').length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
-       });
+               assert.strictEqual( $tbMW.find( 'span' ).length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
+               assert.strictEqual( $( caFoo ).find( 'span' ).length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
+       } );
 
        QUnit.test( 'jsMessage', 1, function ( assert ) {
                var a = mw.util.jsMessage( 'MediaWiki is <b>Awesome</b>.' );
 
                // Clean up
                $( '#mw-js-message' ).remove();
-       });
+       } );
 
        QUnit.test( 'validateEmail', 6, function ( assert ) {
                assert.strictEqual( mw.util.validateEmail( '' ), null, 'Should return null for empty string ' );
                // testEmailWithHyphens
                assert.strictEqual( mw.util.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
                assert.strictEqual( mw.util.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
-       });
+       } );
 
        QUnit.test( 'isIPv6Address', 40, function ( assert ) {
                // Shortcuts
                function assertFalseIPv6( addy, summary ) {
                        return assert.strictEqual( mw.util.isIPv6Address( addy ), false, summary );
                }
+
                function assertTrueIPv6( addy, summary ) {
                        return assert.strictEqual( mw.util.isIPv6Address( addy ), true, summary );
                }
                assertFalseIPv6( 'fc:100:300', 'IPv6 with only 3 words' );
 
                $.each(
-               ['fc:100::',
-               'fc:100:a::',
-               'fc:100:a:d::',
-               'fc:100:a:d:1::',
-               'fc:100:a:d:1:e::',
-               'fc:100:a:d:1:e:ac::'], function ( i, addy ){
-                       assertTrueIPv6( addy, addy + ' is a valid IP' );
-               });
+                       ['fc:100::',
+                               'fc:100:a::',
+                               'fc:100:a:d::',
+                               'fc:100:a:d:1::',
+                               'fc:100:a:d:1:e::',
+                               'fc:100:a:d:1:e:ac::'], function ( i, addy ) {
+                               assertTrueIPv6( addy, addy + ' is a valid IP' );
+                       } );
 
                assertFalseIPv6( 'fc:100:a:d:1:e:ac:0::', 'IPv6 with 8 words ending with "::"' );
                assertFalseIPv6( 'fc:100:a:d:1:e:ac:0:1::', 'IPv6 with 9 words ending with "::"' );
 
                assertTrueIPv6( '::', 'IPv6 zero address' );
                $.each(
-               ['::0',
-               '::fc',
-               '::fc:100',
-               '::fc:100:a',
-               '::fc:100:a:d',
-               '::fc:100:a:d:1',
-               '::fc:100:a:d:1:e',
-               '::fc:100:a:d:1:e:ac',
-
-               'fc:100:a:d:1:e:ac:0'], function ( i, addy ){
-                       assertTrueIPv6( addy, addy + ' is a valid IP' );
-               });
+                       ['::0',
+                               '::fc',
+                               '::fc:100',
+                               '::fc:100:a',
+                               '::fc:100:a:d',
+                               '::fc:100:a:d:1',
+                               '::fc:100:a:d:1:e',
+                               '::fc:100:a:d:1:e:ac',
+
+                               'fc:100:a:d:1:e:ac:0'], function ( i, addy ) {
+                               assertTrueIPv6( addy, addy + ' is a valid IP' );
+                       } );
 
                assertFalseIPv6( '::fc:100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
                assertFalseIPv6( '::fc:100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
 
                assertFalseIPv6( 'fc::100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
                assertFalseIPv6( 'fc::100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
-       });
+       } );
 
        QUnit.test( 'isIPv4Address', 11, function ( assert ) {
                // Shortcuts
                function assertFalseIPv4( addy, summary ) {
                        assert.strictEqual( mw.util.isIPv4Address( addy ), false, summary );
                }
+
                function assertTrueIPv4( addy, summary ) {
                        assert.strictEqual( mw.util.isIPv4Address( addy ), true, summary );
                }
                assertTrueIPv4( '124.24.52.13', '124.24.52.134 is a valid IP' );
                assertTrueIPv4( '1.24.52.13', '1.24.52.13 is a valid IP' );
                assertFalseIPv4( '74.24.52.13/20', 'IPv4 ranges are not recogzized as valid IPs' );
-       });
+       } );
 }( mediaWiki, jQuery ) );
index ecf7f9e..07f9867 100644 (file)
@@ -47,7 +47,9 @@ class Selenium {
        public function start() {
                $this->tester = new Testing_Selenium( $this->browser, self::$url, $this->host,
                        $this->port, $this->timeout );
-               if ( method_exists( $this->tester, "setVerbose" ) ) $this->tester->setVerbose( $this->verbose );
+               if ( method_exists( $this->tester, "setVerbose" ) ) {
+                       $this->tester->setVerbose( $this->verbose );
+               }
 
                $this->tester->start();
                $this->isStarted = true;
@@ -94,7 +96,7 @@ class Selenium {
                $this->logger = $logger;
        }
 
-       public function getLogger( ) {
+       public function getLogger() {
                return $this->logger;
        }
 
@@ -106,7 +108,7 @@ class Selenium {
                self::$url = $url;
        }
 
-       static public function getUrl() {
+       public static function getUrl() {
                return self::$url;
        }
 
@@ -122,22 +124,21 @@ class Selenium {
                $this->user = $user;
        }
 
-        // Function to get username
-        public function getUser() {
+       // Function to get username
+       public function getUser() {
                return $this->user;
        }
-        
+
 
        public function setPass( $pass ) {
                $this->pass = $pass;
        }
 
-    //add function to get password    
-       public function getPass(  ) {
+       //add function to get password
+       public function getPass() {
                return $this->pass;
        }
-       
-       
+
        public function setHost( $host ) {
                $this->host = $host;
        }
@@ -154,7 +155,7 @@ class Selenium {
                $this->junitlogfile = $junitlogfile;
        }
 
-       public function getJUnitLogfile( ) {
+       public function getJUnitLogfile() {
                return $this->junitlogfile;
        }
 
@@ -163,7 +164,7 @@ class Selenium {
        }
 
        public function setBrowser( $b ) {
-               if ($this->runagainstgrid) {
+               if ( $this->runagainstgrid ) {
                        $this->browser = $b;
                        return true;
                }
@@ -184,7 +185,7 @@ class Selenium {
        }
 
        // Prevent external cloning
-       protected function __clone() { }
+       protected function __clone() {}
        // Prevent external construction
        // protected function __construct() {}
 }
index 04cf8d8..0823275 100644 (file)
@@ -10,14 +10,15 @@ class SeleniumConfig {
         * See sample config file in selenium_settings.ini.sample
         *
         */
-
-       public static function getSeleniumSettings ( &$seleniumSettings,
-                       &$seleniumBrowsers,
-                       &$seleniumTestSuites,
-                       $seleniumConfigFile = null ) {
+       public static function getSeleniumSettings( &$seleniumSettings,
+                                                                                               &$seleniumBrowsers,
+                                                                                               &$seleniumTestSuites,
+                                                                                               $seleniumConfigFile = null ) {
                if ( strlen( $seleniumConfigFile ) == 0 ) {
                        global $wgSeleniumConfigFile;
-                       if ( isset( $wgSeleniumConfigFile ) ) $seleniumConfigFile =  $wgSeleniumConfigFile ;
+                       if ( isset( $wgSeleniumConfigFile ) ) {
+                               $seleniumConfigFile = $wgSeleniumConfigFile;
+                       }
                }
 
                if ( strlen( $seleniumConfigFile ) == 0 || !file_exists( $seleniumConfigFile ) ) {
@@ -29,7 +30,7 @@ class SeleniumConfig {
                        throw new MWException( "Error parsing " . $seleniumConfigFile . "\n" );
                }
 
-               if ( array_key_exists( 'SeleniumSettings', $configArray ) {
+               if ( array_key_exists( 'SeleniumSettings', $configArray ) ) {
                        wfSuppressWarnings();
                        //we may need to change how this is set. But for now leave it in the ini file
                        $seleniumBrowsers = $configArray['SeleniumSettings']['browsers'];
@@ -48,7 +49,7 @@ class SeleniumConfig {
 
                        wfRestoreWarnings();
                }
-               if ( array_key_exists( 'SeleniumTests', $configArray ) {
+               if ( array_key_exists( 'SeleniumTests', $configArray ) ) {
                        wfSuppressWarnings();
                        $seleniumTestSuites = $configArray['SeleniumTests']['testSuite'];
                        wfRestoreWarnings();
index 9e2d4aa..3fbc831 100644 (file)
@@ -34,15 +34,22 @@ class SeleniumServerManager {
        private $SeleniumServerExecPath;
 
        public function __construct( $startServer,
-                                        $serverPort,
-                                        $serverExecPath ) {
-               $this->OS = (string) PHP_OS;
-               if ( isset( $startServer ) )
+                                                                $serverPort,
+                                                                $serverExecPath ) {
+               $this->OS = (string)PHP_OS;
+
+               if ( isset( $startServer ) ) {
                        $this->SeleniumStartServer = $startServer;
-               if ( isset( $serverPort ) )
+               }
+
+               if ( isset( $serverPort ) ) {
                        $this->SeleniumServerPort = $serverPort;
-               if ( isset( $serverExecPath ) )
+               }
+
+               if ( isset( $serverExecPath ) ) {
                        $this->SeleniumServerExecPath = $serverExecPath;
+               }
+
                return;
        }
 
@@ -66,7 +73,9 @@ class SeleniumServerManager {
        // to true, since after server is started, it is shut down by stop().
 
        public function setSeleniumStartServer( $startServer ) {
-               if ( $startServer == true ) $this->SeleniumStartServer = true;
+               if ( $startServer == true ) {
+                       $this->SeleniumStartServer = true;
+               }
        }
 
        // return values are: 1) started - server started, 2) failed -
@@ -75,7 +84,9 @@ class SeleniumServerManager {
 
        public function start() {
 
-               if ( !$this->SeleniumStartServer ) return 'failed';
+               if ( !$this->SeleniumStartServer ) {
+                       return 'failed';
+               }
 
                // commented out cases are untested
 
@@ -142,15 +153,15 @@ class SeleniumServerManager {
                $output = array();
                $user = $_ENV['USER'];
                // @todo FIXME: This should be a little more generalized :)
-               if (PHP_OS == 'Darwin') {
+               if ( PHP_OS == 'Darwin' ) {
                        // Mac OS X's ps barfs on the 'w' param, but doesn't need it.
                        $ps = "ps -U %s";
                } else {
                        // Good on Linux
                        $ps = "ps -U %s w";
                }
-               $psCommand = sprintf($ps, escapeshellarg($user));
-               exec($psCommand . " | grep -i selenium-server", $output);
+               $psCommand = sprintf( $ps, escapeshellarg( $user ) );
+               exec( $psCommand . " | grep -i selenium-server", $output );
 
                // Start server. If there is already a server running,
                // return running.
@@ -170,16 +181,16 @@ class SeleniumServerManager {
                                // The echo guarentees it is put into $op when
                                // the exec command is run.
 
-                               $commandSuffix = ' > /dev/null 2>&1'. ' & echo $!';
+                               $commandSuffix = ' > /dev/null 2>&1' . ' & echo $!';
                                $portText = ' -port ' . $this->SeleniumServerPort;
                                $command = "java -jar " .
-                                       escapeshellarg($this->SeleniumServerExecPath) .
+                                       escapeshellarg( $this->SeleniumServerExecPath ) .
                                        $portText . $commandSuffix;
-                               exec($command ,$op);
+                               exec( $command, $op );
                                $pid = (int)$op[0];
-                               if ( $pid != "" )
+                               if ( $pid != "" ) {
                                        $this->SeleniumServerPid = $pid;
-                               else {
+                               else {
                                        $this->SeleniumServerPid = 'NaN';
                                        // Server start failed.
                                        return 'failed';
@@ -192,27 +203,29 @@ class SeleniumServerManager {
                                for ( $cnt = 1;
                                          $cnt <= $this->SeleniumServerStartTimeout;
                                          $cnt++ ) {
-                                       $fp = fsockopen ( 'localhost',
+                                       $fp = fsockopen( 'localhost',
                                                $this->SeleniumServerPort,
                                                $errno, $errstr, 0 );
                                        if ( !$fp ) {
                                                sleep( 1 );
                                                continue;
-                                         // Server start succeeded.
+                                               // Server start succeeded.
                                        } else {
-                                               fclose ( $fp );
+                                               fclose( $fp );
                                                return 'started';
                                        }
                                }
                                wfRestoreWarnings();
                                echo ( "Starting Selenium server timed out.\n" );
                                return 'failed';
+                       } else {
+                               // server already running.
+                               return 'running';
                        }
-                       // server already running.
-                       else return 'running';
 
                }
-                               // No Server execution path defined.
+
+               // No Server execution path defined.
                return 'failed';
        }
 
@@ -224,11 +237,13 @@ class SeleniumServerManager {
        private function stopServerOnUnix() {
 
                if ( !empty( $this->SeleniumServerPid ) &&
-                        $this->SeleniumServerPid != 'NaN' ) {
+                       $this->SeleniumServerPid != 'NaN'
+               ) {
                        exec( "kill -9 " . $this->SeleniumServerPid );
                        return 'stopped';
+               } else {
+                       return 'failed';
                }
-               else return 'failed';
        }
 
        private function stopServerOnWindows() {
index 7976c16..5346b1b 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-include("SeleniumTestConstants.php");
+include( "SeleniumTestConstants.php" );
 
 class SeleniumTestCase extends PHPUnit_Framework_TestCase { // PHPUnit_Extensions_SeleniumTestCase
        protected $selenium;
@@ -35,93 +35,93 @@ class SeleniumTestCase extends PHPUnit_Framework_TestCase { // PHPUnit_Extension
         */
        function createTestPageIfMissing( $pageName = null ) {
                if ( $pageName == null ) {
-                       $pageName = SeleniumTestConstants::WIKI_INTERNAL_LINK;          
+                       $pageName = SeleniumTestConstants::WIKI_INTERNAL_LINK;
                }
-               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName  );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName );
                $this->click( SeleniumTestConstants::BUTTON_SEARCH );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                $this->click( SeleniumTestConstants::LINK_START . $pageName );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-               $location =  $this->getLocation() . "\n";
-               if ( strpos( $location, '&redlink=1') !== false  ) {
-                       $this->type( SeleniumTestConstants::TEXT_EDITOR,  "Test fixture page. No real content here" );
+               $location = $this->getLocation() . "\n";
+               if ( strpos( $location, '&redlink=1' ) !== false ) {
+                       $this->type( SeleniumTestConstants::TEXT_EDITOR, "Test fixture page. No real content here" );
                        $this->click( SeleniumTestConstants::BUTTON_SAVE );
                        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                        $this->assertTrue( $this->isTextPresent( $pageName ),
-                       $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
+                               $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
                }
        }
-       
+
        /**
         * Create a test page using date as part of the name so that it is unique
         * @param $pagePrefix The prefix to use for the page name. The current date will be appended to this to make it unique
         * @param $watchThis Whether to add the page to my watchlist. Defaults to false.
         */
        function createNewTestPage( $pagePrefix, $watchThis = false ) {
-               $pageName = $pagePrefix . date("Ymd-His");
-               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName  );
+               $pageName = $pagePrefix . date( "Ymd-His" );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName );
                $this->click( SeleniumTestConstants::BUTTON_SEARCH );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                $this->click( SeleniumTestConstants::LINK_START . $pageName );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-               $location =  $this->getLocation() . "\n";
-               $this->assertContains( '&redlink=1', $location ).
-               $this->type( SeleniumTestConstants::TEXT_EDITOR,  "Test fixture page. No real content here" );
+               $location = $this->getLocation() . "\n";
+               $this->assertContains( '&redlink=1', $location ) .
+                       $this->type( SeleniumTestConstants::TEXT_EDITOR, "Test fixture page. No real content here" );
                if ( $watchThis ) {
                        $this->click( "wpWatchthis" );
                }
                $this->click( SeleniumTestConstants::BUTTON_SAVE );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                $this->assertTrue( $this->isTextPresent( $pageName ),
-               $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
+                       $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
                return $pageName;
        }
 
-       public function getExistingPage(){
+       public function getExistingPage() {
                $this->open( $this->getUrl() .
                        '/index.php?title=Main_Page&action=edit' );
-               $this->type("searchInput", "new" );
-               $this->click("searchGoButton");
-               $this->waitForPageToLoad("30000");
+               $this->type( "searchInput", "new" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( "30000" );
        }
 
-       public function getNewPage($pageName){
+       public function getNewPage( $pageName ) {
 
                $this->open( $this->getUrl() .
                        '/index.php?title=Main_Page&action=edit' );
-               $this->type("searchInput", $pageName );
-               $this->click("searchGoButton");
-               $this->waitForPageToLoad("30000");
-               $this->click("link=".$pageName);
-               $this->waitForPageToLoad("600000");
+               $this->type( "searchInput", $pageName );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( "30000" );
+               $this->click( "link=" . $pageName );
+               $this->waitForPageToLoad( "600000" );
 
 
        }
+
        // Loading the mediawiki editor
-       public function loadWikiEditor(){
+       public function loadWikiEditor() {
                $this->open( $this->getUrl() .
                        '/index.php?title=Main_Page&action=edit' );
        }
 
        // Clear the content of the mediawiki editor
-       public function clearWikiEditor(){
-               $this->type("wpTextbox1", "");
+       public function clearWikiEditor() {
+               $this->type( "wpTextbox1", "" );
        }
 
        // Click on the 'Show preview' button of the mediawiki editor
-       public function clickShowPreviewBtn(){
-               $this->click("wpPreview");
+       public function clickShowPreviewBtn() {
+               $this->click( "wpPreview" );
        }
 
        // Click on the 'Save Page' button of the mediawiki editor
-       public function clickSavePageBtn(){
-               $this->click("wpSave");
+       public function clickSavePageBtn() {
+               $this->click( "wpSave" );
        }
 
        // Click on the 'Edit' link
-       public function clickEditLink(){
-               $this->click("link=Edit");
-               $this->waitForPageToLoad("30000");
+       public function clickEditLink() {
+               $this->click( "link=Edit" );
+               $this->waitForPageToLoad( "30000" );
        }
-
 }
index 9436f67..dc0ac66 100644 (file)
@@ -14,20 +14,17 @@ class SeleniumTestListener implements PHPUnit_Framework_TestListener {
                $this->tests_failed++;
        }
 
-       public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time )
-       {
+       public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time ) {
                $this->logger->write( 'Failed: ' . $e->getMessage() );
                $this->tests_failed++;
        }
 
-       public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time )
-       {
+       public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
                $this->logger->write( 'Incomplete.' );
                $this->tests_failed++;
        }
 
-       public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time )
-       {
+       public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
                $this->logger->write( 'Skipped.' );
                $this->tests_failed++;
        }
@@ -53,7 +50,7 @@ class SeleniumTestListener implements PHPUnit_Framework_TestListener {
        }
 
        public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) {
-               $this->logger->write('Testsuite ' . $suite->getName() . ' ended.' );
+               $this->logger->write( 'Testsuite ' . $suite->getName() . ' ended.' );
                if ( $this->tests_ok > 0 || $this->tests_failed > 0 ) {
                        $this->logger->write( ' OK: ' . $this->tests_ok . ' Failed: ' . $this->tests_failed );
                }
index 81a630f..8c21f21 100644 (file)
@@ -11,7 +11,7 @@ abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
        const RESULT_OK = 2;
        const RESULT_ERROR = 3;
 
-       public abstract function addTests();
+       abstract public function addTests();
 
        public function setUp() {
                // Hack because because PHPUnit version 3.0.6 which is on prototype does not
@@ -25,7 +25,7 @@ abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
                if ( $this->triggerClientTestResources ) {
                        $this->selenium->open( $this->selenium->getUrl() . '/index.php?setupTestSuite=' . $this->getName() );
                        //wait a little longer for the db operation
-                       $this->selenium->waitForPageToLoad( 6000  );
+                       $this->selenium->waitForPageToLoad( 6000 );
                }
                if ( $this->loginBeforeTests ) {
                        $this->login();
@@ -50,7 +50,7 @@ abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
        protected function setLoginBeforeTests( $loginBeforeTests = true ) {
                $this->loginBeforeTests = $loginBeforeTests;
        }
-       
+
        protected function setTriggerClientTestResources( $triggerClientTestResources = true ) {
                $this->triggerClientTestResources = $triggerClientTestResources;
        }
index d688c3b..99ae477 100644 (file)
@@ -633,7 +633,7 @@ CREATE TABLE `mw_msg_resource` (
 
 LOCK TABLES `mw_msg_resource` WRITE;
 /*!40000 ALTER TABLE `mw_msg_resource` DISABLE KEYS */;
-INSERT INTO `mw_msg_resource` VALUES ('ext.vector.collapsibleNav','en','{\"vector-collapsiblenav-more\":\"More languages\"}','20110108005000'),('ext.vector.collapsibleTabs','en','{}','20110108005000'),('ext.vector.simpleSearch','en','{\"vector-simplesearch-search\":\"Search\",\"vector-simplesearch-containing\":\"containing...\"}','20110108005000'),('ext.wikiEditor','en','{}','20110110172914'),('ext.wikiEditor.toolbar','en','{\"wikieditor-toolbar-loading\":\"Loading...\",\"wikieditor-toolbar-tool-bold\":\"Bold\",\"wikieditor-toolbar-tool-bold-example\":\"Bold text\",\"wikieditor-toolbar-tool-italic\":\"Italic\",\"wikieditor-toolbar-tool-italic-example\":\"Italic text\",\"wikieditor-toolbar-tool-ilink\":\"Internal link\",\"wikieditor-toolbar-tool-ilink-example\":\"Link title\",\"wikieditor-toolbar-tool-xlink\":\"External link (remember http:\\/\\/ prefix)\",\"wikieditor-toolbar-tool-xlink-example\":\"http:\\/\\/www.example.com link title\",\"wikieditor-toolbar-tool-link\":\"Link\",\"wikieditor-toolbar-tool-link-title\":\"Insert link\",\"wikieditor-toolbar-tool-link-int\":\"To a wiki page\",\"wikieditor-toolbar-tool-link-int-target\":\"Target page or URL:\",\"wikieditor-toolbar-tool-link-int-target-tooltip\":\"Page title or URL\",\"wikieditor-toolbar-tool-link-int-text\":\"Text to display:\",\"wikieditor-toolbar-tool-link-int-text-tooltip\":\"Text to be displayed\",\"wikieditor-toolbar-tool-link-ext\":\"To an external web page\",\"wikieditor-toolbar-tool-link-ext-target\":\"Link URL:\",\"wikieditor-toolbar-tool-link-ext-text\":\"Link text:\",\"wikieditor-toolbar-tool-link-insert\":\"Insert link\",\"wikieditor-toolbar-tool-link-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-link-int-target-status-exists\":\"Page exists\",\"wikieditor-toolbar-tool-link-int-target-status-notexists\":\"Page does not exist\",\"wikieditor-toolbar-tool-link-int-target-status-invalid\":\"Invalid title\",\"wikieditor-toolbar-tool-link-int-target-status-external\":\"External link\",\"wikieditor-toolbar-tool-link-int-target-status-loading\":\"Checking page existence...\",\"wikieditor-toolbar-tool-link-int-invalid\":\"The title you specified is invalid.\",\"wikieditor-toolbar-tool-link-lookslikeinternal\":\"The URL you specified looks like it was intended as a link to another wiki page.\\nDo you want to make it an internal link?\",\"wikieditor-toolbar-tool-link-lookslikeinternal-int\":\"Internal link\",\"wikieditor-toolbar-tool-link-lookslikeinternal-ext\":\"External link\",\"wikieditor-toolbar-tool-link-empty\":\"You did not enter anything to link to.\",\"wikieditor-toolbar-tool-file\":\"Embedded file\",\"wikieditor-toolbar-tool-file-pre\":\"$1{{ns:file}}:\",\"wikieditor-toolbar-tool-file-example\":\"Example.jpg\",\"wikieditor-toolbar-tool-reference\":\"Reference\",\"wikieditor-toolbar-tool-reference-title\":\"Insert reference\",\"wikieditor-toolbar-tool-reference-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-reference-text\":\"Reference text\",\"wikieditor-toolbar-tool-reference-insert\":\"Insert\",\"wikieditor-toolbar-tool-reference-example\":\"Insert footnote text here\",\"wikieditor-toolbar-tool-signature\":\"Signature and timestamp\",\"wikieditor-toolbar-section-advanced\":\"Advanced\",\"wikieditor-toolbar-tool-heading\":\"Heading\",\"wikieditor-toolbar-tool-heading-1\":\"Level 1\",\"wikieditor-toolbar-tool-heading-2\":\"Level 2\",\"wikieditor-toolbar-tool-heading-3\":\"Level 3\",\"wikieditor-toolbar-tool-heading-4\":\"Level 4\",\"wikieditor-toolbar-tool-heading-5\":\"Level 5\",\"wikieditor-toolbar-tool-heading-example\":\"Heading text\",\"wikieditor-toolbar-group-format\":\"Format\",\"wikieditor-toolbar-tool-ulist\":\"Bulleted list\",\"wikieditor-toolbar-tool-ulist-example\":\"Bulleted list item\",\"wikieditor-toolbar-tool-olist\":\"Numbered list\",\"wikieditor-toolbar-tool-olist-example\":\"Numbered list item\",\"wikieditor-toolbar-tool-indent\":\"Indentation\",\"wikieditor-toolbar-tool-indent-example\":\"Indented line\",\"wikieditor-toolbar-tool-nowiki\":\"No wiki formatting\",\"wikieditor-toolbar-tool-nowiki-example\":\"Insert non-formatted text here\",\"wikieditor-toolbar-tool-redirect\":\"Redirect\",\"wikieditor-toolbar-tool-redirect-example\":\"Target page name\",\"wikieditor-toolbar-tool-big\":\"Big\",\"wikieditor-toolbar-tool-big-example\":\"Big text\",\"wikieditor-toolbar-tool-small\":\"Small\",\"wikieditor-toolbar-tool-small-example\":\"Small text\",\"wikieditor-toolbar-tool-superscript\":\"Superscript\",\"wikieditor-toolbar-tool-superscript-example\":\"Superscript text\",\"wikieditor-toolbar-tool-subscript\":\"Subscript\",\"wikieditor-toolbar-tool-subscript-example\":\"Subscript text\",\"wikieditor-toolbar-group-insert\":\"Insert\",\"wikieditor-toolbar-tool-gallery\":\"Picture gallery\",\"wikieditor-toolbar-tool-gallery-example\":\"{{ns:file}}:Example.jpg|Caption1\\n{{ns:file}}:Example.jpg|Caption2\",\"wikieditor-toolbar-tool-newline\":\"New line\",\"wikieditor-toolbar-tool-table\":\"Table\",\"wikieditor-toolbar-tool-table-example-old\":\"-\\n! header 1\\n! header 2\\n! header 3\\n|-\\n| row 1, cell 1\\n| row 1, cell 2\\n| row 1, cell 3\\n|-\\n| row 2, cell 1\\n| row 2, cell 2\\n| row 2, cell 3\",\"wikieditor-toolbar-tool-table-example-cell-text\":\"Cell text\",\"wikieditor-toolbar-tool-table-example\":\"Example\",\"wikieditor-toolbar-tool-table-example-header\":\"Header text\",\"wikieditor-toolbar-tool-table-title\":\"Insert table\",\"wikieditor-toolbar-tool-table-dimensions-rows\":\"Rows\",\"wikieditor-toolbar-tool-table-dimensions-columns\":\"Columns\",\"wikieditor-toolbar-tool-table-dimensions-header\":\"Add header row\",\"wikieditor-toolbar-tool-table-wikitable\":\"Style with borders\",\"wikieditor-toolbar-tool-table-sortable\":\"Make table sortable\",\"wikieditor-toolbar-tool-table-insert\":\"Insert\",\"wikieditor-toolbar-tool-table-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-table-example-text\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut nec purus diam. Sed aliquam imperdiet nunc quis lacinia. Donec rutrum consectetur placerat. Sed volutpat neque non purus faucibus id ultricies enim euismod.\",\"wikieditor-toolbar-tool-table-toomany\":\"Inserting a table with more than $1 cells is not possible with this dialog.\",\"wikieditor-toolbar-tool-table-invalidnumber\":\"You have not entered a valid number of rows or columns.\",\"wikieditor-toolbar-tool-table-zero\":\"You cannot insert a table with zero rows or columns.\",\"wikieditor-toolbar-tool-replace\":\"Search and replace\",\"wikieditor-toolbar-tool-replace-title\":\"Search and replace\",\"wikieditor-toolbar-tool-replace-search\":\"Search for:\",\"wikieditor-toolbar-tool-replace-replace\":\"Replace with:\",\"wikieditor-toolbar-tool-replace-case\":\"Match case\",\"wikieditor-toolbar-tool-replace-regex\":\"Treat search string as a regular expression\",\"wikieditor-toolbar-tool-replace-button-findnext\":\"Find next\",\"wikieditor-toolbar-tool-replace-button-replacenext\":\"Replace next\",\"wikieditor-toolbar-tool-replace-button-replaceall\":\"Replace all\",\"wikieditor-toolbar-tool-replace-close\":\"Close\",\"wikieditor-toolbar-tool-replace-nomatch\":\"Your search did not match anything.\",\"wikieditor-toolbar-tool-replace-success\":\"$1 replacement(s) made.\",\"wikieditor-toolbar-tool-replace-emptysearch\":\"You did not enter anything to search for.\",\"wikieditor-toolbar-tool-replace-invalidregex\":\"The regular expression you entered is invalid: $1\",\"wikieditor-toolbar-section-characters\":\"Special characters\",\"wikieditor-toolbar-characters-page-latin\":\"Latin\",\"wikieditor-toolbar-characters-page-latinextended\":\"Latin extended\",\"wikieditor-toolbar-characters-page-ipa\":\"IPA\",\"wikieditor-toolbar-characters-page-symbols\":\"Symbols\",\"wikieditor-toolbar-characters-page-greek\":\"Greek\",\"wikieditor-toolbar-characters-page-cyrillic\":\"Cyrillic\",\"wikieditor-toolbar-characters-page-arabic\":\"Arabic\",\"wikieditor-toolbar-characters-page-persian\":\"Persian\",\"wikieditor-toolbar-characters-page-hebrew\":\"Hebrew\",\"wikieditor-toolbar-characters-page-bangla\":\"Bangla\",\"wikieditor-toolbar-characters-page-telugu\":\"Telugu\",\"wikieditor-toolbar-characters-page-sinhala\":\"Sinhala\",\"wikieditor-toolbar-characters-page-gujarati\":\"Gujarati\",\"wikieditor-toolbar-characters-page-thai\":\"Thai\",\"wikieditor-toolbar-characters-page-lao\":\"Lao\",\"wikieditor-toolbar-characters-page-khmer\":\"Khmer\",\"wikieditor-toolbar-section-help\":\"Help\",\"wikieditor-toolbar-help-heading-description\":\"Description\",\"wikieditor-toolbar-help-heading-syntax\":\"What you type\",\"wikieditor-toolbar-help-heading-result\":\"What you get\",\"wikieditor-toolbar-help-page-format\":\"Formatting\",\"wikieditor-toolbar-help-page-link\":\"Links\",\"wikieditor-toolbar-help-page-heading\":\"Headings\",\"wikieditor-toolbar-help-page-list\":\"Lists\",\"wikieditor-toolbar-help-page-file\":\"Files\",\"wikieditor-toolbar-help-page-reference\":\"References\",\"wikieditor-toolbar-help-page-discussion\":\"Discussion\",\"wikieditor-toolbar-help-content-bold-description\":\"Bold\",\"wikieditor-toolbar-help-content-bold-syntax\":\"\'\'\'Bold text\'\'\'\",\"wikieditor-toolbar-help-content-bold-result\":\"<strong>Bold text<\\/strong>\",\"wikieditor-toolbar-help-content-italic-description\":\"Italic\",\"wikieditor-toolbar-help-content-italic-syntax\":\"\'\'Italic text\'\'\",\"wikieditor-toolbar-help-content-italic-result\":\"<em>Italic text<\\/em>\",\"wikieditor-toolbar-help-content-bolditalic-description\":\"Bold &amp; italic\",\"wikieditor-toolbar-help-content-bolditalic-syntax\":\"\'\'\'\'\'Bold &amp; italic text\'\'\'\'\'\",\"wikieditor-toolbar-help-content-bolditalic-result\":\"<strong><em>Bold &amp; italic text<\\/em><\\/strong>\",\"wikieditor-toolbar-help-content-ilink-description\":\"Internal link\",\"wikieditor-toolbar-help-content-ilink-syntax\":\"[[Page title|Link label]]<br \\/>[[Page title]]\",\"wikieditor-toolbar-help-content-ilink-result\":\"<a href=\'#\'>Link label<\\/a><br \\/><a href=\'#\'>Page title<\\/a>\",\"wikieditor-toolbar-help-content-xlink-description\":\"External link\",\"wikieditor-toolbar-help-content-xlink-syntax\":\"[http:\\/\\/www.example.org Link label]<br \\/>[http:\\/\\/www.example.org]<br \\/>http:\\/\\/www.example.org\",\"wikieditor-toolbar-help-content-xlink-result\":\"<a href=\'#\' class=\'external\'>Link label<\\/a><br \\/><a href=\'#\' class=\'external autonumber\'>[1]<\\/a><br \\/><a href=\'#\' class=\'external\'>http:\\/\\/www.example.org<\\/a>\",\"wikieditor-toolbar-help-content-heading1-description\":\"&lt;wikieditor-toolbar-help-content-heading1-description&gt;\",\"wikieditor-toolbar-help-content-heading1-syntax\":\"&lt;wikieditor-toolbar-help-content-heading1-syntax&gt;\",\"wikieditor-toolbar-help-content-heading1-result\":\"&lt;wikieditor-toolbar-help-content-heading1-result&gt;\",\"wikieditor-toolbar-help-content-heading2-description\":\"2nd level heading\",\"wikieditor-toolbar-help-content-heading2-syntax\":\"== Heading text ==\",\"wikieditor-toolbar-help-content-heading2-result\":\"<h2>Heading text<\\/h2>\",\"wikieditor-toolbar-help-content-heading3-description\":\"3rd level heading\",\"wikieditor-toolbar-help-content-heading3-syntax\":\"=== Heading text ===\",\"wikieditor-toolbar-help-content-heading3-result\":\"<h3>Heading text<\\/h3>\",\"wikieditor-toolbar-help-content-heading4-description\":\"4th level heading\",\"wikieditor-toolbar-help-content-heading4-syntax\":\"==== Heading text ====\",\"wikieditor-toolbar-help-content-heading4-result\":\"<h4>Heading text<\\/h4>\",\"wikieditor-toolbar-help-content-heading5-description\":\"5th level heading\",\"wikieditor-toolbar-help-content-heading5-syntax\":\"===== Heading text =====\",\"wikieditor-toolbar-help-content-heading5-result\":\"<h5>Heading text<\\/h5>\",\"wikieditor-toolbar-help-content-ulist-description\":\"Bulleted list\",\"wikieditor-toolbar-help-content-ulist-syntax\":\"* List item<br \\/>* List item\",\"wikieditor-toolbar-help-content-ulist-result\":\"<ul><li>List item<\\/li><li>List item<\\/li><\\/ul>\",\"wikieditor-toolbar-help-content-olist-description\":\"Numbered list\",\"wikieditor-toolbar-help-content-olist-syntax\":\"# List item<br \\/># List item\",\"wikieditor-toolbar-help-content-olist-result\":\"<ol><li>List item<\\/li><li>List item<\\/li><\\/ol>\",\"wikieditor-toolbar-help-content-file-description\":\"Embedded file\",\"wikieditor-toolbar-help-content-file-syntax\":\"[[{{ns:file}}:Example.png|thumb|Caption text]]\",\"wikieditor-toolbar-help-content-file-result\":\"<div style=\'width:104px;\' class=\'thumbinner\'><a title=\'Caption text\' class=\'image\' href=\'#\'><img height=\'50\' width=\'100\' border=\'0\' class=\'thumbimage\' src=\'extensions\\/UsabilityInitiative\\/images\\/wikiEditor\\/toolbar\\/example-image.png\' alt=\'\'\\/><\\/a><div class=\'thumbcaption\'><div class=\'magnify\'><a title=\'Enlarge\' class=\'internal\' href=\'#\'><img height=\'11\' width=\'15\' alt=\'\' src=\'$1\\/common\\/images\\/magnify-clip.png\'\\/><\\/a><\\/div>Caption text<\\/div><\\/div>\",\"wikieditor-toolbar-help-content-reference-description\":\"Reference\",\"wikieditor-toolbar-help-content-reference-syntax\":\"Page text.&lt;ref name=\\\"test\\\"&gt;[http:\\/\\/www.example.org Link text], additional text.&lt;\\/ref&gt;\",\"wikieditor-toolbar-help-content-reference-result\":\"Page text.<sup><a href=\'#\'>[1]<\\/a><\\/sup>\",\"wikieditor-toolbar-help-content-rereference-description\":\"Additional use of same reference\",\"wikieditor-toolbar-help-content-rereference-syntax\":\"&lt;ref name=\\\"test\\\" \\/&gt;\",\"wikieditor-toolbar-help-content-rereference-result\":\"Page text.<sup><a href=\'#\'>[1]<\\/a><\\/sup>\",\"wikieditor-toolbar-help-content-showreferences-description\":\"Display references\",\"wikieditor-toolbar-help-content-showreferences-syntax\":\"&lt;references \\/&gt;\",\"wikieditor-toolbar-help-content-showreferences-result\":\"<ol class=\'references\'><li id=\'cite_note-test-0\'><b><a title=\'\' href=\'#\'>^<\\/a><\\/b> <a rel=\'nofollow\' title=\'http:\\/\\/www.example.org\' class=\'external text\' href=\'#\'>Link text<\\/a>, additional text.<\\/li><\\/ol>\",\"wikieditor-toolbar-help-content-signaturetimestamp-description\":\"Signature with timestamp\",\"wikieditor-toolbar-help-content-signaturetimestamp-syntax\":\"~~~~\",\"wikieditor-toolbar-help-content-signaturetimestamp-result\":\"<a href=\'#\' title=\'{{#special:mypage}}\'>Username<\\/a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk<\\/a>) 15:54, 10 June 2009 (UTC)\",\"wikieditor-toolbar-help-content-signature-description\":\"Signature\",\"wikieditor-toolbar-help-content-signature-syntax\":\"~~~\",\"wikieditor-toolbar-help-content-signature-result\":\"<a href=\'#\' title=\'{{#special:mypage}}\'>Username<\\/a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk<\\/a>)\",\"wikieditor-toolbar-help-content-indent-description\":\"Indent\",\"wikieditor-toolbar-help-content-indent-syntax\":\"Normal text<br \\/>:Indented text<br \\/>::Indented text\",\"wikieditor-toolbar-help-content-indent-result\":\"Normal text<dl><dd>Indented text<dl><dd>Indented text<\\/dd><\\/dl><\\/dd><\\/dl>\"}','20110110172914'),('jquery.async','en','{}','20110110172915'),('jquery.autoEllipsis','en','{}','20110110172915'),('jquery.checkboxShiftClick','en','{}','20110110172915'),('jquery.client','en','{}','20110110172915'),('jquery.collapsibleTabs','en','{}','20110110172915'),('jquery.cookie','en','{}','20110110172915'),('jquery.delayedBind','en','{}','20110110172915'),('jquery.highlightText','en','{}','20110110172915'),('jquery.makeCollapsible','en','{\"collapsible-expand\":\"Expand\",\"collapsible-collapse\":\"Collapse\"}','20110110172915'),('jquery.placeholder','en','{}','20110110172915'),('jquery.suggestions','en','{}','20110110172915'),('jquery.tabIndex','en','{}','20110110172915'),('jquery.textSelection','en','{}','20110110172915'),('jquery.wikiEditor','en','{\"wikieditor-wikitext-tab\":\"Wikitext\",\"wikieditor-loading\":\"Loading\"}','20110110172914'),('jquery.wikiEditor.toolbar','en','{}','20110110172914'),('mediawiki.action.watch.ajax','en','{}','20110110172915'),('mediawiki.language','en','{}','20110110172915'),('mediawiki.legacy.ajax','en','{\"watch\":\"Watch\",\"unwatch\":\"Unwatch\",\"watching\":\"Watching...\",\"unwatching\":\"Unwatching...\",\"tooltip-ca-watch\":\"Add this page to your watchlist\",\"tooltip-ca-unwatch\":\"Remove this page from your watchlist\"}','20110110172915'),('mediawiki.legacy.edit','en','{}','20110110172915'),('mediawiki.legacy.wikibits','en','{\"showtoc\":\"show\",\"hidetoc\":\"hide\"}','20110110172915'),('mediawiki.util','en','{}','20110110172915');
+INSERT INTO `mw_msg_resource` VALUES ('ext.vector.collapsibleNav','en','{\"vector-collapsiblenav-more\":\"More languages\"}','20110108005000'),('ext.vector.collapsibleTabs','en','{}','20110108005000'),('ext.vector.simpleSearch','en','{\"vector-simplesearch-search\":\"Search\",\"vector-simplesearch-containing\":\"containing...\"}','20110108005000'),('ext.wikiEditor','en','{}','20110110172914'),('ext.wikiEditor.toolbar','en','{\"wikieditor-toolbar-loading\":\"Loading...\",\"wikieditor-toolbar-tool-bold\":\"Bold\",\"wikieditor-toolbar-tool-bold-example\":\"Bold text\",\"wikieditor-toolbar-tool-italic\":\"Italic\",\"wikieditor-toolbar-tool-italic-example\":\"Italic text\",\"wikieditor-toolbar-tool-ilink\":\"Internal link\",\"wikieditor-toolbar-tool-ilink-example\":\"Link title\",\"wikieditor-toolbar-tool-xlink\":\"External link (remember http:\\/\\/ prefix)\",\"wikieditor-toolbar-tool-xlink-example\":\"http:\\/\\/www.example.com link title\",\"wikieditor-toolbar-tool-link\":\"Link\",\"wikieditor-toolbar-tool-link-title\":\"Insert link\",\"wikieditor-toolbar-tool-link-int\":\"To a wiki page\",\"wikieditor-toolbar-tool-link-int-target\":\"Target page or URL:\",\"wikieditor-toolbar-tool-link-int-target-tooltip\":\"Page title or URL\",\"wikieditor-toolbar-tool-link-int-text\":\"Text to display:\",\"wikieditor-toolbar-tool-link-int-text-tooltip\":\"Text to be displayed\",\"wikieditor-toolbar-tool-link-ext\":\"To an external web page\",\"wikieditor-toolbar-tool-link-ext-target\":\"Link URL:\",\"wikieditor-toolbar-tool-link-ext-text\":\"Link text:\",\"wikieditor-toolbar-tool-link-insert\":\"Insert link\",\"wikieditor-toolbar-tool-link-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-link-int-target-status-exists\":\"Page exists\",\"wikieditor-toolbar-tool-link-int-target-status-notexists\":\"Page does not exist\",\"wikieditor-toolbar-tool-link-int-target-status-invalid\":\"Invalid title\",\"wikieditor-toolbar-tool-link-int-target-status-external\":\"External link\",\"wikieditor-toolbar-tool-link-int-target-status-loading\":\"Checking page existence...\",\"wikieditor-toolbar-tool-link-int-invalid\":\"The title you specified is invalid.\",\"wikieditor-toolbar-tool-link-lookslikeinternal\":\"The URL you specified looks like it was intended as a link to another wiki page.\\nDo you want to make it an internal link?\",\"wikieditor-toolbar-tool-link-lookslikeinternal-int\":\"Internal link\",\"wikieditor-toolbar-tool-link-lookslikeinternal-ext\":\"External link\",\"wikieditor-toolbar-tool-link-empty\":\"You did not enter anything to link to.\",\"wikieditor-toolbar-tool-file\":\"Embedded file\",\"wikieditor-toolbar-tool-file-pre\":\"$1{{ns:file}}:\",\"wikieditor-toolbar-tool-file-example\":\"Example.jpg\",\"wikieditor-toolbar-tool-reference\":\"Reference\",\"wikieditor-toolbar-tool-reference-title\":\"Insert reference\",\"wikieditor-toolbar-tool-reference-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-reference-text\":\"Reference text\",\"wikieditor-toolbar-tool-reference-insert\":\"Insert\",\"wikieditor-toolbar-tool-reference-example\":\"Insert footnote text here\",\"wikieditor-toolbar-tool-signature\":\"Signature and timestamp\",\"wikieditor-toolbar-section-advanced\":\"Advanced\",\"wikieditor-toolbar-tool-heading\":\"Heading\",\"wikieditor-toolbar-tool-heading-1\":\"Level 1\",\"wikieditor-toolbar-tool-heading-2\":\"Level 2\",\"wikieditor-toolbar-tool-heading-3\":\"Level 3\",\"wikieditor-toolbar-tool-heading-4\":\"Level 4\",\"wikieditor-toolbar-tool-heading-5\":\"Level 5\",\"wikieditor-toolbar-tool-heading-example\":\"Heading text\",\"wikieditor-toolbar-group-format\":\"Format\",\"wikieditor-toolbar-tool-ulist\":\"Bulleted list\",\"wikieditor-toolbar-tool-ulist-example\":\"Bulleted list item\",\"wikieditor-toolbar-tool-olist\":\"Numbered list\",\"wikieditor-toolbar-tool-olist-example\":\"Numbered list item\",\"wikieditor-toolbar-tool-indent\":\"Indentation\",\"wikieditor-toolbar-tool-indent-example\":\"Indented line\",\"wikieditor-toolbar-tool-nowiki\":\"No wiki formatting\",\"wikieditor-toolbar-tool-nowiki-example\":\"Insert non-formatted text here\",\"wikieditor-toolbar-tool-redirect\":\"Redirect\",\"wikieditor-toolbar-tool-redirect-example\":\"Target page name\",\"wikieditor-toolbar-tool-big\":\"Big\",\"wikieditor-toolbar-tool-big-example\":\"Big text\",\"wikieditor-toolbar-tool-small\":\"Small\",\"wikieditor-toolbar-tool-small-example\":\"Small text\",\"wikieditor-toolbar-tool-superscript\":\"Superscript\",\"wikieditor-toolbar-tool-superscript-example\":\"Superscript text\",\"wikieditor-toolbar-tool-subscript\":\"Subscript\",\"wikieditor-toolbar-tool-subscript-example\":\"Subscript text\",\"wikieditor-toolbar-group-insert\":\"Insert\",\"wikieditor-toolbar-tool-gallery\":\"Picture gallery\",\"wikieditor-toolbar-tool-gallery-example\":\"{{ns:file}}:Example.jpg|Caption1\\n{{ns:file}}:Example.jpg|Caption2\",\"wikieditor-toolbar-tool-newline\":\"New line\",\"wikieditor-toolbar-tool-table\":\"Table\",\"wikieditor-toolbar-tool-table-example-old\":\"-\\n! header 1\\n! header 2\\n! header 3\\n|-\\n| row 1, cell 1\\n| row 1, cell 2\\n| row 1, cell 3\\n|-\\n| row 2, cell 1\\n| row 2, cell 2\\n| row 2, cell 3\",\"wikieditor-toolbar-tool-table-example-cell-text\":\"Cell text\",\"wikieditor-toolbar-tool-table-example\":\"Example\",\"wikieditor-toolbar-tool-table-example-header\":\"Header text\",\"wikieditor-toolbar-tool-table-title\":\"Insert table\",\"wikieditor-toolbar-tool-table-dimensions-rows\":\"Rows\",\"wikieditor-toolbar-tool-table-dimensions-columns\":\"Columns\",\"wikieditor-toolbar-tool-table-dimensions-header\":\"Add header row\",\"wikieditor-toolbar-tool-table-wikitable\":\"Style with borders\",\"wikieditor-toolbar-tool-table-sortable\":\"Make table sortable\",\"wikieditor-toolbar-tool-table-insert\":\"Insert\",\"wikieditor-toolbar-tool-table-cancel\":\"Cancel\",\"wikieditor-toolbar-tool-table-example-text\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut nec purus diam. Sed aliquam imperdiet nunc quis lacinia. Donec rutrum consectetur placerat. Sed volutpat neque non purus faucibus id ultricies enim euismod.\",\"wikieditor-toolbar-tool-table-toomany\":\"Inserting a table with more than $1 cells is not possible with this dialog.\",\"wikieditor-toolbar-tool-table-invalidnumber\":\"You have not entered a valid number of rows or columns.\",\"wikieditor-toolbar-tool-table-zero\":\"You cannot insert a table with zero rows or columns.\",\"wikieditor-toolbar-tool-replace\":\"Search and replace\",\"wikieditor-toolbar-tool-replace-title\":\"Search and replace\",\"wikieditor-toolbar-tool-replace-search\":\"Search for:\",\"wikieditor-toolbar-tool-replace-replace\":\"Replace with:\",\"wikieditor-toolbar-tool-replace-case\":\"Match case\",\"wikieditor-toolbar-tool-replace-regex\":\"Treat search string as a regular expression\",\"wikieditor-toolbar-tool-replace-button-findnext\":\"Find next\",\"wikieditor-toolbar-tool-replace-button-replacenext\":\"Replace next\",\"wikieditor-toolbar-tool-replace-button-replaceall\":\"Replace all\",\"wikieditor-toolbar-tool-replace-close\":\"Close\",\"wikieditor-toolbar-tool-replace-nomatch\":\"Your search did not match anything.\",\"wikieditor-toolbar-tool-replace-success\":\"$1 replacement(s) made.\",\"wikieditor-toolbar-tool-replace-emptysearch\":\"You did not enter anything to search for.\",\"wikieditor-toolbar-tool-replace-invalidregex\":\"The regular expression you entered is invalid: $1\",\"wikieditor-toolbar-section-characters\":\"Special characters\",\"wikieditor-toolbar-characters-page-latin\":\"Latin\",\"wikieditor-toolbar-characters-page-latinextended\":\"Latin extended\",\"wikieditor-toolbar-characters-page-ipa\":\"IPA\",\"wikieditor-toolbar-characters-page-symbols\":\"Symbols\",\"wikieditor-toolbar-characters-page-greek\":\"Greek\",\"wikieditor-toolbar-characters-page-cyrillic\":\"Cyrillic\",\"wikieditor-toolbar-characters-page-arabic\":\"Arabic\",\"wikieditor-toolbar-characters-page-persian\":\"Persian\",\"wikieditor-toolbar-characters-page-hebrew\":\"Hebrew\",\"wikieditor-toolbar-characters-page-bangla\":\"Bangla\",\"wikieditor-toolbar-characters-page-telugu\":\"Telugu\",\"wikieditor-toolbar-characters-page-sinhala\":\"Sinhala\",\"wikieditor-toolbar-characters-page-gujarati\":\"Gujarati\",\"wikieditor-toolbar-characters-page-thai\":\"Thai\",\"wikieditor-toolbar-characters-page-lao\":\"Lao\",\"wikieditor-toolbar-characters-page-khmer\":\"Khmer\",\"wikieditor-toolbar-section-help\":\"Help\",\"wikieditor-toolbar-help-heading-description\":\"Description\",\"wikieditor-toolbar-help-heading-syntax\":\"What you type\",\"wikieditor-toolbar-help-heading-result\":\"What you get\",\"wikieditor-toolbar-help-page-format\":\"Formatting\",\"wikieditor-toolbar-help-page-link\":\"Links\",\"wikieditor-toolbar-help-page-heading\":\"Headings\",\"wikieditor-toolbar-help-page-list\":\"Lists\",\"wikieditor-toolbar-help-page-file\":\"Files\",\"wikieditor-toolbar-help-page-reference\":\"References\",\"wikieditor-toolbar-help-page-discussion\":\"Discussion\",\"wikieditor-toolbar-help-content-bold-description\":\"Bold\",\"wikieditor-toolbar-help-content-bold-syntax\":\"\'\'\'Bold text\'\'\'\",\"wikieditor-toolbar-help-content-bold-result\":\"<strong>Bold text<\\/strong>\",\"wikieditor-toolbar-help-content-italic-description\":\"Italic\",\"wikieditor-toolbar-help-content-italic-syntax\":\"\'\'Italic text\'\'\",\"wikieditor-toolbar-help-content-italic-result\":\"<em>Italic text<\\/em>\",\"wikieditor-toolbar-help-content-bolditalic-description\":\"Bold &amp; italic\",\"wikieditor-toolbar-help-content-bolditalic-syntax\":\"\'\'\'\'\'Bold &amp; italic text\'\'\'\'\'\",\"wikieditor-toolbar-help-content-bolditalic-result\":\"<strong><em>Bold &amp; italic text<\\/em><\\/strong>\",\"wikieditor-toolbar-help-content-ilink-description\":\"Internal link\",\"wikieditor-toolbar-help-content-ilink-syntax\":\"[[Page title|Link label]]<br \\/>[[Page title]]\",\"wikieditor-toolbar-help-content-ilink-result\":\"<a href=\'#\'>Link label<\\/a><br \\/><a href=\'#\'>Page title<\\/a>\",\"wikieditor-toolbar-help-content-xlink-description\":\"External link\",\"wikieditor-toolbar-help-content-xlink-syntax\":\"[http:\\/\\/www.example.org Link label]<br \\/>[http:\\/\\/www.example.org]<br \\/>http:\\/\\/www.example.org\",\"wikieditor-toolbar-help-content-xlink-result\":\"<a href=\'#\' class=\'external\'>Link label<\\/a><br \\/><a href=\'#\' class=\'external autonumber\'>[1]<\\/a><br \\/><a href=\'#\' class=\'external\'>http:\\/\\/www.example.org<\\/a>\",\"wikieditor-toolbar-help-content-heading1-description\":\"&lt;wikieditor-toolbar-help-content-heading1-description&gt;\",\"wikieditor-toolbar-help-content-heading1-syntax\":\"&lt;wikieditor-toolbar-help-content-heading1-syntax&gt;\",\"wikieditor-toolbar-help-content-heading1-result\":\"&lt;wikieditor-toolbar-help-content-heading1-result&gt;\",\"wikieditor-toolbar-help-content-heading2-description\":\"2nd level heading\",\"wikieditor-toolbar-help-content-heading2-syntax\":\"== Heading text ==\",\"wikieditor-toolbar-help-content-heading2-result\":\"<h2>Heading text<\\/h2>\",\"wikieditor-toolbar-help-content-heading3-description\":\"3rd level heading\",\"wikieditor-toolbar-help-content-heading3-syntax\":\"=== Heading text ===\",\"wikieditor-toolbar-help-content-heading3-result\":\"<h3>Heading text<\\/h3>\",\"wikieditor-toolbar-help-content-heading4-description\":\"4th level heading\",\"wikieditor-toolbar-help-content-heading4-syntax\":\"==== Heading text ====\",\"wikieditor-toolbar-help-content-heading4-result\":\"<h4>Heading text<\\/h4>\",\"wikieditor-toolbar-help-content-heading5-description\":\"5th level heading\",\"wikieditor-toolbar-help-content-heading5-syntax\":\"===== Heading text =====\",\"wikieditor-toolbar-help-content-heading5-result\":\"<h5>Heading text<\\/h5>\",\"wikieditor-toolbar-help-content-ulist-description\":\"Bulleted list\",\"wikieditor-toolbar-help-content-ulist-syntax\":\"* List item<br \\/>* List item\",\"wikieditor-toolbar-help-content-ulist-result\":\"<ul><li>List item<\\/li><li>List item<\\/li><\\/ul>\",\"wikieditor-toolbar-help-content-olist-description\":\"Numbered list\",\"wikieditor-toolbar-help-content-olist-syntax\":\"# List item<br \\/># List item\",\"wikieditor-toolbar-help-content-olist-result\":\"<ol><li>List item<\\/li><li>List item<\\/li><\\/ol>\",\"wikieditor-toolbar-help-content-file-description\":\"Embedded file\",\"wikieditor-toolbar-help-content-file-syntax\":\"[[{{ns:file}}:Example.png|thumb|Caption text]]\",\"wikieditor-toolbar-help-content-file-result\":\"<div style=\'width:104px;\' class=\'thumbinner\'><a title=\'Caption text\' class=\'image\' href=\'#\'><img height=\'50\' width=\'100\' border=\'0\' class=\'thumbimage\' src=\'extensions\\/UsabilityInitiative\\/images\\/wikiEditor\\/toolbar\\/example-image.png\' alt=\'\'\\/><\\/a><div class=\'thumbcaption\'><div class=\'magnify\'><a title=\'Enlarge\' class=\'internal\' href=\'#\'><img height=\'11\' width=\'15\' alt=\'\' src=\'$1\\/common\\/images\\/magnify-clip.png\'\\/><\\/a><\\/div>Caption text<\\/div><\\/div>\",\"wikieditor-toolbar-help-content-reference-description\":\"Reference\",\"wikieditor-toolbar-help-content-reference-syntax\":\"Page text.&lt;ref name=\\\"test\\\"&gt;[http:\\/\\/www.example.org Link text], additional text.&lt;\\/ref&gt;\",\"wikieditor-toolbar-help-content-reference-result\":\"Page text.<sup><a href=\'#\'>[1]<\\/a><\\/sup>\",\"wikieditor-toolbar-help-content-rereference-description\":\"Additional use of same reference\",\"wikieditor-toolbar-help-content-rereference-syntax\":\"&lt;ref name=\\\"test\\\" \\/&gt;\",\"wikieditor-toolbar-help-content-rereference-result\":\"Page text.<sup><a href=\'#\'>[1]<\\/a><\\/sup>\",\"wikieditor-toolbar-help-content-showreferences-description\":\"Display references\",\"wikieditor-toolbar-help-content-showreferences-syntax\":\"&lt;references \\/&gt;\",\"wikieditor-toolbar-help-content-showreferences-result\":\"<ol class=\'references\'><li id=\'cite_note-test-0\'><b><a title=\'\' href=\'#\'>^<\\/a><\\/b> <a rel=\'nofollow\' title=\'http:\\/\\/www.example.org\' class=\'external text\' href=\'#\'>Link text<\\/a>, additional text.<\\/li><\\/ol>\",\"wikieditor-toolbar-help-content-signaturetimestamp-description\":\"Signature with timestamp\",\"wikieditor-toolbar-help-content-signaturetimestamp-syntax\":\"~~~~\",\"wikieditor-toolbar-help-content-signaturetimestamp-result\":\"<a href=\'#\' title=\'{{#special:mypage}}\'>Username<\\/a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk<\\/a>) 15:54, 10 June 2009 (UTC)\",\"wikieditor-toolbar-help-content-signature-description\":\"Signature\",\"wikieditor-toolbar-help-content-signature-syntax\":\"~~~\",\"wikieditor-toolbar-help-content-signature-result\":\"<a href=\'#\' title=\'{{#special:mypage}}\'>Username<\\/a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk<\\/a>)\",\"wikieditor-toolbar-help-content-indent-description\":\"Indent\",\"wikieditor-toolbar-help-content-indent-syntax\":\"Normal text<br \\/>:Indented text<br \\/>::Indented text\",\"wikieditor-toolbar-help-content-indent-result\":\"Normal text<dl><dd>Indented text<dl><dd>Indented text<\\/dd><\\/dl><\\/dd><\\/dl>\"}','20110110172914'),('jquery.async','en','{}','20110110172915'),('jquery.autoEllipsis','en','{}','20110110172915'),('jquery.checkboxShiftClick','en','{}','20110110172915'),('jquery.client','en','{}','20110110172915'),('jquery.cookie','en','{}','20110110172915'),('jquery.delayedBind','en','{}','20110110172915'),('jquery.highlightText','en','{}','20110110172915'),('jquery.makeCollapsible','en','{\"collapsible-expand\":\"Expand\",\"collapsible-collapse\":\"Collapse\"}','20110110172915'),('jquery.placeholder','en','{}','20110110172915'),('jquery.suggestions','en','{}','20110110172915'),('jquery.tabIndex','en','{}','20110110172915'),('jquery.textSelection','en','{}','20110110172915'),('jquery.wikiEditor','en','{\"wikieditor-wikitext-tab\":\"Wikitext\",\"wikieditor-loading\":\"Loading\"}','20110110172914'),('jquery.wikiEditor.toolbar','en','{}','20110110172914'),('mediawiki.action.watch.ajax','en','{}','20110110172915'),('mediawiki.language','en','{}','20110110172915'),('mediawiki.legacy.ajax','en','{\"watch\":\"Watch\",\"unwatch\":\"Unwatch\",\"watching\":\"Watching...\",\"unwatching\":\"Unwatching...\",\"tooltip-ca-watch\":\"Add this page to your watchlist\",\"tooltip-ca-unwatch\":\"Remove this page from your watchlist\"}','20110110172915'),('mediawiki.legacy.edit','en','{}','20110110172915'),('mediawiki.legacy.wikibits','en','{\"showtoc\":\"show\",\"hidetoc\":\"hide\"}','20110110172915'),('mediawiki.util','en','{}','20110110172915');
 /*!40000 ALTER TABLE `mw_msg_resource` ENABLE KEYS */;
 UNLOCK TABLES;
 
index 8bca4b0..341b316 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 30 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name :'Back' and 'Continue' button availability
  * Version        : MediaWiki 1.18alpha
-*/
-
+ */
 
 class MediaWikiButtonsAvailabilityTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-
-    // Verify only 'Continue' button available on 'Language' page
-    public function testOnlyContinueButtonAvailability() {
-
-        parent::navigateLanguagePage();
-
-        // Verify only 'Continue' button avaialble
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-
-        // 'Back' button is not avaialble
-        $this->assertElementNotPresent( "submit-back" );
-    }
-
-
-    // Verify 'Continue' and 'Back' buttons availability
-    public function testBothButtonsAvailability() {
-
-        // Verify buttons availability on 'Welcome to MediaWiki' page
-        parent::navigateWelcometoMediaWikiPage();
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Connect to Database' page
-        parent::navigateConnetToDatabasePage();
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Database settings' page
-        $databaseName = DB_NAME_PREFIX."_db_settings";
-        parent::navigateDatabaseSettingsPage( $databaseName );
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Name' page
-        $databaseName = DB_NAME_PREFIX."_name";
-        parent::navigateNamePage( $databaseName );
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Options' page
-        $databaseName = DB_NAME_PREFIX."_options";
-        parent::navigateOptionsPage( $databaseName );
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Install' page
-        $databaseName = DB_NAME_PREFIX."_install";
-        parent::navigateInstallPage($databaseName);
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify only 'Continue' button available on 'Language' page
+       public function testOnlyContinueButtonAvailability() {
+               parent::navigateLanguagePage();
+
+               // Verify only 'Continue' button avaialble
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+
+               // 'Back' button is not avaialble
+               $this->assertElementNotPresent( "submit-back" );
+       }
+
+       // Verify 'Continue' and 'Back' buttons availability
+       public function testBothButtonsAvailability() {
+               // Verify buttons availability on 'Welcome to MediaWiki' page
+               parent::navigateWelcometoMediaWikiPage();
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Connect to Database' page
+               parent::navigateConnetToDatabasePage();
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Database settings' page
+               $databaseName = DB_NAME_PREFIX . "_db_settings";
+               parent::navigateDatabaseSettingsPage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Name' page
+               $databaseName = DB_NAME_PREFIX . "_name";
+               parent::navigateNamePage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Options' page
+               $databaseName = DB_NAME_PREFIX . "_options";
+               parent::navigateOptionsPage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Install' page
+               $databaseName = DB_NAME_PREFIX . "_install";
+               parent::navigateInstallPage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+       }
 }
index 8e2afe7..76a794c 100644 (file)
@@ -34,49 +34,46 @@ require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
  * Test Case ID   : 04 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install MediaWiki with different Database accounts for web access.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiDifferentDatabaseAccountTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-
-    // Install Mediawiki using 'MySQL' database type.
-    public function testDifferentDatabaseAccount() {
-
-        $databaseName = DB_NAME_PREFIX."_dif_accounts";
+       // Install Mediawiki using 'MySQL' database type.
+       public function testDifferentDatabaseAccount() {
+               $databaseName = DB_NAME_PREFIX . "_dif_accounts";
 
-        // Navigate to the 'Database settings' page
-        parent::navigateDatabaseSettingsPage( $databaseName );
+               // Navigate to the 'Database settings' page
+               parent::navigateDatabaseSettingsPage( $databaseName );
 
-        // Click on the 'Use the same account as for installation' check box
-        $this->click( "mysql__SameAccount" );
+               // Click on the 'Use the same account as for installation' check box
+               $this->click( "mysql__SameAccount" );
 
-        // Change the 'Database username'
-        $this->type( "mysql_wgDBuser", DB_WEB_USER );
+               // Change the 'Database username'
+               $this->type( "mysql_wgDBuser", DB_WEB_USER );
 
-        // Enter 'Database password:'
-        $this->type( "mysql_wgDBpassword", DB_WEB_USER_PASSWORD );
+               // Enter 'Database password:'
+               $this->type( "mysql_wgDBpassword", DB_WEB_USER_PASSWORD );
 
-        // Select 'Create the account if it does not already exist' check box
-        $this->click( "mysql__CreateDBAccount" );
-        parent::clickContinueButton();
+               // Select 'Create the account if it does not already exist' check box
+               $this->click( "mysql__CreateDBAccount" );
+               parent::clickContinueButton();
 
-        // 'Name' page
-        parent::completeNamePage();
+               // 'Name' page
+               parent::completeNamePage();
 
-        // 'Options' page
-        parent::clickContinueButton();
+               // 'Options' page
+               parent::clickContinueButton();
 
-        // 'Install' page
-        $this->assertEquals("Creating database user... done",
-                $this->getText( LINK_FORM."ul/li[3]"));
-        parent::clickContinueButton();
+               // 'Install' page
+               $this->assertEquals( "Creating database user... done",
+                       $this->getText( LINK_FORM . "ul/li[3]" ) );
+               parent::clickContinueButton();
 
-        // 'Complete' page
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-    }
+               // 'Complete' page
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+       }
 }
index 55ad461..2c879c3 100644 (file)
@@ -34,62 +34,60 @@ require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
  * Test Case Name : Install MediaWiki with the same database and the different
  *                  database prefixes(Share one database between multiple wikis).
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiDifferntDatabasePrefixTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Install Mediawiki using 'MySQL' database type.
-    public function testDifferentDatabasePrefix() {
-
-        $databaseName = DB_NAME_PREFIX."_db_prefix";
-        parent::navigateInstallPage( $databaseName );
+       // Install Mediawiki using 'MySQL' database type.
+       public function testDifferentDatabasePrefix() {
+               $databaseName = DB_NAME_PREFIX . "_db_prefix";
+               parent::navigateInstallPage( $databaseName );
 
-        // To 'Options' page
-        parent::clickBackButton();
+               // To 'Options' page
+               parent::clickBackButton();
 
-        // To 'Name' page
-        parent::clickBackButton();
+               // To 'Name' page
+               parent::clickBackButton();
 
-        // To 'Database settings' page
-        parent::clickBackButton();
+               // To 'Database settings' page
+               parent::clickBackButton();
 
-        // To 'Connect to database' page
-        parent::clickBackButton();
+               // To 'Connect to database' page
+               parent::clickBackButton();
 
-        // From 'Connect to database' page without database prefix
-        parent::clickContinueButton();
+               // From 'Connect to database' page without database prefix
+               parent::clickContinueButton();
 
-        // Verify upgrade existing message
-        $this->assertEquals( "Upgrade existing installation",
-                $this->getText( LINK_DIV."h2" ));
+               // Verify upgrade existing message
+               $this->assertEquals( "Upgrade existing installation",
+                       $this->getText( LINK_DIV . "h2" ) );
 
-        // To 'Connect to database' page
-        parent::clickBackButton();
+               // To 'Connect to database' page
+               parent::clickBackButton();
 
-        // Input the database prefix
-        $this->type( "mysql_wgDBprefix", DATABASE_PREFIX );
+               // Input the database prefix
+               $this->type( "mysql_wgDBprefix", DATABASE_PREFIX );
 
-        // From 'Connect to database' page with database prefix
-        parent::clickContinueButton();
+               // From 'Connect to database' page with database prefix
+               parent::clickContinueButton();
 
-        // To 'Complete' page
-        parent::clickContinueButton();
-        parent::completeNamePage();
-        parent::clickContinueButton();
+               // To 'Complete' page
+               parent::clickContinueButton();
+               parent::completeNamePage();
+               parent::clickContinueButton();
 
-        // Verify already installed warning message
-        $this->assertEquals( "Install",
-                $this->getText( LINK_DIV."h2" ));
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_FORM."div[1]" ));
+               // Verify already installed warning message
+               $this->assertEquals( "Install",
+                       $this->getText( LINK_DIV . "h2" ) );
+               $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_FORM . "div[1]" ) );
 
-        parent::clickContinueButton();
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-        parent::restartInstallation();
-    }
+               parent::clickContinueButton();
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+               parent::restartInstallation();
+       }
 }
index 825ca42..7eb6d38 100644 (file)
@@ -34,103 +34,102 @@ require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
  * Test Case ID   : 09 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Invalid/ blank values for fields in 'Connect to database' page.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiErrorsConnectToDatabasePageTestCase extends MediaWikiInstallationCommonFunction {
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify warning messages for the 'Connet to database' page
-    public function testErrorsConnectToDatabasePage() {
-
-        parent::navigateConnetToDatabasePage();
-
-        // Verify warning mesage for invalid database host
-        $this->type( "mysql_wgDBserver", INVALID_DB_HOST );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: php_network_getaddresses: getaddrinfo failed: No such host is known. (".INVALID_DB_HOST.").",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-        // Verify warning message for the blank database host
-        $this->type( "mysql_wgDBserver", "" );
-        parent::clickContinueButton();
-        $this->assertEquals( "MySQL 4.0.14 or later is required, you have .",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // Valid Database Host
-        $this->type( "mysql_wgDBserver", VALID_DB_HOST );
-
-        // Verify warning message for the invalid database name
-        $this->type( "mysql_wgDBname", INVALID_DB_NAME );
-        parent::clickContinueButton();
-        $this->assertEquals( "Invalid database name \"".INVALID_DB_NAME."\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p" ));
-
-        // Verify warning message for the blank database name
-        $this->type( "mysql_wgDBname", "");
-        parent::clickContinueButton();
-        $this->assertEquals( "You must enter a value for \"Database name\"",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // valid Database name
-        $this->type( "mysql_wgDBname", VALID_DB_NAME);
-
-        // Verify warning message for the invalid databaase prefix
-        $this->type( "mysql_wgDBprefix", INVALID_DB_PREFIX );
-        parent::clickContinueButton();
-        $this->assertEquals( "Invalid database prefix \"".INVALID_DB_PREFIX."\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // Valid Database prefix
-        $this->type( "mysql_wgDBprefix", VALID_DB_PREFIX );
-
-        // Verify warning message for the invalid database user name
-        $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: Access denied for user '".INVALID_DB_USER_NAME."'@'localhost' (using password: NO) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]"));
-
-        // Verify warning message for the blank database user name
-        $this->type( "mysql__InstallUser", "" );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: Access denied for user 'SYSTEM'@'localhost' (using password: NO) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-
-        // Valid Database username
-        $this->type( "mysql__InstallUser",  VALID_DB_USER_NAME );
-
-        // Verify warning message for the invalid password
-        $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
-        parent::clickContinueButton();
-
-        $this->assertEquals( "DB connection error: Access denied for user 'root'@'localhost' (using password: YES) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-
-        // Verify warning message for the invalid username and password
-        $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
-        $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: Access denied for user '".INVALID_DB_USER_NAME."'@'localhost' (using password: YES) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-
-        // Valid username and valid password
-        $this->type( "mysql__InstallUser", VALID_DB_USER_NAME );
-        $this->type( "mysql__InstallPassword", "" );
-        parent::clickContinueButton();
-
-        // successfully completes the 'Connect to database' page
-        $this->assertEquals( "Database settings",
-                $this->getText( LINK_DIV."h2" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify warning messages for the 'Connet to database' page
+       public function testErrorsConnectToDatabasePage() {
+               parent::navigateConnetToDatabasePage();
+
+               // Verify warning mesage for invalid database host
+               $this->type( "mysql_wgDBserver", INVALID_DB_HOST );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: php_network_getaddresses: getaddrinfo failed: No such host is known. (" . INVALID_DB_HOST . ").",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+               // Verify warning message for the blank database host
+               $this->type( "mysql_wgDBserver", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "MySQL 4.0.14 or later is required, you have .",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Valid Database Host
+               $this->type( "mysql_wgDBserver", VALID_DB_HOST );
+
+               // Verify warning message for the invalid database name
+               $this->type( "mysql_wgDBname", INVALID_DB_NAME );
+               parent::clickContinueButton();
+               $this->assertEquals( "Invalid database name \"" . INVALID_DB_NAME . "\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p" ) );
+
+               // Verify warning message for the blank database name
+               $this->type( "mysql_wgDBname", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "You must enter a value for \"Database name\"",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // valid Database name
+               $this->type( "mysql_wgDBname", VALID_DB_NAME );
+
+               // Verify warning message for the invalid databaase prefix
+               $this->type( "mysql_wgDBprefix", INVALID_DB_PREFIX );
+               parent::clickContinueButton();
+               $this->assertEquals( "Invalid database prefix \"" . INVALID_DB_PREFIX . "\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Valid Database prefix
+               $this->type( "mysql_wgDBprefix", VALID_DB_PREFIX );
+
+               // Verify warning message for the invalid database user name
+               $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: Access denied for user '" . INVALID_DB_USER_NAME . "'@'localhost' (using password: NO) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Verify warning message for the blank database user name
+               $this->type( "mysql__InstallUser", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: Access denied for user 'SYSTEM'@'localhost' (using password: NO) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Valid Database username
+               $this->type( "mysql__InstallUser", VALID_DB_USER_NAME );
+
+               // Verify warning message for the invalid password
+               $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
+               parent::clickContinueButton();
+
+               $this->assertEquals( "DB connection error: Access denied for user 'root'@'localhost' (using password: YES) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Verify warning message for the invalid username and password
+               $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
+               $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: Access denied for user '" . INVALID_DB_USER_NAME . "'@'localhost' (using password: YES) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Valid username and valid password
+               $this->type( "mysql__InstallUser", VALID_DB_USER_NAME );
+               $this->type( "mysql__InstallPassword", "" );
+               parent::clickContinueButton();
+
+               // successfully completes the 'Connect to database' page
+               $this->assertEquals( "Database settings",
+                       $this->getText( LINK_DIV . "h2" ) );
+       }
 }
index c2b3505..e3d4266 100644 (file)
  * Test Case ID   : 10 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Invalid/ blank values for fields in 'Name' page.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
 
 class MediaWikiErrorsNamepageTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify warning message for the 'Name' page
-    public function testErrorsNamePage() {
-
-        $databaseName  = DB_NAME_PREFIX."_error_name";
-
-        parent::navigateNamePage( $databaseName );
-
-        // Verify warning message for all blank fields
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter a site name.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-        $this->assertEquals( "Enter an administrator username.",
-                $this->getText( LINK_DIV."div[3]/div[2]" ));
-        $this->assertEquals( "Enter a password for the administrator account.",
-                $this->getText( LINK_DIV."div[4]/div[2]" ));
-
-        // Verify warning message for the blank 'Site name'
-        $this->type( "config__AdminName", VALID_YOUR_NAME );
-        $this->type( "config__AdminPassword", VALID_PASSWORD );
-        $this->type( "config__AdminPassword2", VALID_PASSWORD_AGAIN );
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter a site name.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // Input valid 'Site name'
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-
-
-        // Verify warning message for the invalid "Project namespace'
-        $this->click( "config__NamespaceType_other" );
-        $this->type( "config_wgMetaNamespace", INVALID_NAMESPACE );
-        parent::clickContinueButton();
-        $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Verify warning message for the blank 'Project namespace'
-        $this->type( "config_wgSitename",  VALID_WIKI_NAME );
-        $this->click( "config__NamespaceType_other" );
-        $this->type( "config_wgMetaNamespace" , "" );
-        parent::clickContinueButton();
-        $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Valid 'Project namespace'
-        $this->click( "config__NamespaceType_other" );
-        $this->type( "config_wgMetaNamespace", VALID_NAMESPACE );
-        parent::clickContinueButton();
-
-
-        // Valid 'Site name'
-        $this->click( "config__NamespaceType_site-name" );
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-
-
-        // Verify warning message for blank 'Your name'
-        $this->type( "config__AdminName", " " );
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter an administrator username.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-        // Verify warning message for blank 'Password'
-        $this->type( "config__AdminName", VALID_YOUR_NAME );
-        $this->type( "config__AdminPassword", " " );
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter a password for the administrator account.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Verify warning message for the blank 'Password again'
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-        $this->type( "config__AdminPassword", VALID_PASSWORD );
-        $this->type( "config__AdminPassword2", " " );
-        parent::clickContinueButton();
-        $this->assertEquals( "The two passwords you entered do not match.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Verify warning message for the different'Password' and 'Password again'
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-        $this->type( "config__AdminPassword", VALID_PASSWORD );
-        $this->type( "config__AdminPassword2", INVALID_PASSWORD_AGAIN );
-        parent::clickContinueButton();
-        $this->assertEquals( "The two passwords you entered do not match.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify warning message for the 'Name' page
+       public function testErrorsNamePage() {
+
+               $databaseName = DB_NAME_PREFIX . "_error_name";
+
+               parent::navigateNamePage( $databaseName );
+
+               // Verify warning message for all blank fields
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter a site name.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+               $this->assertEquals( "Enter an administrator username.",
+                       $this->getText( LINK_DIV . "div[3]/div[2]" ) );
+               $this->assertEquals( "Enter a password for the administrator account.",
+                       $this->getText( LINK_DIV . "div[4]/div[2]" ) );
+
+               // Verify warning message for the blank 'Site name'
+               $this->type( "config__AdminName", VALID_YOUR_NAME );
+               $this->type( "config__AdminPassword", VALID_PASSWORD );
+               $this->type( "config__AdminPassword2", VALID_PASSWORD_AGAIN );
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter a site name.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Input valid 'Site name'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+
+               // Verify warning message for the invalid "Project namespace'
+               $this->click( "config__NamespaceType_other" );
+               $this->type( "config_wgMetaNamespace", INVALID_NAMESPACE );
+               parent::clickContinueButton();
+               $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Verify warning message for the blank 'Project namespace'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               $this->click( "config__NamespaceType_other" );
+               $this->type( "config_wgMetaNamespace", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Valid 'Project namespace'
+               $this->click( "config__NamespaceType_other" );
+               $this->type( "config_wgMetaNamespace", VALID_NAMESPACE );
+               parent::clickContinueButton();
+
+               // Valid 'Site name'
+               $this->click( "config__NamespaceType_site-name" );
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+
+               // Verify warning message for blank 'Your name'
+               $this->type( "config__AdminName", " " );
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter an administrator username.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               // Verify warning message for blank 'Password'
+               $this->type( "config__AdminName", VALID_YOUR_NAME );
+               $this->type( "config__AdminPassword", " " );
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter a password for the administrator account.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Verify warning message for the blank 'Password again'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               $this->type( "config__AdminPassword", VALID_PASSWORD );
+               $this->type( "config__AdminPassword2", " " );
+               parent::clickContinueButton();
+               $this->assertEquals( "The two passwords you entered do not match.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Verify warning message for the different'Password' and 'Password again'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               $this->type( "config__AdminPassword", VALID_PASSWORD );
+               $this->type( "config__AdminPassword2", INVALID_PASSWORD_AGAIN );
+               parent::clickContinueButton();
+               $this->assertEquals( "The two passwords you entered do not match.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+       }
 }
index 78205cf..961f692 100644 (file)
  * Test Case ID   : 29 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Help field hint availability for the fields.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
 
 class MediaWikiHelpFieldHintTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-
-    // Verify help field availability for the fields
-    public function testMySQLConnectToDatabaseFieldHint() {
-
-        parent::navigateConnetToDatabasePage();
-
-        // Verify help field for 'Database host'
-        $this->click( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATABASE_HOST_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[2]" ) );
-
-        // Verify help field for 'Database name'
-        $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATABASE_NAME_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]" ));
-
-
-        // Verify help field for 'Database table prefix'
-        $this->click("//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/div/span[1]" );
-        $this->assertEquals(MYSQL_DATABASE_TABLE_PREFIX_HELP,
-                $this->getText("//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]/p[1]" ));
-
-        // Verify help field for 'Database username'
-        $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATBASE_USERNAME_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[2]" ));
-
-        // Verify help field for 'Database password'
-        $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATABASE_PASSWORD_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[2]/p" ));
-    }
-
-
-    public function testSQLiteConnectToDatabaseFieldHint() {
-
-        parent::navigateConnetToDatabasePage();
-        $this->click( "DBType_sqlite" );
-
-        //  Verify help field for 'SQLite data directory'
-        $this->click( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( SQLITE_DATA_DIRECTORY_HELP,
-                $this->getText( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[2]" ));
-
-        // Verify help field for 'Database name'
-        $this->click( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[1]" );
-        $this->assertEquals( SQLITE_DATABASE_NAME_HELP , $this->getText( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[2]/p" ));
-    }
-
-
-    public function testDatabaseSettingsFieldHint() {
-
-        $databaseName = DB_NAME_PREFIX."_db_field";
-        parent::navigateDatabaseSettingsPage($databaseName);
-
-        // Verify help field for 'Search engine'
-        $this->click( LINK_FORM."div[2]/span[1]" );
-        $this->assertEquals( SEARCH_ENGINE_HELP,
-                $this->getText( LINK_FORM."div[2]/span[2]" ));
-
-        // Verify help field for 'Database character set'
-        $this->click( LINK_FORM."div[4]/span[1]" );
-        $this->assertEquals( DATABASE_CHARACTER_SET_HELP,
-                $this->getText( LINK_FORM."div[4]/span[2]"));
-        parent::restartInstallation();
-    }
-
-
-    public function testNameFieldHint() {
-
-        $databaseName = DB_NAME_PREFIX."_name_field";
-        parent::navigateNamePage( $databaseName );
-
-        // Verify help field for 'Name of Wiki'
-        $this->click( LINK_FORM."div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( NAME_OF_WIKI_HELP,
-                $this->getText( LINK_FORM."div[1]/div[1]/div/span[2]/p" ));
-
-        // Verify help field for 'Project namespace'
-        $this->click( LINK_FORM."div[2]/div[1]/div/span[1]" );
-        $this->assertEquals( PROJECT_NAMESPACE_HELP,
-                $this->getText( LINK_FORM."div[2]/div[1]/div/span[2]/p"));
-
-        // Verify help field for 'Your Name'
-        $this->click( LINK_FORM."fieldset/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( USER_NAME_HELP,
-                $this->getText( LINK_FORM."fieldset/div[1]/div[1]/div/span[2]/p" ));
-
-        // Verify help field for 'E mail address'
-        $this->click( LINK_FORM."fieldset/div[4]/div[1]/div/span[1]" );
-        $this->assertEquals( EMAIL_ADDRESS_HELP,
-                $this->getText( LINK_FORM."fieldset/div[4]/div[1]/div/span[2]/p" ));
-
-        parent::restartInstallation();
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify help field availability for the fields
+       public function testMySQLConnectToDatabaseFieldHint() {
+
+               parent::navigateConnetToDatabasePage();
+
+               // Verify help field for 'Database host'
+               $this->click( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_HOST_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[2]" ) );
+
+               // Verify help field for 'Database name'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_NAME_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]" ) );
+
+
+               // Verify help field for 'Database table prefix'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_TABLE_PREFIX_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]/p[1]" ) );
+
+               // Verify help field for 'Database username'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATBASE_USERNAME_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[2]" ) );
+
+               // Verify help field for 'Database password'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_PASSWORD_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[2]/p" ) );
+       }
+
+       public function testSQLiteConnectToDatabaseFieldHint() {
+               parent::navigateConnetToDatabasePage();
+               $this->click( "DBType_sqlite" );
+
+               //  Verify help field for 'SQLite data directory'
+               $this->click( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( SQLITE_DATA_DIRECTORY_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[2]" ) );
+
+               // Verify help field for 'Database name'
+               $this->click( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( SQLITE_DATABASE_NAME_HELP, $this->getText( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[2]/p" ) );
+       }
+
+       public function testDatabaseSettingsFieldHint() {
+
+               $databaseName = DB_NAME_PREFIX . "_db_field";
+               parent::navigateDatabaseSettingsPage( $databaseName );
+
+               // Verify help field for 'Search engine'
+               $this->click( LINK_FORM . "div[2]/span[1]" );
+               $this->assertEquals( SEARCH_ENGINE_HELP,
+                       $this->getText( LINK_FORM . "div[2]/span[2]" ) );
+
+               // Verify help field for 'Database character set'
+               $this->click( LINK_FORM . "div[4]/span[1]" );
+               $this->assertEquals( DATABASE_CHARACTER_SET_HELP,
+                       $this->getText( LINK_FORM . "div[4]/span[2]" ) );
+               parent::restartInstallation();
+       }
+
+       public function testNameFieldHint() {
+               $databaseName = DB_NAME_PREFIX . "_name_field";
+               parent::navigateNamePage( $databaseName );
+
+               // Verify help field for 'Name of Wiki'
+               $this->click( LINK_FORM . "div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( NAME_OF_WIKI_HELP,
+                       $this->getText( LINK_FORM . "div[1]/div[1]/div/span[2]/p" ) );
+
+               // Verify help field for 'Project namespace'
+               $this->click( LINK_FORM . "div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( PROJECT_NAMESPACE_HELP,
+                       $this->getText( LINK_FORM . "div[2]/div[1]/div/span[2]/p" ) );
+
+               // Verify help field for 'Your Name'
+               $this->click( LINK_FORM . "fieldset/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( USER_NAME_HELP,
+                       $this->getText( LINK_FORM . "fieldset/div[1]/div[1]/div/span[2]/p" ) );
+
+               // Verify help field for 'E mail address'
+               $this->click( LINK_FORM . "fieldset/div[4]/div[1]/div/span[1]" );
+               $this->assertEquals( EMAIL_ADDRESS_HELP,
+                       $this->getText( LINK_FORM . "fieldset/div[4]/div[1]/div/span[2]/p" ) );
+
+               parent::restartInstallation();
+       }
 }
 
index 353fa2e..06bad30 100644 (file)
 require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
 require_once ( __DIR__ . '/MediaWikiInstallationConfig.php' );
 require_once ( __DIR__ . '/MediaWikiInstallationMessage.php' );
-require_once ( __DIR__ . '/MediaWikiInstallationVariables.php');
-
+require_once ( __DIR__ . '/MediaWikiInstallationVariables.php' );
 
 class MediaWikiInstallationCommonFunction extends PHPUnit_Extensions_SeleniumTestCase {
-
-    function setUp() {
-        $this->setBrowser( TEST_BROWSER );
-        $this->setBrowserUrl("http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/");
-    }
-
-
-    public function navigateInitialpage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/" );
-    }
-
-
-    // Navigate to the 'Language' page
-    public function navigateLanguagePage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-    }
-
-
-    // Navigate to the 'Welcome to MediaWiki' page
-    public function navigateWelcometoMediaWikiPage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-        $this->click( "submit-continue ");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate yo 'Connect to Database' page
-    public function navigateConnetToDatabasePage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click("submit-continue");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate to the 'Database Settings' page
-    public function navigateDatabaseSettingsPage( $databaseName ) {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click("submit-continue");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click("submit-continue");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type("mysql_wgDBname", $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate to the 'Name' page
-    public function navigateNamePage( $databaseName ) {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate 'Options' page
-    public function navigateOptionsPage( $databaseName ) {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Name
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate 'Install' page
-    public function navigateInstallPage( $databaseName ) {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Name
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Options page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate to 'Complete' page
-    public function navigateCompletePage( $databaseName ) {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Name
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Options page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Install page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->chooseCancelOnNextConfirmation();
-    }
-
-
-    // Complete the Name page fields
-    public function completeNamePage() {
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME);
-    }
-
-
-    // Clicking on the 'Continue' button in any MediaWiki page
-    public function clickContinueButton() {
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Clicking on the 'Back' button in any MediaWiki page
-    public function clickBackButton() {
-        $this->click( "submit-back" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Restarting the installation
-    public function restartInstallation() {
-        $this->click( "link=Restart installation" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->click( "submit-restart" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Verify 'MediaWiki' logo available in the initial screen
-    public function mediaWikiLogoPresentInitialScreen() {
-        $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ));
-    }
-
-
-    // Verify 'MediaWiki' logo available
-    public function mediaWikiLogoPresent() {
-        $this->assertTrue( $this->isElementPresent( "//div[@id='p-logo']/a" ));
-    }
-
-
-    public function completePageSuccessfull() {
-        $this->assertEquals( "Complete!",
-                $this->getText( "//div[@id='bodyContent']/div/div/h2" ));
-
-        // 'Congratulations!' text should be available in the 'Complete!' page.
-        $this->assertEquals( "Congratulations!",
-                $this->getText( "//div[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]/p[1]/b" ));
-    }
+       function setUp() {
+               $this->setBrowser( TEST_BROWSER );
+               $this->setBrowserUrl( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/" );
+       }
+
+       public function navigateInitialpage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/" );
+       }
+
+       // Navigate to the 'Language' page
+       public function navigateLanguagePage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+       }
+
+       // Navigate to the 'Welcome to MediaWiki' page
+       public function navigateWelcometoMediaWikiPage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+               $this->click( "submit-continue " );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate yo 'Connect to Database' page
+       public function navigateConnetToDatabasePage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate to the 'Database Settings' page
+       public function navigateDatabaseSettingsPage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate to the 'Name' page
+       public function navigateNamePage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate 'Options' page
+       public function navigateOptionsPage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Name
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate 'Install' page
+       public function navigateInstallPage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Name
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Options page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate to 'Complete' page
+       public function navigateCompletePage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Name
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Options page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Install page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->chooseCancelOnNextConfirmation();
+       }
+
+       // Complete the Name page fields
+       public function completeNamePage() {
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Clicking on the 'Continue' button in any MediaWiki page
+       public function clickContinueButton() {
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Clicking on the 'Back' button in any MediaWiki page
+       public function clickBackButton() {
+               $this->click( "submit-back" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Restarting the installation
+       public function restartInstallation() {
+               $this->click( "link=Restart installation" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->click( "submit-restart" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Verify 'MediaWiki' logo available in the initial screen
+       public function mediaWikiLogoPresentInitialScreen() {
+               $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ) );
+       }
+
+       // Verify 'MediaWiki' logo available
+       public function mediaWikiLogoPresent() {
+               $this->assertTrue( $this->isElementPresent( "//div[@id='p-logo']/a" ) );
+       }
+
+       public function completePageSuccessfull() {
+               $this->assertEquals( "Complete!",
+                       $this->getText( "//div[@id='bodyContent']/div/div/h2" ) );
+
+               // 'Congratulations!' text should be available in the 'Complete!' page.
+               $this->assertEquals( "Congratulations!",
+                       $this->getText( "//div[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]/p[1]/b" ) );
+       }
 }
index d86bcb8..2663f65 100644 (file)
@@ -33,9 +33,9 @@
  * with current value of the 'DB_NAME_PREFIX'.
  * If you wish to run the suite more than one time, you need to change
  * the value of the 'DB_NAME_PREFIX'.
-*/
-define('DB_NAME_PREFIX', "database_name" );
-define('DIRECTORY_NAME', "mediawiki" );
+ */
+define( 'DB_NAME_PREFIX', "database_name" );
+define( 'DIRECTORY_NAME', "mediawiki" );
 define( 'PORT', "8080" );
 define( 'HOST_NAME', "localhost" );
 
@@ -45,5 +45,5 @@ define( 'HOST_NAME', "localhost" );
  *  IE :  *iexplore
  *  Google chrome : *googlechrome
  *  Opera :  *opera
-*/
+ */
 define ( 'TEST_BROWSER', "*firefox" );
index a348b54..f63c2eb 100644 (file)
 // 'MySQL' database type help field hint
 define( 'MYSQL_DATABASE_HOST_HELP', "If your database server is on different server, enter the host name or IP address here. \nIf you are using shared web hosting, your hosting provider should give you the correct host name in their documentation. \nIf you are installing on a Windows server and using MySQL, using \"localhost\" may not work for the server name. If it does not, try \"127.0.0.1\" for the local IP address." );
 define( 'MYSQL_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens. \nIf you are using shared web hosting, your hosting provider will either give you a specific database name to use or let you create databases via a control panel." );
-define( 'MYSQL_DATABASE_TABLE_PREFIX_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens.");
+define( 'MYSQL_DATABASE_TABLE_PREFIX_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens." );
 define( 'MYSQL_DATBASE_USERNAME_HELP', "Enter the username that will be used to connect to the database during the installation process. This is not the username of the MediaWiki account; this is the username for your database." );
 define( 'MYSQL_DATABASE_PASSWORD_HELP', "Enter the password that will be used to connect to the database during the installation process. This is not the password for the MediaWiki account; this is the password for your database." );
 
 
 // 'SQLite' database type help field hint
 define( 'SQLITE_DATA_DIRECTORY_HELP', "SQLite stores all data in a single file. \nThe directory you provide must be writable by the webserver during installation. \nIt should not be accessible via the web, this is why we're not putting it where your PHP files are. \nThe installer will write a .htaccess file along with it, but if that fails someone can gain access to your raw database. That includes raw user data (e-mail addresses, hashed passwords) as well as deleted revisions and other restricted data on the wiki. \nConsider putting the database somewhere else altogether, for example in /var/lib/mediawiki/yourwiki." );
-define( 'SQLITE_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. Do not use spaces or hyphens. This will be used for the SQLite data file name.");
+define( 'SQLITE_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. Do not use spaces or hyphens. This will be used for the SQLite data file name." );
 
 
 // 'Database settings' page hel0p field hint
@@ -47,7 +47,7 @@ define( 'DATABASE_CHARACTER_SET_HELP', "In binary mode, MediaWiki stores UTF-8 t
 
 
 // 'Name' page help field hint
-define( 'NAME_OF_WIKI_HELP', "This will appear in the title bar of the browser and in various other places.");
+define( 'NAME_OF_WIKI_HELP', "This will appear in the title bar of the browser and in various other places." );
 define( 'PROJECT_NAMESPACE_HELP', "Following Wikipedia's example, many wikis keep their policy pages separate from their content pages, in a \"project namespace\". All page titles in this namespace start with a certain prefix, which you can specify here. Traditionally, this prefix is derived from the name of the wiki, but it cannot contain punctuation characters such as \"#\" or \":\"." );
 define( 'USER_NAME_HELP', "Enter your preferred username here, for example \"Joe Bloggs\". This is the name you will use to log in to the wiki." );
 define( 'EMAIL_ADDRESS_HELP', "Enter an e-mail address here to allow you to receive e-mail from other users on the wiki, reset your password, and be notified of changes to pages on your watchlist." );
index bb11d02..b271c7e 100644 (file)
 
 
 // Common variables
-define('PAGE_LOAD_TIME', "80000" );
+define( 'PAGE_LOAD_TIME', "80000" );
 
 // Common links
-define( 'LINK_DIV', "//div[@id='bodyContent']/div/div/");
+define( 'LINK_DIV', "//div[@id='bodyContent']/div/div/" );
 define( 'LINK_FORM', "//div[@id='bodyContent']/div/div/div[2]/form/" );
-define( 'LINK_RIGHT_FRAMEWORK', "//div[@id='bodyContent']/div/div/div[1]/ul[1]/");
+define( 'LINK_RIGHT_FRAMEWORK', "//div[@id='bodyContent']/div/div/div[1]/ul[1]/" );
 
 // 'Name' page input values
 define( 'NAME_OF_WIKI', "Site Name" );
@@ -48,30 +48,30 @@ define ( 'ADMIN_EMAIL_ADDRESS', "admin@example.com" );
 define( 'VALID_WIKI_NAME', "MyWiki" );
 define( 'VALID_YOUR_NAME', "FirstName LastName" );
 define( 'VALID_PASSWORD', "12345" );
-define( 'VALID_PASSWORD_AGAIN', "12345"  );
+define( 'VALID_PASSWORD_AGAIN', "12345" );
 define( 'INVALID_PASSWORD_AGAIN', "123" );
-define( 'VALID_NAMESPACE', "Mynamespace"  );
+define( 'VALID_NAMESPACE', "Mynamespace" );
 define( 'INVALID_NAMESPACE', "##..##" );
 
 
 // 'Database settings' page input values
 define( 'DB_WEB_USER', "different" );
-define('DB_WEB_USER_PASSWORD', "12345" );
+define( 'DB_WEB_USER_PASSWORD', "12345" );
 
 
 // 'Connet to database' page input values
-define( 'DATABASE_PREFIX',"databaseprefix" );
+define( 'DATABASE_PREFIX', "databaseprefix" );
 
 
 // 'Connet to database' page input values for warning messages
 define( 'VALID_DB_HOST', "localhost" );
 define( 'INVALID_DB_HOST', "local" );
 define( 'INVALID_DB_NAME', "my-wiki" );
-define( 'VALID_DB_NAME', "my_wiki1");
+define( 'VALID_DB_NAME', "my_wiki1" );
 define( 'INVALID_DB_PREFIX', "database prefix" );
-define( 'VALID_DB_PREFIX', "database_prefix");
+define( 'VALID_DB_PREFIX', "database_prefix" );
 define( 'INVALID_DB_USER_NAME', "roots" );
-define( 'VALID_DB_USER_NAME', "root");
+define( 'VALID_DB_USER_NAME', "root" );
 define( 'INVALID_DB_PASSWORD', "12345" );
 
 
index 58ccc7c..1356ce6 100644 (file)
@@ -27,7 +27,6 @@
  *
  */
 
-require_once 'PHPUnit/Framework.php';
 require_once 'PHPUnit/Framework/TestSuite.php';
 
 require_once ( __DIR__ . '/MediaWikiUserInterfaceTestCase.php' );
@@ -44,10 +43,7 @@ require_once ( __DIR__ . '/MediaWikiDifferntDatabasePrefixTestCase.php' );
 require_once ( __DIR__ . '/MediaWikiDifferentDatabaseAccountTestCase.php' );
 require_once ( __DIR__ . '/MediaWikiOnAlreadyInstalledTestCase.php' );
 
-
-
-
-$suite = new PHPUnit_Framework_TestSuite('ArrayTest');
+$suite = new PHPUnit_Framework_TestSuite( 'ArrayTest' );
 $result = new PHPUnit_Framework_TestResult;
 
-$suite->run($result);
+$suite->run( $result );
index 16d065c..d631ed8 100644 (file)
  *
  */
 
-
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 01 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install Mediawiki using 'MySQL' database type successfully
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiMySQLDataBaseTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify  MediaWiki installation using 'MySQL' database type
-    public function testMySQLDatabaseSuccess() {
-
-        $databaseName = DB_NAME_PREFIX."_sql_db";
+       // Verify  MediaWiki installation using 'MySQL' database type
+       public function testMySQLDatabaseSuccess() {
+               $databaseName = DB_NAME_PREFIX . "_sql_db";
 
-        parent::navigateConnetToDatabasePage();
+               parent::navigateConnetToDatabasePage();
 
-        // Verify 'MySQL" is selected as the default database type
-        $this->assertEquals( "MySQL settings", $this->getText( "//div[@id='DB_wrapper_mysql']/h3" ));
+               // Verify 'MySQL" is selected as the default database type
+               $this->assertEquals( "MySQL settings", $this->getText( "//div[@id='DB_wrapper_mysql']/h3" ) );
 
-        // Change 'Database name'
-        $defaultDbName = $this->getText( "mysql_wgDBname" );
-        $this->type( "mysql_wgDBname", " ");
-        $this->type( "mysql_wgDBname", $databaseName );
-        $this->assertNotEquals( $defaultDbName, $databaseName );
+               // Change 'Database name'
+               $defaultDbName = $this->getText( "mysql_wgDBname" );
+               $this->type( "mysql_wgDBname", " " );
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->assertNotEquals( $defaultDbName, $databaseName );
 
-        // 'Database settings' page
-        parent::clickContinueButton();
+               // 'Database settings' page
+               parent::clickContinueButton();
 
-        // 'Name' page
-        parent::clickContinueButton();
-        parent::completeNamePage();
+               // 'Name' page
+               parent::clickContinueButton();
+               parent::completeNamePage();
 
-        // 'Options page
-        parent::clickContinueButton();
+               // 'Options page
+               parent::clickContinueButton();
 
-        // 'Install' page
-        parent::clickContinueButton();
+               // 'Install' page
+               parent::clickContinueButton();
 
-        // 'Complete' page
-        parent::completePageSuccessfull();
-        parent::restartInstallation();
-    }
+               // 'Complete' page
+               parent::completePageSuccessfull();
+               parent::restartInstallation();
+       }
 }
index 4ca6916..19c05da 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 06 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install Mediawiki using 'MySQL' database type successfully
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiMySQLiteDataBaseTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify  MediaWiki installation using 'MySQL' database type
-    public function testMySQLDatabaseSuccess() {
-
-        $databaseName = DB_NAME_PREFIX."_sqlite_db";
+       // Verify  MediaWiki installation using 'MySQL' database type
+       public function testMySQLDatabaseSuccess() {
+               $databaseName = DB_NAME_PREFIX . "_sqlite_db";
 
-        parent::navigateConnetToDatabasePage();
-        $this->click( "DBType_sqlite" );
+               parent::navigateConnetToDatabasePage();
+               $this->click( "DBType_sqlite" );
 
-        // Select 'SQLite' database type
-        $this->assertEquals( "SQLite settings", $this->getText( "//div[@id='DB_wrapper_sqlite']/h3" ));
+               // Select 'SQLite' database type
+               $this->assertEquals( "SQLite settings", $this->getText( "//div[@id='DB_wrapper_sqlite']/h3" ) );
 
-        // Change database name
-        $defaultDbName = $this->getText( "sqlite_wgDBname" );
-        $this->type( "sqlite_wgDBname", " ");
-        $this->type( "sqlite_wgDBname", $databaseName );
-        $this->assertNotEquals( $defaultDbName, $databaseName );
+               // Change database name
+               $defaultDbName = $this->getText( "sqlite_wgDBname" );
+               $this->type( "sqlite_wgDBname", " " );
+               $this->type( "sqlite_wgDBname", $databaseName );
+               $this->assertNotEquals( $defaultDbName, $databaseName );
 
-        // 'Database settings' page
-        parent::clickContinueButton();
+               // 'Database settings' page
+               parent::clickContinueButton();
 
-        // 'Name' page
-        parent::clickContinueButton();
-        parent::completeNamePage();
+               // 'Name' page
+               parent::clickContinueButton();
+               parent::completeNamePage();
 
-        // 'Options page
-        parent::clickContinueButton();
+               // 'Options page
+               parent::clickContinueButton();
 
-        // 'Install' page
-        parent::clickContinueButton();
+               // 'Install' page
+               parent::clickContinueButton();
 
-        // 'Complete' page
-        parent::completePageSuccessfull();
-        parent::restartInstallation();
-    }
+               // 'Complete' page
+               parent::completePageSuccessfull();
+               parent::restartInstallation();
+       }
 }
index 7a1b615..21c4578 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 
 /**
  * Test Case ID   : 03 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install mediawiki on a already installed Mediawiki.]
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiOnAlreadyInstalledTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Install Mediawiki using 'MySQL' database type.
-    public function testInstallOnAlreadyInstalled() {
-
-        $databaseName = DB_NAME_PREFIX."_already_installed";
-        parent::navigateInstallPage( $databaseName );
+       // Install Mediawiki using 'MySQL' database type.
+       public function testInstallOnAlreadyInstalled() {
+               $databaseName = DB_NAME_PREFIX . "_already_installed";
+               parent::navigateInstallPage( $databaseName );
 
-        // 'Options' page
-        parent::clickBackButton();
+               // 'Options' page
+               parent::clickBackButton();
 
-        // Install page
-        parent::clickContinueButton();
+               // Install page
+               parent::clickContinueButton();
 
-        // 'Install' page should display after the 'Option' page
-        $this->assertEquals( "Install", $this->getText( LINK_DIV."h2" ));
+               // 'Install' page should display after the 'Option' page
+               $this->assertEquals( "Install", $this->getText( LINK_DIV . "h2" ) );
 
-        // Verify warning text displayed
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_FORM."div[1]/div[2]" ));
+               // Verify warning text displayed
+               $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_FORM . "div[1]/div[2]" ) );
 
-        // Complete page
-        parent::clickContinueButton();
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-        parent::restartInstallation();
-    }
+               // Complete page
+               parent::clickContinueButton();
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+               parent::restartInstallation();
+       }
 }
index ea87de0..2acb4df 100644 (file)
  */
 
 
-
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 11, 12 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install mediawiki on a already installed Mediawiki.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiRestartInstallationTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify restarting the installation
-    public function testSuccessRestartInstallation() {
-
-        $dbNameBeforeRestart  = DB_NAME_PREFIX."_db_before";
-        parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart );
-
-        // Verify 'Restart installation' link available
-        $this->assertTrue($this->isElementPresent( "link=Restart installation" ));
-
-        // Click 'Restart installation'
-        $this->click( "link=Restart installation ");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       // Verify restarting the installation
+       public function testSuccessRestartInstallation() {
+               $dbNameBeforeRestart = DB_NAME_PREFIX . "_db_before";
+               parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart );
 
-        // 'Restart Installation' page displayed
-        $this->assertEquals( "Restart installation", $this->getText( LINK_DIV."h2"));
+               // Verify 'Restart installation' link available
+               $this->assertTrue( $this->isElementPresent( "link=Restart installation" ) );
 
-        // Restart warning message displayed
-        $this->assertTrue($this->isTextPresent( "exact:Do you want to clear all saved data that you have entered and restart the installation process?" ));
+               // Click 'Restart installation'
+               $this->click( "link=Restart installation " );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
 
-        // Click on the 'Yes, restart' button
-        $this->click( "submit-restart" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               // 'Restart Installation' page displayed
+               $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) );
 
-        // Navigate to the initial installation page(Language).
-        $this->assertEquals(  "Language", $this->getText( LINK_DIV."h2" ));
+               // Restart warning message displayed
+               $this->assertTrue( $this->isTextPresent( "exact:Do you want to clear all saved data that you have entered and restart the installation process?" ) );
 
-        // 'Welcome to MediaWiki!' page
-        parent::clickContinueButton();
+               // Click on the 'Yes, restart' button
+               $this->click( "submit-restart" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
 
-        // 'Connect to database' page
-        parent::clickContinueButton();
+               // Navigate to the initial installation page(Language).
+               $this->assertEquals( "Language", $this->getText( LINK_DIV . "h2" ) );
 
-        // saved data should be deleted
-        $dbNameAfterRestart = $this->getValue("mysql_wgDBname");
-        $this->assertNotEquals($dbNameBeforeRestart, $dbNameAfterRestart);
-    }
+               // 'Welcome to MediaWiki!' page
+               parent::clickContinueButton();
 
+               // 'Connect to database' page
+               parent::clickContinueButton();
 
-    // Verify cancelling restart
-    public function testCancelRestartInstallation() {
+               // saved data should be deleted
+               $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" );
+               $this->assertNotEquals( $dbNameBeforeRestart, $dbNameAfterRestart );
+       }
 
-        $dbNameBeforeRestart  = DB_NAME_PREFIX."_cancel_restart";
+       // Verify cancelling restart
+       public function testCancelRestartInstallation() {
+               $dbNameBeforeRestart = DB_NAME_PREFIX . "_cancel_restart";
 
-        parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart);
-        // Verify 'Restart installation' link available
-        $this->assertTrue($this->isElementPresent( "link=Restart installation" ));
+               parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart );
+               // Verify 'Restart installation' link available
+               $this->assertTrue( $this->isElementPresent( "link=Restart installation" ) );
 
-        $this->click( "link=Restart installation" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->click( "link=Restart installation" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
 
-        // 'Restart Installation' page displayed
-        $this->assertEquals( "Restart installation", $this->getText( LINK_DIV."h2" ));
+               // 'Restart Installation' page displayed
+               $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) );
 
-        // Restart warning message displayed
-        $this->assertTrue( $this->isTextPresent( "Do you want to clear all saved data that you have entered and restart the installation process?"));
+               // Restart warning message displayed
+               $this->assertTrue( $this->isTextPresent( "Do you want to clear all saved data that you have entered and restart the installation process?" ) );
 
-        // Click on the 'Back' button
-        parent::clickBackButton();
+               // Click on the 'Back' button
+               parent::clickBackButton();
 
-        // Navigates to the previous page
-        $this->assertEquals( "Database settings", $this->getText( LINK_DIV."h2" ));
+               // Navigates to the previous page
+               $this->assertEquals( "Database settings", $this->getText( LINK_DIV . "h2" ) );
 
-        // 'Connect to database' page
-        parent::clickBackButton();
+               // 'Connect to database' page
+               parent::clickBackButton();
 
-        // Saved data remain on the page.
-        $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" );
-        $this->assertEquals( $dbNameBeforeRestart, $dbNameAfterRestart );
-    }
+               // Saved data remain on the page.
+               $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" );
+               $this->assertEquals( $dbNameBeforeRestart, $dbNameAfterRestart );
+       }
 }
index 7b0fcf3..63491c7 100644 (file)
@@ -27,8 +27,7 @@
  *
  */
 
-
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 14, 15, 16, 17 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
@@ -37,57 +36,53 @@ require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
  *                  User selects 'Copying' link.
  *                  User selects 'Upgrading' link.
  * Version        : MediaWiki 1.18alpha
-*/
-
+ */
 
 class MediaWikiRightFrameworkLinksTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-    public function testLinksAvailability() {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // Verify 'Read me' link availability
-        $this->assertTrue($this->isElementPresent( "link=Read me" ));
-
-        // Verify 'Release notes' link availability
-        $this->assertTrue($this->isElementPresent( "link=Release notes" ));
-
-        //  Verify 'Copying' link availability
-        $this->assertTrue($this->isElementPresent( "link=Copying" ));
-    }
-
-    public function testPageNavigation() {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // Navigate to the 'Read me' page
-        $this->click( "link=Read me" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Read me", $this->getText( LINK_DIV."h2[1]" ));
-        $this->assertTrue($this->isElementPresent( "submit-back" ));
-        parent::clickBackButton();
-
-        // Navigate to the 'Release notes' page
-        $this->click( "link=Release notes" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME);
-        $this->assertEquals( "Release notes", $this->getText( LINK_DIV."h2[1]" ));
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        parent::clickBackButton();
-
-        // Navigate to the 'Copying' page
-        $this->click( "link=Copying" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Copying", $this->getText( LINK_DIV."h2[1]" ));
-        $this->assertTrue($this->isElementPresent( "submit-back" ));
-        parent::clickBackButton();
-
-        // Navigate to the 'Upgrading' page
-        $this->click( "link=Upgrading" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Upgrading", $this->getText( LINK_DIV."h2[1]" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       public function testLinksAvailability() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // Verify 'Read me' link availability
+               $this->assertTrue( $this->isElementPresent( "link=Read me" ) );
+
+               // Verify 'Release notes' link availability
+               $this->assertTrue( $this->isElementPresent( "link=Release notes" ) );
+
+               //  Verify 'Copying' link availability
+               $this->assertTrue( $this->isElementPresent( "link=Copying" ) );
+       }
+
+       public function testPageNavigation() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // Navigate to the 'Read me' page
+               $this->click( "link=Read me" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Read me", $this->getText( LINK_DIV . "h2[1]" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               parent::clickBackButton();
+
+               // Navigate to the 'Release notes' page
+               $this->click( "link=Release notes" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Release notes", $this->getText( LINK_DIV . "h2[1]" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               parent::clickBackButton();
+
+               // Navigate to the 'Copying' page
+               $this->click( "link=Copying" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Copying", $this->getText( LINK_DIV . "h2[1]" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               parent::clickBackButton();
+
+               // Navigate to the 'Upgrading' page
+               $this->click( "link=Upgrading" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Upgrading", $this->getText( LINK_DIV . "h2[1]" ) );
+       }
 }
index 5cdc8d4..c20fafe 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 05 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install Mediawiki by updating the existing database.
  * Version        : MediaWiki 1.18alpha
-*/
-
+ */
 
 class MediaWikiUpgradeExistingDatabaseTestCase extends MediaWikiInstallationCommonFunction {
-    
-    function setUp() {
-        parent::setUp();
-    }
-    
-    // Install Mediawiki using 'MySQL' database type.
-    public function testUpgradeExistingDatabase() {
-        
-        $databaseName = DB_NAME_PREFIX."_upgrade_existing";
-        parent::navigateInstallPage( $databaseName );
-        
-        $this->open( "http://localhost:".PORT."/".DIRECTORY_NAME."/config/index.php" );
-        $this->assertEquals( "Install", $this->getText( LINK_DIV."h2" ));
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_DIV."div[2]/form/div[1]/div[2]" ));
-        
-        // 'Optionis' page
-        parent::clickBackButton();
-        
-        // 'Name' page
-        parent::clickBackButton();
-        
-        // 'Database settings' page
-        parent::clickBackButton();
-        
-        // 'Connect to database' page
-        parent::clickBackButton();
-        $this->type( "mysql_wgDBname", $databaseName );
-        parent::clickContinueButton();
-        
-        // 'Upgrade existing installation' page  displayed next to the 'Connect to database' page.
-        $this->assertEquals( "Upgrade existing installation", $this->getText( LINK_DIV."h2" ));
-        
-        // Warning message displayed.
-        $this->assertEquals( "There are MediaWiki tables in this database. To upgrade them to MediaWiki 1.18alpha, click Continue.",
-                $this->getText( LINK_DIV."div[2]/form/div[1]/div[2]" ));
-        
-        parent::clickContinueButton();
-        $this->assertEquals( "Upgrade existing installation",
-                $this->getText( LINK_DIV."h2" ));
-        
-        // 'Upgrade complete.' text display
-        $this->assertEquals("Upgrade complete.",
-                $this->getText("//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[1]"));
-        
-        $this->assertEquals("You can now Folder/index.php start using your wiki.",
-                $this->getText("//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[2]" ));
-        
-        $this->assertEquals( "Folder/index.php start using your wiki",
-                $this->getText( "link=Folder/index.php start using your wiki" ));
-        
-        $this->assertTrue($this->isElementPresent( "submit-regenerate" ));
-        $this->click( "submit-regenerate" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Database settings",
-                $this->getText( LINK_DIV."h2" ));
-        
-        // 'Database settings' page
-        parent::clickContinueButton();
-        
-        // Name page
-        parent::completeNamePage();
-        
-        // Options page
-        parent::clickContinueButton();
-        
-        // Install page
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_FORM."div[1]/div[2]" ));
-        parent::clickContinueButton();
-        
-        // complete
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-        parent::restartInstallation();
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Install Mediawiki using 'MySQL' database type.
+       public function testUpgradeExistingDatabase() {
+
+               $databaseName = DB_NAME_PREFIX . "_upgrade_existing";
+               parent::navigateInstallPage( $databaseName );
+
+               $this->open( "http://localhost:" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+               $this->assertEquals( "Install", $this->getText( LINK_DIV . "h2" ) );
+               $this->assertEquals(
+                       "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_DIV . "div[2]/form/div[1]/div[2]" )
+               );
+
+               // 'Optionis' page
+               parent::clickBackButton();
+
+               // 'Name' page
+               parent::clickBackButton();
+
+               // 'Database settings' page
+               parent::clickBackButton();
+
+               // 'Connect to database' page
+               parent::clickBackButton();
+               $this->type( "mysql_wgDBname", $databaseName );
+               parent::clickContinueButton();
+
+               // 'Upgrade existing installation' page  displayed next to the 'Connect to database' page.
+               $this->assertEquals( "Upgrade existing installation", $this->getText( LINK_DIV . "h2" ) );
+
+               // Warning message displayed.
+               $this->assertEquals( "There are MediaWiki tables in this database. To upgrade them to MediaWiki 1.18alpha, click Continue.",
+                       $this->getText( LINK_DIV . "div[2]/form/div[1]/div[2]" ) );
+
+               parent::clickContinueButton();
+               $this->assertEquals( "Upgrade existing installation",
+                       $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Upgrade complete.' text display
+               $this->assertEquals( "Upgrade complete.",
+                       $this->getText( "//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[1]" ) );
+
+               $this->assertEquals( "You can now Folder/index.php start using your wiki.",
+                       $this->getText( "//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[2]" ) );
+
+               $this->assertEquals( "Folder/index.php start using your wiki",
+                       $this->getText( "link=Folder/index.php start using your wiki" ) );
+
+               $this->assertTrue( $this->isElementPresent( "submit-regenerate" ) );
+               $this->click( "submit-regenerate" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Database settings",
+                       $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Database settings' page
+               parent::clickContinueButton();
+
+               // Name page
+               parent::completeNamePage();
+
+               // Options page
+               parent::clickContinueButton();
+
+               // Install page
+               $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_FORM . "div[1]/div[2]" ) );
+               parent::clickContinueButton();
+
+               // complete
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+               parent::restartInstallation();
+       }
 }
index 15fad95..c73effc 100644 (file)
  *
  */
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 18 - 27 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : UI of MediaWiki initial/ Language/ Welcome to MediaWiki!/ Connect to database/
  * Database settings/ Name/ Options/ Install/ Complete/ Restart Inslation pages
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 
 class MediaWikiUserInterfaceTestCase extends MediaWikiInstallationCommonFunction {
-    
-    function setUp() {
-        parent::setUp();
-    }
-    
-    
-    public function testInitialPageUI() {
-        
-        parent::navigateInitialpage();
-        
-        // MediaWiki logo available
-        $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ));
-        
-        // 'MediaWiki 1.18alpha' text available
-        $this->assertEquals( "MediaWiki 1.18alpha", $this->getText( "//h1" ));
-        
-        // 'LocalSettings.php not found.' text available
-        $this->assertEquals( "LocalSettings.php not found.", $this->getText( "//p[1]" ));
-        
-        // 'Please set up the wiki first' text available
-        $this->assertEquals( "Please set up the wiki first.", $this->getText( "//p[2]" ));
-        
-        // 'set up the wiki' link available
-        $this->assertTrue($this->isElementPresent( "link=set up the wiki" ));
-    }
-    
-    
-    public function testlanguagePageUI() {
-        
-        parent::navigateLanguagePage();
-        
-        // Verify 'Language' heading
-        $this->assertEquals( "Language", $this->getText( LINK_DIV."h2" ));
-        
-        // 'Your language' label available
-        $this->assertEquals( "Your language:",
-                $this->getText( LINK_FORM."div[1]/div[1]/label" ));
-        
-        // 'Your language' dropdown available
-        $this->assertTrue( $this->isElementPresent( "UserLang" ));
-        
-        // 'Wiki language' label available
-        $this->assertEquals( "Wiki language:",
-                $this->getText( LINK_FORM."div[2]/div[1]/label" ));
-        
-        // 'Wiki language' dropdown available
-        $this->assertTrue($this->isElementPresent( "ContLang" ));
-    }
-    
-    
-    public function testWelcometoMediaWikiUI() {
-        
-        parent::navigateWelcometoMediaWikiPage();
-        
-        // Verify 'Welcome to MediaWiki!' heading
-        $this->assertEquals( "Welcome to MediaWiki!",
-                $this->getText( LINK_DIV."h2" ));
-        
-        // Verify environment ok text displayed.
-        $this->assertEquals( "The environment has been checked.You can install MediaWiki.",
-                $this->getText( LINK_DIV."div[6]/span" ));
-    }
-    
-    
-    public function testConnectToDatabaseUI() {
-        
-        parent::navigateConnetToDatabasePage();
-        
-        //  'MYSQL radio button available
-        $this->assertEquals( "MySQL",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[1]/label" ));
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."div[2]/div[2]/ul/li[1]" ));
-        
-        // 'SQLite' radio button available
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."div[2]/div[2]/ul/li[2]" ));
-        $this->assertEquals( "SQLite", $this->getText( LINK_FORM."div[2]/div[2]/ul/li[2]/label "));
-        
-        // 'Database host' label available
-        $this->assertEquals( "Database host:", $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/label" ));
-        
-        // 'Database host' text box default to 'localhost'
-        $this->assertEquals( "localhost", $this->getValue( "mysql_wgDBserver" ));
-        
-        // 'Identify this wiki' section available
-        $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ));
-        
-        // 'Identify this wiki' label available
-        $this->assertEquals( "Identify this wiki", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ));
-        
-        // 'Database name' lable available
-        $this->assertEquals( "Database name:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/label" ));
-        
-        // Verify 'Database name:' text box is default to 'my_wiki'
-        $this->assertEquals( "my_wiki", $this->getValue( "mysql_wgDBname" ));
-        
-        // Verify 'Database table prefix:' label available
-        $this->assertEquals( "Database table prefix:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/label" ));
-        
-        // 'User account for installation' section available
-        $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ));
-        
-        // 'User account for installation' label available
-        $this->assertEquals( "User account for installation", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ));
-        
-        // 'Database username' label available
-        $this->assertEquals( "Database username:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/label" ));
-        
-        // 'Database username' text box defaults to 'root'
-        $this->assertEquals("root", $this->getValue( "mysql__InstallUser" ));
-        
-        // 'Database password' label available
-        $this->assertEquals( "Database password:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/label" ));
-    }
-    
-    
-    
-    public function testDatabaseSettingsUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_db_settings_UI";
-        parent::navigateDatabaseSettingsPage( $databaseName );
-        
-        // 'Database settings' text available.
-        $this->assertEquals( "Database settings", $this->getText( LINK_DIV."h2" ));
-        
-        // 'Database account for web access' section available
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."fieldset" ));
-        
-        // 'Database account for web access' label available
-        $this->assertEquals( "Database account for web access", $this->getText( LINK_FORM."fieldset/legend" ));
-        
-        // 'Use the same account as for installation' check box available
-        $this->assertEquals( "Use the same account as for installation", $this->getText( LINK_FORM."fieldset/div[1]/label" ));
-        
-        // 'Use the same account as for installation' check box is selected by default
-        $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ));
-        
-        // 'Use the same account as for installation' check box deselected
-        $this->click( "mysql__SameAccount" );
-        
-        // verify 'Use the same account as for installation' check box is not selected
-        $this->assertEquals( "off", $this->getValue( "mysql__SameAccount" ));
-        
-        // 'Database username' label available
-        $this->assertEquals( "Database username:", $this->getText( "//div[@id='dbOtherAccount']/div[1]/div[1]/label" ));
-        
-        // 'Database username' text box is default to the 'wikiuser'
-        $this->assertEquals( "wikiuser", $this->getValue( "mysql_wgDBuser" ));
-        
-        // 'Database password' label available
-        $this->assertEquals( "Database password:", $this->getText( "//div[@id='dbOtherAccount']/div[2]/div[1]/label" ));
-        
-        // 'Create the account if it does not already exist' label available
-        $this->assertEquals( "Create the account if it does not already exist", $this->getText( "//div[@id='dbOtherAccount']/div[4]/label" ));
-        
-        // 'Create the account if it does not already exist' check box is not selected by default
-        $this->assertEquals( "off" , $this->getValue( "mysql__CreateDBAccount" ));
-        
-        //  'Create the account if it does not already exist' check box selected
-        $this->click( "mysql__CreateDBAccount" );
-        
-        // Verify  'Create the account if it does not already exist' check box is selected
-        $this->assertEquals( "on" , $this->getValue( "mysql__CreateDBAccount" ));
-        $this->click( "mysql__SameAccount" );
-        $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ));
-        
-        // 'Storage engine' label available
-        $this->assertEquals( "Storage engine:",
-                $this->getText( LINK_FORM."div[1]/div[1]/label"));
-        
-        // 'InnoDB' label available
-        $this->assertEquals( "InnoDB",
-                $this->getText( LINK_FORM."div[1]/div[2]/ul/li[1]/label" ));
-        
-        // 'InnoDB' radio button available
-        $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_InnoDB" ));
-        
-        // 'MyISAM' label available
-        $this->assertEquals( "MyISAM", $this->getText( LINK_FORM."div[1]/div[2]/ul/li[2]/label" ));
-        
-        // 'MyISAM' radio button available
-        $this->assertTrue($this->isElementPresent( "mysql__MysqlEngine_MyISAM" ));
-        
-        // 'Database character set' label available
-        $this->assertEquals( "Database character set:",
-                $this->getText( LINK_FORM."div[3]/div[1]/label" ));
-        
-        // 'Binary' radio button available
-        $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_binary" ));
-        
-        // 'Binary' radio button available
-        $this->assertEquals( "Binary", $this->getText( LINK_FORM."div[3]/div[2]/ul/li[1]/label" ));
-        
-        // 'UTF-8' radio button available
-        $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_utf8" ));
-        
-        // 'UTF-8' label available
-        $this->assertEquals( "UTF-8", $this->getText( LINK_FORM."div[3]/div[2]/ul/li[2]/label" ));
-        
-        // 'Binary' radio button is selected
-        $this->assertEquals( "on", $this->getValue( "mysql__MysqlCharset_binary" ));
-    }
-    
-    
-    
-    public function testNamePageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_name_UI";
-        parent::navigateNamePage($databaseName);
-        
-        // 'Name of wiki' text box available
-        $this->assertEquals( "Name of wiki:",
-                $this->getText( LINK_FORM."div[1]/div[1]/label" ));
-        
-        $this->assertTrue( $this->isElementPresent( "config_wgSitename" ));
-        
-        // 'Project namespace' label available
-        $this->assertEquals( "Project namespace:",
-                $this->getText( LINK_FORM."div[2]/div[1]/label" ));
-        
-        // 'Same as the wiki name' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__NamespaceType_site-name" ));
-        
-        // 'Project' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__NamespaceType_generic" ));
-        
-        // 'Project' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__NamespaceType_other" ));
-        
-        // 'Same as the wiki name' label available
-        $this->assertEquals( "Same as the wiki name:",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[1]/label" ));
-        
-        // 'Project' label available
-        $this->assertEquals("Project",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[2]/label" ));
-        
-        // 'Project' label available
-        $this->assertEquals( "Other (specify)",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[3]/label" ));
-        
-        //  'Same as the wiki name' radio button selected by default
-        $this->assertEquals( "on", $this->getValue( "config__NamespaceType_site-name" ));
-        
-        // 'Administrator account' section available
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."fieldset" ));
-        
-        // 'Administrator account' label available
-        $this->assertEquals( "Administrator account",
-                $this->getText( LINK_FORM."fieldset/legend" ));
-        
-        // 'Your Name' label available
-        $this->assertEquals( "Your name:",
-                $this->getText( LINK_FORM."fieldset/div[1]/div[1]/label" ));
-        
-        // 'Your Name' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminName" ));
-        
-        // 'Password' label available
-        $this->assertEquals( "Password:",
-                $this->getText( LINK_FORM."fieldset/div[2]/div[1]/label" ));
-        
-        // 'Password' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminPassword" ));
-        
-        // 'Password again' label available
-        $this->assertEquals( "Password again:",
-                $this->getText( LINK_FORM."fieldset/div[3]/div[1]/label" ));
-        
-        // 'Password again' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminPassword2" ));
-        
-        // 'Email address' label avaialble
-        $this->assertEquals( "E-mail address:",
-                $this->getText( LINK_FORM."fieldset/div[4]/div[1]/label" ));
-        
-        // 'Email address' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminEmail" ));
-        
-        // Message displayed
-        $this->assertEquals( "You are almost done! You can now skip the remaining configuration and install the wiki right now.",
-                $this->getText( LINK_FORM."/div[4]/div[2]/p" ));
-        
-        // 'Ask me more questions.' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__SkipOptional_continue" ));
-        
-        // 'Ask me more questions.' label available
-        $this->assertEquals( "Ask me more questions.",
-                $this->getText( LINK_FORM."div[5]/div[2]/ul/li[1]/label" ));
-        
-        // 'I'm bored already, just install the wiki' radio button is avaiable
-        $this->assertTrue( $this->isElementPresent( "config__SkipOptional_skip" ));
-        
-        // 'I'm bored already, just install the wiki' label available
-        $this->assertEquals( "I'm bored already, just install the wiki.",
-                $this->getText( LINK_FORM."div[5]/div[2]/ul/li[2]/label" ));
-        
-        //  'Ask me more questions.' radio button is default selected
-        $this->assertEquals( "on", $this->getValue( "config__SkipOptional_continue" ));
-    }
-    
-    
-    
-    public function testOptionPageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_options_UI";
-        parent::navigateOptionsPage($databaseName);
-        
-        // 'Options' label available
-        $this->assertEquals( "Options", $this->getText( LINK_DIV."h2"));
-        
-        // 'Return e-mail address' label available
-        $this->assertEquals( "Return e-mail address:", $this->getText( "//div[@id='emailwrapper']/div[1]/div[1]/label" ));
-        
-        //    'Return e-mail address' text box available
-        $this->assertTrue( $this->isElementPresent( "config_wgPasswordSender" ));
-        
-        // Text 'apache@localhost' is default value of the 'Return e-mail address' text box
-        $this->assertEquals( "apache@localhost", $this->getValue( "config_wgPasswordSender" ));
-        
-        // 'Logo URL' label available
-        $this->assertEquals( "Logo URL:", $this->getText( LINK_FORM."fieldset[2]/div[3]/div[1]/label" ));
-        
-        // 'Logo URL' text box available
-        $this->assertTrue( $this->isElementPresent( "config_wgLogo" ));
-        
-        // Correct path available in the 'Logo URL' text box
-        $this->assertEquals( "/wiki/skins/common/images/wiki.png", $this->getValue( "config_wgLogo" ));
-        
-        // 'Enable file uploads' radio button available
-        $this->assertTrue( $this->isElementPresent( "config_wgEnableUploads" ));
-        
-        // 'Enable file uploads' label available
-        $this->assertEquals( "Enable file uploads",
-                $this->getText( LINK_FORM."fieldset[2]/div[1]/label" ));
-        
-        // 'Enable file uploads' check box is not selected
-        $this->assertEquals( "off", $this->getValue( "config_wgEnableUploads" ));
-        
-        $this->click( "config_wgEnableUploads" );
-        
-        // 'Directory for deleted files' label available
-        $this->assertEquals( "Directory for deleted files:",
-                $this->getText( "//div[@id='uploadwrapper']/div/div[1]/label" ));
-        
-        // 'Directory for deleted files' text box available
-        $this->assertTrue( $this->isElementPresent( "config_wgDeletedDirectory" ));
-        
-        // Correct path available in the 'Directory for deleted files' text box
-        $this->assertEquals( "C:\\wamp\\www\\".DIRECTORY_NAME."/images/deleted",
-                $this->getValue( "config_wgDeletedDirectory" ));
-    }
-    
-    
-    
-    public function testInstallPageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_install_UI";
-        parent::navigateInstallPage( $databaseName );
-        
-        // Verify installation done messages display
-        $this->assertEquals( "Setting up database... done",
-                $this->getText( LINK_FORM."ul/li[1]" ));
-        $this->assertEquals( "Creating tables... done",
-                $this->getText( LINK_FORM."ul/li[2]" ));
-        $this->assertEquals( "Creating database user... done",
-                $this->getText( LINK_FORM."ul/li[3]" ));
-        $this->assertEquals( "Populating default interwiki table... done",
-                $this->getText( LINK_FORM."ul/li[4]" ));
-        $this->assertEquals( "Generating secret key... done",
-                $this->getText( LINK_FORM."ul/li[5]" ));
-        $this->assertEquals( "Generating default upgrade key... done",
-                $this->getText( LINK_FORM."ul/li[6]" ));
-        $this->assertEquals( "Creating administrator user account... done",
-                $this->getText( LINK_FORM."ul/li[7]" ));
-        $this->assertEquals( "Creating main page with default content... done",
-                $this->getText( LINK_FORM."ul/li[8]" ));
-    }
-    
-    
-    
-    public function testCompletePageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_complete_UI";
-        parent::navigateCompletePage( $databaseName );
-        
-        // 'Congratulations!' text display
-        $this->assertEquals("Congratulations!",
-                $this->getText( LINK_FORM."div[1]/div[2]/p[1]/b"));
-        // 'LocalSettings.php' generated message display
-        $this->assertEquals( "The installer has generated a LocalSettings.php file. It contains all your configuration.",
-                $this->getText( LINK_FORM."div[1]/div[2]/p[2]" ));
-        
-        // 'Download LocalSettings.php'' link available
-        $this->assertTrue( $this->isElementPresent( "link=Download LocalSettings.php" ));
-        
-        // 'enter your wiki' link available
-        $this->assertTrue($this->isElementPresent("link=Folder/index.php enter your wiki"));
-    }
-    
-    
-    
-    public function testRestartInstallation() {
-        
-        parent::navigateConnetToDatabasePage();
-        $this->click( "link=Restart installation" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        
-        // Restart installation' label should be available.
-        $this->assertEquals( "Restart installation", $this->getText( LINK_DIV."h2" ));
-        
-        //'Do you want to clear all saved data that you have entered and restart the installation process?' label available
-        $this->assertEquals( "Do you want to clear all saved data that you have entered and restart the installation process?",
-                $this->getText( "//*[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]" ));
-        // 'Back' button available
-        $this->assertTrue($this->isElementPresent( "submit-back" ));
-        
-        // 'Restart' button available
-        $this->assertTrue($this->isElementPresent( "submit-restart" ));
-    }
-    
-    
-    
-    public function testMediaWikiLogoAvailability() {
-        
-        $databaseName = DB_NAME_PREFIX."_mediawiki_logo";
-        parent::navigateInitialpage();
-        parent::mediaWikiLogoPresentInitialScreen();
-        $this->click( "link=set up the wiki" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        
-        // 'Language' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Welcome to MediaWiki' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Connet to database' page
-        parent::mediaWikiLogoPresent();
-        $this->type("mysql_wgDBname", $databaseName );
-        parent::clickContinueButton();
-        
-        // 'Database setting' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Name' page
-        parent::mediaWikiLogoPresent();
-        parent::completeNamePage();
-        parent::clickContinueButton();
-        
-        // 'Options' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Install' page
-        parent::mediaWikiLogoPresent();
-    }
-    
-    
-    public function testRightFramework() {
-        
-        parent::navigateLanguagePage();
-        // Verfy right framework texts display
-        $this->assertEquals( "Language",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[1]" ));
-        $this->assertEquals( "Existing wiki",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[2]" ));
-        $this->assertEquals( "Welcome to MediaWiki!",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[3]" ));
-        $this->assertEquals( "Connect to database",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[4]" ));
-        $this->assertEquals( "Upgrade existing installation",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[5]" ));
-        $this->assertEquals( "Database settings",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[6]" ));
-        $this->assertEquals( "Name",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[7]" ));
-        $this->assertEquals( "Options",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[8]" ));
-        $this->assertEquals( "Install",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[9]" ));
-        $this->assertEquals( "Complete!",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[10]/span" ));
-    } 
+       function setUp() {
+               parent::setUp();
+       }
+
+       public function testInitialPageUI() {
+
+               parent::navigateInitialpage();
+
+               // MediaWiki logo available
+               $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ) );
+
+               // 'MediaWiki 1.18alpha' text available
+               $this->assertEquals( "MediaWiki 1.18alpha", $this->getText( "//h1" ) );
+
+               // 'LocalSettings.php not found.' text available
+               $this->assertEquals( "LocalSettings.php not found.", $this->getText( "//p[1]" ) );
+
+               // 'Please set up the wiki first' text available
+               $this->assertEquals( "Please set up the wiki first.", $this->getText( "//p[2]" ) );
+
+               // 'set up the wiki' link available
+               $this->assertTrue( $this->isElementPresent( "link=set up the wiki" ) );
+       }
+
+       public function testlanguagePageUI() {
+               parent::navigateLanguagePage();
+
+               // Verify 'Language' heading
+               $this->assertEquals( "Language", $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Your language' label available
+               $this->assertEquals( "Your language:",
+                       $this->getText( LINK_FORM . "div[1]/div[1]/label" ) );
+
+               // 'Your language' dropdown available
+               $this->assertTrue( $this->isElementPresent( "UserLang" ) );
+
+               // 'Wiki language' label available
+               $this->assertEquals( "Wiki language:",
+                       $this->getText( LINK_FORM . "div[2]/div[1]/label" ) );
+
+               // 'Wiki language' dropdown available
+               $this->assertTrue( $this->isElementPresent( "ContLang" ) );
+       }
+
+       public function testWelcometoMediaWikiUI() {
+               parent::navigateWelcometoMediaWikiPage();
+
+               // Verify 'Welcome to MediaWiki!' heading
+               $this->assertEquals( "Welcome to MediaWiki!",
+                       $this->getText( LINK_DIV . "h2" ) );
+
+               // Verify environment ok text displayed.
+               $this->assertEquals( "The environment has been checked.You can install MediaWiki.",
+                       $this->getText( LINK_DIV . "div[6]/span" ) );
+       }
+
+       public function testConnectToDatabaseUI() {
+               parent::navigateConnetToDatabasePage();
+
+               //  'MYSQL radio button available
+               $this->assertEquals( "MySQL",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[1]/label" ) );
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "div[2]/div[2]/ul/li[1]" ) );
+
+               // 'SQLite' radio button available
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "div[2]/div[2]/ul/li[2]" ) );
+               $this->assertEquals( "SQLite", $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[2]/label " ) );
+
+               // 'Database host' label available
+               $this->assertEquals( "Database host:", $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/label" ) );
+
+               // 'Database host' text box default to 'localhost'
+               $this->assertEquals( "localhost", $this->getValue( "mysql_wgDBserver" ) );
+
+               // 'Identify this wiki' section available
+               $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ) );
+
+               // 'Identify this wiki' label available
+               $this->assertEquals( "Identify this wiki", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ) );
+
+               // 'Database name' lable available
+               $this->assertEquals( "Database name:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/label" ) );
+
+               // Verify 'Database name:' text box is default to 'my_wiki'
+               $this->assertEquals( "my_wiki", $this->getValue( "mysql_wgDBname" ) );
+
+               // Verify 'Database table prefix:' label available
+               $this->assertEquals( "Database table prefix:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/label" ) );
+
+               // 'User account for installation' section available
+               $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ) );
+
+               // 'User account for installation' label available
+               $this->assertEquals( "User account for installation", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ) );
+
+               // 'Database username' label available
+               $this->assertEquals( "Database username:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/label" ) );
+
+               // 'Database username' text box defaults to 'root'
+               $this->assertEquals( "root", $this->getValue( "mysql__InstallUser" ) );
+
+               // 'Database password' label available
+               $this->assertEquals( "Database password:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/label" ) );
+       }
+
+       public function testDatabaseSettingsUI() {
+               $databaseName = DB_NAME_PREFIX . "_db_settings_UI";
+               parent::navigateDatabaseSettingsPage( $databaseName );
+
+               // 'Database settings' text available.
+               $this->assertEquals( "Database settings", $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Database account for web access' section available
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "fieldset" ) );
+
+               // 'Database account for web access' label available
+               $this->assertEquals( "Database account for web access", $this->getText( LINK_FORM . "fieldset/legend" ) );
+
+               // 'Use the same account as for installation' check box available
+               $this->assertEquals( "Use the same account as for installation", $this->getText( LINK_FORM . "fieldset/div[1]/label" ) );
+
+               // 'Use the same account as for installation' check box is selected by default
+               $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ) );
+
+               // 'Use the same account as for installation' check box deselected
+               $this->click( "mysql__SameAccount" );
+
+               // verify 'Use the same account as for installation' check box is not selected
+               $this->assertEquals( "off", $this->getValue( "mysql__SameAccount" ) );
+
+               // 'Database username' label available
+               $this->assertEquals( "Database username:", $this->getText( "//div[@id='dbOtherAccount']/div[1]/div[1]/label" ) );
+
+               // 'Database username' text box is default to the 'wikiuser'
+               $this->assertEquals( "wikiuser", $this->getValue( "mysql_wgDBuser" ) );
+
+               // 'Database password' label available
+               $this->assertEquals( "Database password:", $this->getText( "//div[@id='dbOtherAccount']/div[2]/div[1]/label" ) );
+
+               // 'Create the account if it does not already exist' label available
+               $this->assertEquals( "Create the account if it does not already exist", $this->getText( "//div[@id='dbOtherAccount']/div[4]/label" ) );
+
+               // 'Create the account if it does not already exist' check box is not selected by default
+               $this->assertEquals( "off", $this->getValue( "mysql__CreateDBAccount" ) );
+
+               //  'Create the account if it does not already exist' check box selected
+               $this->click( "mysql__CreateDBAccount" );
+
+               // Verify  'Create the account if it does not already exist' check box is selected
+               $this->assertEquals( "on", $this->getValue( "mysql__CreateDBAccount" ) );
+               $this->click( "mysql__SameAccount" );
+               $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ) );
+
+               // 'Storage engine' label available
+               $this->assertEquals( "Storage engine:",
+                       $this->getText( LINK_FORM . "div[1]/div[1]/label" ) );
+
+               // 'InnoDB' label available
+               $this->assertEquals( "InnoDB",
+                       $this->getText( LINK_FORM . "div[1]/div[2]/ul/li[1]/label" ) );
+
+               // 'InnoDB' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_InnoDB" ) );
+
+               // 'MyISAM' label available
+               $this->assertEquals( "MyISAM", $this->getText( LINK_FORM . "div[1]/div[2]/ul/li[2]/label" ) );
+
+               // 'MyISAM' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_MyISAM" ) );
+
+               // 'Database character set' label available
+               $this->assertEquals( "Database character set:",
+                       $this->getText( LINK_FORM . "div[3]/div[1]/label" ) );
+
+               // 'Binary' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_binary" ) );
+
+               // 'Binary' radio button available
+               $this->assertEquals( "Binary", $this->getText( LINK_FORM . "div[3]/div[2]/ul/li[1]/label" ) );
+
+               // 'UTF-8' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_utf8" ) );
+
+               // 'UTF-8' label available
+               $this->assertEquals( "UTF-8", $this->getText( LINK_FORM . "div[3]/div[2]/ul/li[2]/label" ) );
+
+               // 'Binary' radio button is selected
+               $this->assertEquals( "on", $this->getValue( "mysql__MysqlCharset_binary" ) );
+       }
+
+       public function testNamePageUI() {
+               $databaseName = DB_NAME_PREFIX . "_name_UI";
+               parent::navigateNamePage( $databaseName );
+
+               // 'Name of wiki' text box available
+               $this->assertEquals( "Name of wiki:",
+                       $this->getText( LINK_FORM . "div[1]/div[1]/label" ) );
+
+               $this->assertTrue( $this->isElementPresent( "config_wgSitename" ) );
+
+               // 'Project namespace' label available
+               $this->assertEquals( "Project namespace:",
+                       $this->getText( LINK_FORM . "div[2]/div[1]/label" ) );
+
+               // 'Same as the wiki name' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__NamespaceType_site-name" ) );
+
+               // 'Project' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__NamespaceType_generic" ) );
+
+               // 'Project' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__NamespaceType_other" ) );
+
+               // 'Same as the wiki name' label available
+               $this->assertEquals( "Same as the wiki name:",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[1]/label" ) );
+
+               // 'Project' label available
+               $this->assertEquals( "Project",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[2]/label" ) );
+
+               // 'Project' label available
+               $this->assertEquals( "Other (specify)",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[3]/label" ) );
+
+               //  'Same as the wiki name' radio button selected by default
+               $this->assertEquals( "on", $this->getValue( "config__NamespaceType_site-name" ) );
+
+               // 'Administrator account' section available
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "fieldset" ) );
+
+               // 'Administrator account' label available
+               $this->assertEquals( "Administrator account",
+                       $this->getText( LINK_FORM . "fieldset/legend" ) );
+
+               // 'Your Name' label available
+               $this->assertEquals( "Your name:",
+                       $this->getText( LINK_FORM . "fieldset/div[1]/div[1]/label" ) );
+
+               // 'Your Name' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminName" ) );
+
+               // 'Password' label available
+               $this->assertEquals( "Password:",
+                       $this->getText( LINK_FORM . "fieldset/div[2]/div[1]/label" ) );
+
+               // 'Password' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminPassword" ) );
+
+               // 'Password again' label available
+               $this->assertEquals( "Password again:",
+                       $this->getText( LINK_FORM . "fieldset/div[3]/div[1]/label" ) );
+
+               // 'Password again' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminPassword2" ) );
+
+               // 'Email address' label avaialble
+               $this->assertEquals( "E-mail address:",
+                       $this->getText( LINK_FORM . "fieldset/div[4]/div[1]/label" ) );
+
+               // 'Email address' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminEmail" ) );
+
+               // Message displayed
+               $this->assertEquals( "You are almost done! You can now skip the remaining configuration and install the wiki right now.",
+                       $this->getText( LINK_FORM . "/div[4]/div[2]/p" ) );
+
+               // 'Ask me more questions.' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__SkipOptional_continue" ) );
+
+               // 'Ask me more questions.' label available
+               $this->assertEquals( "Ask me more questions.",
+                       $this->getText( LINK_FORM . "div[5]/div[2]/ul/li[1]/label" ) );
+
+               // 'I'm bored already, just install the wiki' radio button is avaiable
+               $this->assertTrue( $this->isElementPresent( "config__SkipOptional_skip" ) );
+
+               // 'I'm bored already, just install the wiki' label available
+               $this->assertEquals( "I'm bored already, just install the wiki.",
+                       $this->getText( LINK_FORM . "div[5]/div[2]/ul/li[2]/label" ) );
+
+               //  'Ask me more questions.' radio button is default selected
+               $this->assertEquals( "on", $this->getValue( "config__SkipOptional_continue" ) );
+       }
+
+       public function testOptionPageUI() {
+               $databaseName = DB_NAME_PREFIX . "_options_UI";
+               parent::navigateOptionsPage( $databaseName );
+
+               // 'Options' label available
+               $this->assertEquals( "Options", $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Return e-mail address' label available
+               $this->assertEquals( "Return e-mail address:", $this->getText( "//div[@id='emailwrapper']/div[1]/div[1]/label" ) );
+
+               //    'Return e-mail address' text box available
+               $this->assertTrue( $this->isElementPresent( "config_wgPasswordSender" ) );
+
+               // Text 'apache@localhost' is default value of the 'Return e-mail address' text box
+               $this->assertEquals( "apache@localhost", $this->getValue( "config_wgPasswordSender" ) );
+
+               // 'Logo URL' label available
+               $this->assertEquals( "Logo URL:", $this->getText( LINK_FORM . "fieldset[2]/div[3]/div[1]/label" ) );
+
+               // 'Logo URL' text box available
+               $this->assertTrue( $this->isElementPresent( "config_wgLogo" ) );
+
+               // Correct path available in the 'Logo URL' text box
+               $this->assertEquals( "/wiki/skins/common/images/wiki.png", $this->getValue( "config_wgLogo" ) );
+
+               // 'Enable file uploads' radio button available
+               $this->assertTrue( $this->isElementPresent( "config_wgEnableUploads" ) );
+
+               // 'Enable file uploads' label available
+               $this->assertEquals( "Enable file uploads",
+                       $this->getText( LINK_FORM . "fieldset[2]/div[1]/label" ) );
+
+               // 'Enable file uploads' check box is not selected
+               $this->assertEquals( "off", $this->getValue( "config_wgEnableUploads" ) );
+
+               $this->click( "config_wgEnableUploads" );
+
+               // 'Directory for deleted files' label available
+               $this->assertEquals( "Directory for deleted files:",
+                       $this->getText( "//div[@id='uploadwrapper']/div/div[1]/label" ) );
+
+               // 'Directory for deleted files' text box available
+               $this->assertTrue( $this->isElementPresent( "config_wgDeletedDirectory" ) );
+
+               // Correct path available in the 'Directory for deleted files' text box
+               $this->assertEquals( "C:\\wamp\\www\\" . DIRECTORY_NAME . "/images/deleted",
+                       $this->getValue( "config_wgDeletedDirectory" ) );
+       }
+
+       public function testInstallPageUI() {
+               $databaseName = DB_NAME_PREFIX . "_install_UI";
+               parent::navigateInstallPage( $databaseName );
+
+               // Verify installation done messages display
+               $this->assertEquals( "Setting up database... done",
+                       $this->getText( LINK_FORM . "ul/li[1]" ) );
+               $this->assertEquals( "Creating tables... done",
+                       $this->getText( LINK_FORM . "ul/li[2]" ) );
+               $this->assertEquals( "Creating database user... done",
+                       $this->getText( LINK_FORM . "ul/li[3]" ) );
+               $this->assertEquals( "Populating default interwiki table... done",
+                       $this->getText( LINK_FORM . "ul/li[4]" ) );
+               $this->assertEquals( "Generating secret key... done",
+                       $this->getText( LINK_FORM . "ul/li[5]" ) );
+               $this->assertEquals( "Generating default upgrade key... done",
+                       $this->getText( LINK_FORM . "ul/li[6]" ) );
+               $this->assertEquals( "Creating administrator user account... done",
+                       $this->getText( LINK_FORM . "ul/li[7]" ) );
+               $this->assertEquals( "Creating main page with default content... done",
+                       $this->getText( LINK_FORM . "ul/li[8]" ) );
+       }
+
+       public function testCompletePageUI() {
+               $databaseName = DB_NAME_PREFIX . "_complete_UI";
+               parent::navigateCompletePage( $databaseName );
+
+               // 'Congratulations!' text display
+               $this->assertEquals( "Congratulations!",
+                       $this->getText( LINK_FORM . "div[1]/div[2]/p[1]/b" ) );
+               // 'LocalSettings.php' generated message display
+               $this->assertEquals( "The installer has generated a LocalSettings.php file. It contains all your configuration.",
+                       $this->getText( LINK_FORM . "div[1]/div[2]/p[2]" ) );
+
+               // 'Download LocalSettings.php'' link available
+               $this->assertTrue( $this->isElementPresent( "link=Download LocalSettings.php" ) );
+
+               // 'enter your wiki' link available
+               $this->assertTrue( $this->isElementPresent( "link=Folder/index.php enter your wiki" ) );
+       }
+
+       public function testRestartInstallation() {
+               parent::navigateConnetToDatabasePage();
+               $this->click( "link=Restart installation" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Restart installation' label should be available.
+               $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) );
+
+               //'Do you want to clear all saved data that you have entered and restart the installation process?' label available
+               $this->assertEquals( "Do you want to clear all saved data that you have entered and restart the installation process?",
+                       $this->getText( "//*[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]" ) );
+               // 'Back' button available
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+
+               // 'Restart' button available
+               $this->assertTrue( $this->isElementPresent( "submit-restart" ) );
+       }
+
+       public function testMediaWikiLogoAvailability() {
+               $databaseName = DB_NAME_PREFIX . "_mediawiki_logo";
+               parent::navigateInitialpage();
+               parent::mediaWikiLogoPresentInitialScreen();
+               $this->click( "link=set up the wiki" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Language' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Welcome to MediaWiki' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Connet to database' page
+               parent::mediaWikiLogoPresent();
+               $this->type( "mysql_wgDBname", $databaseName );
+               parent::clickContinueButton();
+
+               // 'Database setting' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Name' page
+               parent::mediaWikiLogoPresent();
+               parent::completeNamePage();
+               parent::clickContinueButton();
+
+               // 'Options' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Install' page
+               parent::mediaWikiLogoPresent();
+       }
+
+       public function testRightFramework() {
+               parent::navigateLanguagePage();
+               // Verfy right framework texts display
+               $this->assertEquals( "Language",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[1]" ) );
+               $this->assertEquals( "Existing wiki",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[2]" ) );
+               $this->assertEquals( "Welcome to MediaWiki!",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[3]" ) );
+               $this->assertEquals( "Connect to database",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[4]" ) );
+               $this->assertEquals( "Upgrade existing installation",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[5]" ) );
+               $this->assertEquals( "Database settings",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[6]" ) );
+               $this->assertEquals( "Name",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[7]" ) );
+               $this->assertEquals( "Options",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[8]" ) );
+               $this->assertEquals( "Install",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[9]" ) );
+               $this->assertEquals( "Complete!",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[10]/span" ) );
+       }
 }
index 72e75e1..a74efc5 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  *
  */
 
-
 class AddContentToNewPageTestCase extends SeleniumTestCase {
-
-  
-    // Add bold text and verify output
-    public function testAddBoldText() {
-
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-bold']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify bold text displayed on mediawiki preview
-        $this->assertTrue($this->isElementPresent( "//div[@id='wikiPreview']/p/b" ));
-        $this->assertTrue($this->isTextPresent( "Bold text" ));
-    }
-
-    // Add italic text and verify output
-    public function testAddItalicText() {
-
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-italic']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify italic text displayed on mediawiki preview
-        $this->assertTrue($this->isElementPresent("//div[@id='wikiPreview']/p/i"));
-        $this->assertTrue($this->isTextPresent( "Italic text" ));
-    }
-
-    // Add internal link for a new page and verify output in the preview
-    public function testAddInternalLinkNewPage() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-link']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify internal link displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
-        $correct = strstr( $source, "Link title" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( SeleniumTestConstants::LINK_START."Link title" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify internal link open as a new page - editing mode
-        $source = $this->getText( "firstHeading" );
-        $correct = strstr( $source, "Editing Link title" );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add external link and verify output in the preview
-    public function testAddExternalLink() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-extlink']" );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, "[http://www.google.com Google]" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify external links displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
-        $correct = strstr( $source, "Google" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( SeleniumTestConstants::LINK_START."Google" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify external link opens
-        $source = $this->getTitle();
-        $correct = strstr( $source, "Google" );
-        $this->assertEquals( $correct, true);
-    }
-
-    // Add level 2 headline and verify output in the preview
-    public function testAddLevel2HeadLine() {
-        $blnElementPresent = false;
-        $blnTextPresent = false;
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "mw-editbutton-headline" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertTrue($this->isElementPresent( "//div[@id='wikiPreview']/h2" ));
-
-        // Verify level 2 headline displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='Headline_text']" );
-        $correct = strstr( $source, "Headline text" );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add text with ignore wiki format and verify output the preview
-    public function testAddNoWikiFormat() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-nowiki']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify ignore wiki format text displayed on mediawiki preview
-        $source = $this->getText( "//div[@id='wikiPreview']/p" );
-        $correct = strstr( $source, "Insert non-formatted text here" );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add signature and verify output in the preview
-    public function testAddUserSignature() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "mw-editbutton-signature" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify signature displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
-        $username = $this->getText( "//*[@id='pt-userpage']/a" );
-        $correct = strstr( $source, $username );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add horizontal line and verify output in the preview
-    public function testHorizontalLine() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "mw-editbutton-hr" );
-
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify horizontal line displayed on mediawiki preview
-        $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/hr" ));
-        $this->deletePage( "new" );
-    }
+       // Add bold text and verify output
+       public function testAddBoldText() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-bold']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify bold text displayed on mediawiki preview
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/p/b" ) );
+               $this->assertTrue( $this->isTextPresent( "Bold text" ) );
+       }
+
+       // Add italic text and verify output
+       public function testAddItalicText() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-italic']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify italic text displayed on mediawiki preview
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/p/i" ) );
+               $this->assertTrue( $this->isTextPresent( "Italic text" ) );
+       }
+
+       // Add internal link for a new page and verify output in the preview
+       public function testAddInternalLinkNewPage() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-link']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify internal link displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
+               $correct = strstr( $source, "Link title" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Link title" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify internal link open as a new page - editing mode
+               $source = $this->getText( "firstHeading" );
+               $correct = strstr( $source, "Editing Link title" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add external link and verify output in the preview
+       public function testAddExternalLink() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-extlink']" );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, "[http://www.google.com Google]" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify external links displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
+               $correct = strstr( $source, "Google" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Google" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify external link opens
+               $source = $this->getTitle();
+               $correct = strstr( $source, "Google" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add level 2 headline and verify output in the preview
+       public function testAddLevel2HeadLine() {
+               $blnElementPresent = false;
+               $blnTextPresent = false;
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "mw-editbutton-headline" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/h2" ) );
+
+               // Verify level 2 headline displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='Headline_text']" );
+               $correct = strstr( $source, "Headline text" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add text with ignore wiki format and verify output the preview
+       public function testAddNoWikiFormat() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-nowiki']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify ignore wiki format text displayed on mediawiki preview
+               $source = $this->getText( "//div[@id='wikiPreview']/p" );
+               $correct = strstr( $source, "Insert non-formatted text here" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add signature and verify output in the preview
+       public function testAddUserSignature() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "mw-editbutton-signature" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify signature displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
+               $username = $this->getText( "//*[@id='pt-userpage']/a" );
+               $correct = strstr( $source, $username );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add horizontal line and verify output in the preview
+       public function testHorizontalLine() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "mw-editbutton-hr" );
+
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify horizontal line displayed on mediawiki preview
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/hr" ) );
+               $this->deletePage( "new" );
+       }
 }
index f3302e5..19dc927 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  *
  */
 
-
 class AddNewPageTestCase extends SeleniumTestCase {
-
-    // Verify adding a new page
-    public function testAddNewPage() {
-        $newPage = "new";
-        $displayName = "New";
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify 'Search results' text available
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr( $source, "Search results" );
-        $this->assertEquals( $correct, true);
-
-        // Verify  'Create the page "<page name>" on this wiki' text available
-        $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
-        $correct = strstr ( $source, "Create the page \"New\" on this wiki!" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( SeleniumTestConstants::LINK_START.$displayName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->assertTrue($this->isElementPresent( SeleniumTestConstants::LINK_START."Create" ));
-        $this->type( "wpTextbox1", "add new test page" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-
-        // Verify new page added
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr ( $source, $displayName );
-        $this->assertEquals( $correct, true );
-    }
+       // Verify adding a new page
+       public function testAddNewPage() {
+               $newPage = "new";
+               $displayName = "New";
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify 'Search results' text available
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Search results" );
+               $this->assertEquals( $correct, true );
+
+               // Verify  'Create the page "<page name>" on this wiki' text available
+               $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
+               $correct = strstr( $source, "Create the page \"New\" on this wiki!" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( SeleniumTestConstants::LINK_START . $displayName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START . "Create" ) );
+               $this->type( "wpTextbox1", "add new test page" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+
+               // Verify new page added
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, $displayName );
+               $this->assertEquals( $correct, true );
+       }
 }
index 5708bcf..e29f2c7 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 Class CreateAccountTestCase extends SeleniumTestCase {
-
-    // Change these values before run the test
-    private $userName = "yourname4000";
-    private $password = "yourpass4000";
-
-    // Verify 'Log in/create account' link existance in Main page.
-    public function testMainPageLink() {
-
-        $this->click( "link=Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-        $this->assertTrue($this->isElementPresent( "link=Log in / create account" ));
-    }
-
-    // Verify 'Create an account' link existance in 'Log in / create account' Page.
-    public function testCreateAccountPageLink() {
-
-        $this->click( "link=Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        // click Log in / create account link to open Log in / create account' page
-        $this->click( "link=Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertTrue($this->isElementPresent( "link=Create an account" ));
-    }
-
-    // Verify Create account
-    public function testCreateAccount() {
-
-        $this->click( "link=Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        $this->click( "link=Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->click( "link=Create an account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify for blank user name
-        $this->type( "wpName2", "" );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n You have not specified a valid user name.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-
-        // Verify for invalid user name
-        $this->type( "wpName2", "@" );
-        $this->click("wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n You have not specified a valid user name.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-
-        // start of test for blank password
-        $this->type( "wpName2", $this->userName);
-        $this->type( "wpPassword2", "" );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n Passwords must be at least 1 character.",
-                $this->getText("//div[@id='bodyContent']/div[4]" ));
-
-        $this->type( "wpName2", $this->userName );
-        $this->type( "wpPassword2", $this->password );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n The passwords you entered do not match.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-
-        $this->type( "wpName2", $this->userName );
-        $this->type( "wpPassword2", $this->password );
-        $this->type( "wpRetype", $this->password );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify successful account creation for valid combination of 'Username', 'Password', 'Retype password'
-        $this->assertEquals( "Welcome, ".ucfirst( $this->userName )."!",
-                $this->getText( "Welcome,_".ucfirst( $this->userName )."!" ));
-    }
+       // Change these values before run the test
+       private $userName = "yourname4000";
+       private $password = "yourpass4000";
+
+       // Verify 'Log in/create account' link existance in Main page.
+       public function testMainPageLink() {
+
+               $this->click( "link=Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+               $this->assertTrue( $this->isElementPresent( "link=Log in / create account" ) );
+       }
+
+       // Verify 'Create an account' link existance in 'Log in / create account' Page.
+       public function testCreateAccountPageLink() {
+
+               $this->click( "link=Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               // click Log in / create account link to open Log in / create account' page
+               $this->click( "link=Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertTrue( $this->isElementPresent( "link=Create an account" ) );
+       }
+
+       // Verify Create account
+       public function testCreateAccount() {
+
+               $this->click( "link=Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               $this->click( "link=Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->click( "link=Create an account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify for blank user name
+               $this->type( "wpName2", "" );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n You have not specified a valid user name.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               // Verify for invalid user name
+               $this->type( "wpName2", "@" );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n You have not specified a valid user name.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               // start of test for blank password
+               $this->type( "wpName2", $this->userName );
+               $this->type( "wpPassword2", "" );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n Passwords must be at least 1 character.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName2", $this->userName );
+               $this->type( "wpPassword2", $this->password );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n The passwords you entered do not match.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName2", $this->userName );
+               $this->type( "wpPassword2", $this->password );
+               $this->type( "wpRetype", $this->password );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify successful account creation for valid combination of 'Username', 'Password', 'Retype password'
+               $this->assertEquals( "Welcome, " . ucfirst( $this->userName ) . "!",
+                       $this->getText( "Welcome,_" . ucfirst( $this->userName ) . "!" ) );
+       }
 }
 
index 9898188..eb25f8b 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  *
  */
 
-
 class DeletePageAdminTestCase extends SeleniumTestCase {
+       // Verify adding a new page
+       public function testDeletePage() {
 
-    // Verify adding a new page
-    public function testDeletePage() {
-
-       
-        $newPage = "new";
-        $displayName = "New";
+               $newPage = "new";
+               $displayName = "New";
 
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
 
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_START.$displayName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage." text" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . $displayName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
 
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_START."Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        $this->type( "wpName1", $this->selenium->getUser() );
-        $this->type( "wpPassword1", $this->selenium->getPass() );
-        $this->click( "wpLoginAttempt" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( "searchInput", "new" );
-        $this->click( "searchGoButton");
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( "wpName1", $this->selenium->getUser() );
+               $this->type( "wpPassword1", $this->selenium->getPass() );
+               $this->click( "wpLoginAttempt" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( "searchInput", "new" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify  'Delete' link displayed
-        $source = $this->gettext( SeleniumTestConstants::LINK_START."Delete" );
-        $correct = strstr ( $source, "Delete" );
-        $this->assertEquals($correct, true );
+               // Verify  'Delete' link displayed
+               $source = $this->gettext( SeleniumTestConstants::LINK_START . "Delete" );
+               $correct = strstr( $source, "Delete" );
+               $this->assertEquals( $correct, true );
 
-        $this->click( SeleniumTestConstants::LINK_START."Delete" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . "Delete" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify 'Delete' button available
-        $this->assertTrue($this->isElementPresent( "wpConfirmB" ));
+               // Verify 'Delete' button available
+               $this->assertTrue( $this->isElementPresent( "wpConfirmB" ) );
 
-        $this->click( "wpConfirmB" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "wpConfirmB" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify  'Action complete' text displayed
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr ( $source, "Action complete" );
-        $this->assertEquals( $correct, true );
+               // Verify  'Action complete' text displayed
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Action complete" );
+               $this->assertEquals( $correct, true );
 
-        // Verify  '<Page Name> has been deleted. See deletion log for a record of recent deletions.' text displayed
-        $source = $this->gettext( "//div[@id='bodyContent']/p[1]" );
-        $correct = strstr ( $source, "\"New\" has been deleted. See deletion log for a record of recent deletions." );
-        $this->assertEquals( $correct, true );
-    }
+               // Verify  '<Page Name> has been deleted. See deletion log for a record of recent deletions.' text displayed
+               $source = $this->gettext( "//div[@id='bodyContent']/p[1]" );
+               $correct = strstr( $source, "\"New\" has been deleted. See deletion log for a record of recent deletions." );
+               $this->assertEquals( $correct, true );
+       }
 }
index 88d9cf9..81310b1 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 class EmailPasswordTestCase extends SeleniumTestCase {
-
-    // change user name for each and every test (with in 24 hours)
-    private $userName = "test1";
-
-    public function testEmailPasswordButton() {
-
-        $this->click( SeleniumTestConstants::LINK_START."Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        // click Log in / create account link to open Log in / create account' page
-        $this->click( SeleniumTestConstants::LINK_START."Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertTrue($this->isElementPresent( "wpMailmypassword" ));
-    }
-
-    // Verify Email password functionality
-    public function testEmailPasswordMessages() {
-
-        $this->click( SeleniumTestConstants::LINK_START."Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        // click Log in / create account link to open Log in / create account' page
-        $this->click( SeleniumTestConstants::LINK_START."Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpName1", "" );
-        $this->click( "wpMailmypassword" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n You have not specified a valid user name.",
-                $this->getText("//div[@id='bodyContent']/div[4]"));
-
-        $this->type( "wpName1", $this->userName );
-        $this->click( "wpMailmypassword" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        //  Can not run on localhost
-        $this->assertEquals( "A new password has been sent to the e-mail address registered for ".ucfirst($this->userName).". Please log in again after you receive it.",
-                $this->getText("//div[@id='bodyContent']/div[4]" ));
-
-        $this->type( "wpName1", $this->userName );
-        $this->click( "wpMailmypassword" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n A password reminder has already been sent, within the last 24 hours. To prevent abuse, only one password reminder will be sent per 24 hours.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-    }
+       // change user name for each and every test (with in 24 hours)
+       private $userName = "test1";
+
+       public function testEmailPasswordButton() {
+               $this->click( SeleniumTestConstants::LINK_START . "Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               // click Log in / create account link to open Log in / create account' page
+               $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertTrue( $this->isElementPresent( "wpMailmypassword" ) );
+       }
+
+       // Verify Email password functionality
+       public function testEmailPasswordMessages() {
+               $this->click( SeleniumTestConstants::LINK_START . "Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               // click Log in / create account link to open Log in / create account' page
+               $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpName1", "" );
+               $this->click( "wpMailmypassword" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n You have not specified a valid user name.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName1", $this->userName );
+               $this->click( "wpMailmypassword" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               //  Can not run on localhost
+               $this->assertEquals( "A new password has been sent to the e-mail address registered for " . ucfirst( $this->userName ) . ". Please log in again after you receive it.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName1", $this->userName );
+               $this->click( "wpMailmypassword" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n A password reminder has already been sent, within the last 24 hours. To prevent abuse, only one password reminder will be sent per 24 hours.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+       }
 }
 
index 072c3cb..aeb2315 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 class MediaWikiEditorConfig {
-
-    public static function getSettings(&$includeFiles, &$globalConfigs) {
-        $includes = array(
-                //files that needed to be included would go here
-                //commenting out because this does not exist
-                //'tests/selenium/suites/MediaWikiCommonFunction.php'
-        );
-        $configs = array(
-                'wgPageLoadTime' => "600000"
-        );
-        $includeFiles = array_merge( $includeFiles, $includes );
-        $globalConfigs = array_merge( $globalConfigs, $configs);
-        return true;
-    }
+       public static function getSettings( &$includeFiles, &$globalConfigs ) {
+               $includes = array(
+                       //files that needed to be included would go here
+                       //commenting out because this does not exist
+                       //'tests/selenium/suites/MediaWikiCommonFunction.php'
+               );
+               $configs = array(
+                       'wgPageLoadTime' => "600000"
+               );
+               $includeFiles = array_merge( $includeFiles, $includes );
+               $globalConfigs = array_merge( $globalConfigs, $configs );
+               return true;
+       }
 }
 
-
-
index c0aee9f..f9cfb7f 100644 (file)
@@ -1,18 +1,19 @@
 <?php
 
 class MediaWikiEditorTestSuite extends SeleniumTestSuite {
-    public function setUp() {
-        $this->setLoginBeforeTests( true );
-        parent::setUp();
-    }
-    public function addTests() {
-        $testFiles = array(
-                'tests/selenium/suites/AddNewPageTestCase.php',
-                'tests/selenium/suites/AddContentToNewPageTestCase.php',
-                'tests/selenium/suites/PreviewPageTestCase.php',
-                'tests/selenium/suites/SavePageTestCase.php',
-        );
-        parent::addTestFiles( $testFiles );
-    }
+       public function setUp() {
+               $this->setLoginBeforeTests( true );
+               parent::setUp();
+       }
+
+       public function addTests() {
+               $testFiles = array(
+                       'tests/selenium/suites/AddNewPageTestCase.php',
+                       'tests/selenium/suites/AddContentToNewPageTestCase.php',
+                       'tests/selenium/suites/PreviewPageTestCase.php',
+                       'tests/selenium/suites/SavePageTestCase.php',
+               );
+               parent::addTestFiles( $testFiles );
+       }
 }
 
index 5cd0a34..8993907 100644 (file)
@@ -5,6 +5,7 @@ class MediaWikiExtraTestSuite extends SeleniumTestSuite {
                $this->setLoginBeforeTests( true );
                parent::setUp();
        }
+
        public function addTests() {
                $testFiles = array(
                        'tests/selenium/suites/MyContributionsTestCase.php',
index 6b8fc97..4491afd 100644 (file)
@@ -50,7 +50,8 @@ class MediawikiCoreSmokeTestCase extends SeleniumTestCase {
                $this->waitForPageToLoad( 30000 );
 
                $this->assertSeleniumHTMLContains(
-                               '//h1[@class="firstHeading"]', "Wikipedia-logo-v2-de.png" );
+                       '//h1[@class="firstHeading"]', "Wikipedia-logo-v2-de.png"
+               );
 
                /*
                $this->open( $this->getUrl() . '/index.php?title=Image:'
index a9a9b4d..fc69e3c 100644 (file)
@@ -2,12 +2,12 @@
 /**
  * Stubs for now. We're going to start populating this test.
  */
-class MediawikiCoreSmokeTestSuite extends SeleniumTestSuite
-{
+class MediawikiCoreSmokeTestSuite extends SeleniumTestSuite {
        public function setUp() {
                $this->setLoginBeforeTests( false );
                parent::setUp();
-       } 
+       }
+
        public function addTests() {
                $testFiles = array(
                        'tests/selenium/suites/MediawikiCoreSmokeTestCase.php'
index 5263e7b..3964dc1 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 class MovePageTestCase extends SeleniumTestCase {
-
-    // Verify move(rename) wiki page
-    public function testMovePage() {
-
-        $newPage = "mypage99";
-        $displayName = "Mypage99";
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( "link=".$displayName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage." text" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify link 'Move' available
-        $this->assertTrue($this->isElementPresent( "link=Move" ));
-
-        $this->click( "link=Move" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify correct page name displayed under 'Move Page' field
-        $this->assertEquals($displayName,
-                $this->getText("//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a"));
-        $movePageName = $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" );
-
-        // Verify 'To new title' field has current page name as the default name
-        $newTitle =  $this->getValue( "wpNewTitle" );
-        $correct = strstr( $movePageName , $newTitle  );
-        $this->assertEquals( $correct, true );
-
-        $this->type( "wpNewTitle", $displayName );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify warning message for the same source and destination titles
-        $this->assertEquals( "Source and destination titles are the same; cannot move a page over itself.",
-                $this->getText("//div[@id='bodyContent']/p[4]/strong" ));
-
-        // Verify warning message for the blank title
-        $this->type( "wpNewTitle", "" );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify warning message for the blank title
-        $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
-                $this->getText( "//div[@id='bodyContent']/p[4]/strong" ));
-
-        //  Verify warning messages for the invalid titles
-        $this->type( "wpNewTitle", "# < > [ ] | { }" );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
-                $this->getText( "//div[@id='bodyContent']/p[4]/strong" ));
-
-        $this->type( "wpNewTitle", $displayName."move" );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify move success message displayed correctly
-        $this->assertEquals( "\"".$displayName."\" has been moved to \"".$displayName."move"."\"",
-                $this->getText( "//div[@id='bodyContent']/p[1]/b" ));
-
-        $this->type( "searchInput", $newPage."move" );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify search using new page name
-        $this->assertEquals( $displayName."move", $this->getText( "firstHeading" ));
-
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify search using old page name
-        $redirectPageName = $this->getText( "//*[@id='contentSub']" );
-        $this->assertEquals( "(Redirected from ".$displayName.")" , $redirectPageName );
-
-        // newpage delete
-        $this->deletePage( $newPage."move" );
-        $this->deletePage( $newPage );
-    }
+       // Verify move(rename) wiki page
+       public function testMovePage() {
+               $newPage = "mypage99";
+               $displayName = "Mypage99";
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "link=" . $displayName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify link 'Move' available
+               $this->assertTrue( $this->isElementPresent( "link=Move" ) );
+
+               $this->click( "link=Move" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify correct page name displayed under 'Move Page' field
+               $this->assertEquals( $displayName,
+                       $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" ) );
+               $movePageName = $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" );
+
+               // Verify 'To new title' field has current page name as the default name
+               $newTitle = $this->getValue( "wpNewTitle" );
+               $correct = strstr( $movePageName, $newTitle );
+               $this->assertEquals( $correct, true );
+
+               $this->type( "wpNewTitle", $displayName );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify warning message for the same source and destination titles
+               $this->assertEquals( "Source and destination titles are the same; cannot move a page over itself.",
+                       $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) );
+
+               // Verify warning message for the blank title
+               $this->type( "wpNewTitle", "" );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify warning message for the blank title
+               $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
+                       $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) );
+
+               //  Verify warning messages for the invalid titles
+               $this->type( "wpNewTitle", "# < > [ ] | { }" );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
+                       $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) );
+
+               $this->type( "wpNewTitle", $displayName . "move" );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify move success message displayed correctly
+               $this->assertEquals( "\"" . $displayName . "\" has been moved to \"" . $displayName . "move" . "\"",
+                       $this->getText( "//div[@id='bodyContent']/p[1]/b" ) );
+
+               $this->type( "searchInput", $newPage . "move" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify search using new page name
+               $this->assertEquals( $displayName . "move", $this->getText( "firstHeading" ) );
+
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify search using old page name
+               $redirectPageName = $this->getText( "//*[@id='contentSub']" );
+               $this->assertEquals( "(Redirected from " . $displayName . ")", $redirectPageName );
+
+               // newpage delete
+               $this->deletePage( $newPage . "move" );
+               $this->deletePage( $newPage );
+       }
 }
 
index b8d2d48..730323d 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
 require_once dirname( __DIR__ ) . '/SeleniumTestConstants.php';
 
 class MyContributionsTestCase extends SeleniumTestCase {
+       // Verify user contributions
+       public function testRecentChangesAvailability() {
+               $newPage = $this->createNewTestPage( "MyContributionsTest" );
 
-    // Verify user contributions
-    public function testRecentChangesAvailability() {
+               // Verify My contributions Link available
+               $this->assertTrue( $this->isElementPresent( "link=Contributions" ) );
 
-        $newPage = $this->createNewTestPage( "MyContributionsTest" );
-        
-        // Verify My contributions Link available
-        $this->assertTrue($this->isElementPresent( "link=Contributions" ));
 
-        
-        $this->click( "link=Contributions" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "link=Contributions" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify recent page adding available on My Contributions list
-        $this->assertEquals( $newPage, $this->getText( "link=".$newPage ));
+               // Verify recent page adding available on My Contributions list
+               $this->assertEquals( $newPage, $this->getText( "link=" . $newPage ) );
 
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $newPage );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        
-        $this->click( SeleniumTestConstants::LINK_EDIT );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text changed" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( "link=Contributions" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $newPage );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify recent page changes available on My Contributions
-        $this->assertTrue( $this->isTextPresent( $newPage ) );
-    }
+               $this->click( SeleniumTestConstants::LINK_EDIT );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text changed" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "link=Contributions" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify recent page changes available on My Contributions
+               $this->assertTrue( $this->isTextPresent( $newPage ) );
+       }
 }
 
index 998fab9..bc7c768 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
 require_once dirname( __DIR__ ) . '/SeleniumTestConstants.php';
 
 class MyWatchListTestCase extends SeleniumTestCase {
-
-    // Verify user watchlist
-    public function testMyWatchlist() {
-
-        $pageName = $this->createNewTestPage( "MyWatchListTest", true );
-        // Verify link 'My Watchlist' available
-        $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START."Watchlist" ) );
-
-        $this->click( SeleniumTestConstants::LINK_START."Watchlist" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify newly added page to the watchlist is available
-        $this->assertEquals( $pageName, $this->getText( SeleniumTestConstants::LINK_START.$pageName ));
-
-        $this->click( SeleniumTestConstants::LINK_START.$pageName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_EDIT );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( "wpWatchthis" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->assertFalse( $this->isElementPresent( SeleniumTestConstants::LINK_START.$pageName ) );
-        //todo watch using the dropdown menu
-    }
+       // Verify user watchlist
+       public function testMyWatchlist() {
+               $pageName = $this->createNewTestPage( "MyWatchListTest", true );
+               // Verify link 'My Watchlist' available
+               $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START . "Watchlist" ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Watchlist" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify newly added page to the watchlist is available
+               $this->assertEquals( $pageName, $this->getText( SeleniumTestConstants::LINK_START . $pageName ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . $pageName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_EDIT );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "wpWatchthis" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->assertFalse( $this->isElementPresent( SeleniumTestConstants::LINK_START . $pageName ) );
+               //todo watch using the dropdown menu
+       }
 }
 
index 256e354..e43ffa8 100644 (file)
@@ -1,16 +1,15 @@
 <?php
 
 class PageDeleteTestSuite extends SeleniumTestSuite {
-    public function setUp() {
-        $this->setLoginBeforeTests( true );
-        parent::setUp();
-    }
-    public function addTests() {
-        $testFiles = array(
-                'tests/selenium/suites/DeletePageAdminTestCase.php'
-        );
-        parent::addTestFiles( $testFiles );
-    }
-
+       public function setUp() {
+               $this->setLoginBeforeTests( true );
+               parent::setUp();
+       }
 
+       public function addTests() {
+               $testFiles = array(
+                       'tests/selenium/suites/DeletePageAdminTestCase.php'
+               );
+               parent::addTestFiles( $testFiles );
+       }
 }
index fe71ead..bde1b57 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 class PageSearchTestCase extends SeleniumTestCase {
-
-    // Verify the functionality of the 'Go' button
-    public function testPageSearchBtnGo() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "calcey qa" );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify  no page matched with the entered search text
-        $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
-        $correct = strstr ( $source, "Create the page \"Calcey qa\" on this wiki!" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( "link=Calcey qa" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( SeleniumTestConstants::TEXT_EDITOR , "Calcey QA team" );
-        $this->click( "wpSave" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-    }
-
-    // Verify the functionality of the 'Search' button
-    public function testPageSearchBtnSearch() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify  no page is available as the search text
-        $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p[2]/b" );
-        $correct = strstr ( $source, "Create the page \"Calcey web\" on this wiki!" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( "link=Calcey web" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey web team" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify saved page is opened  when the exact page name is given
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify exact page matched with the entered search text using 'Search' button
-        $source = $this->getText( "//*[@id='bodyContent']/div[4]/p/b" );
-        $correct = strstr( $source, "There is a page named \"Calcey web\" on this wiki." );
-        $this->assertEquals( $correct, true );
-
-        // Verify resutls available when partial page name is entered as the search text
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey" );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        //  Verify text avaialble in the search result under the page titles
-        if($this->isElementPresent( "Page_title_matches" )) {
-            $textPageTitle = $this->getText( "//*[@id='bodyContent']/div[4]/ul[1]/li[1]/div[1]/a" );
-            $this->assertContains( 'Calcey', $textPageTitle );
-        }
-
-        //  Verify text avaialble in the search result under the page text
-        if($this->isElementPresent( "Page_text_matches" )) {
-            $textPageText = $this->getText( "//*[@id='bodyContent']/div[4]/ul[2]/li[2]/div[2]/span" );
-            $this->assertContains( 'Calcey', $textPageText );
-        }
-        $this->deletePage("Calcey QA");
-        $this->deletePage("Calcey web");
-    }
+       // Verify the functionality of the 'Go' button
+       public function testPageSearchBtnGo() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "calcey qa" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify  no page matched with the entered search text
+               $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
+               $correct = strstr( $source, "Create the page \"Calcey qa\" on this wiki!" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( "link=Calcey qa" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey QA team" );
+               $this->click( "wpSave" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify the functionality of the 'Search' button
+       public function testPageSearchBtnSearch() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify  no page is available as the search text
+               $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p[2]/b" );
+               $correct = strstr( $source, "Create the page \"Calcey web\" on this wiki!" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( "link=Calcey web" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey web team" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify saved page is opened  when the exact page name is given
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify exact page matched with the entered search text using 'Search' button
+               $source = $this->getText( "//*[@id='bodyContent']/div[4]/p/b" );
+               $correct = strstr( $source, "There is a page named \"Calcey web\" on this wiki." );
+               $this->assertEquals( $correct, true );
+
+               // Verify resutls available when partial page name is entered as the search text
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey" );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               //  Verify text avaialble in the search result under the page titles
+               if ( $this->isElementPresent( "Page_title_matches" ) ) {
+                       $textPageTitle = $this->getText( "//*[@id='bodyContent']/div[4]/ul[1]/li[1]/div[1]/a" );
+                       $this->assertContains( 'Calcey', $textPageTitle );
+               }
+
+               //  Verify text avaialble in the search result under the page text
+               if ( $this->isElementPresent( "Page_text_matches" ) ) {
+                       $textPageText = $this->getText( "//*[@id='bodyContent']/div[4]/ul[2]/li[2]/div[2]/span" );
+                       $this->assertContains( 'Calcey', $textPageText );
+               }
+               $this->deletePage( "Calcey QA" );
+               $this->deletePage( "Calcey web" );
+       }
 }
index 32206b9..615c23c 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 class PreviewPageTestCase extends SeleniumTestCase {
+       // Verify adding a new page
+       public function testPreviewPage() {
+               $wikiText = "Adding this page to test the \n Preview button functionality";
+               $newPage = "Test Preview Page";
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->getNewPage( $newPage );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText . "" );
+               $this->assertTrue( $this->isElementPresent( "//*[@id='wpPreview']" ) );
 
-    // Verify adding a new page
-    public function testPreviewPage() {
-        $wikiText = "Adding this page to test the \n Preview button functionality";
-        $newPage =  "Test Preview Page";
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->getNewPage( $newPage );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText."" );
-        $this->assertTrue($this->isElementPresent( "//*[@id='wpPreview']" ));
+               $this->click( "wpPreview" );
 
-        $this->click( "wpPreview" );
+               // Verify saved page available
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Test Preview Page" );
+               $this->assertEquals( $correct, true );
 
-        // Verify saved page available
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr( $source, "Test Preview Page" );
-        $this->assertEquals( $correct, true);
-
-        // Verify page content previewed succesfully
-        $contentOfPreviewPage = $this->getText( "//*[@id='content']" );
-        $this->assertContains( $wikiText, $contentOfPreviewPage  );
-    }
+               // Verify page content previewed succesfully
+               $contentOfPreviewPage = $this->getText( "//*[@id='content']" );
+               $this->assertContains( $wikiText, $contentOfPreviewPage );
+       }
 }
index 310ff20..80eacc5 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 class SavePageTestCase extends SeleniumTestCase {
-
-    // Verify adding a new page
-    public function testSavePage() {
-        $wikiText = "Adding this page to test the Save button functionality";
-        $newPage = "Test Save Page";
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->getNewPage($newPage);
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText );
-
-        // verify 'Save' button available
-        $this->assertTrue($this->isElementPresent( SeleniumTestConstants::BUTTON_SAVE ));
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-
-        // Verify saved page available
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr( $source, "Test Save Page" );
-
-        // Verify Saved page name displayed correctly
-        $this->assertEquals( $correct, true );
-
-        // Verify page content saved succesfully
-        $contentOfSavedPage = $this->getText( "//*[@id='content']" );
-        $this->assertContains( $wikiText, $contentOfSavedPage  );
-        $this->deletePage( $newPage );
-    }
+       // Verify adding a new page
+       public function testSavePage() {
+               $wikiText = "Adding this page to test the Save button functionality";
+               $newPage = "Test Save Page";
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->getNewPage( $newPage );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText );
+
+               // verify 'Save' button available
+               $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::BUTTON_SAVE ) );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+
+               // Verify saved page available
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Test Save Page" );
+
+               // Verify Saved page name displayed correctly
+               $this->assertEquals( $correct, true );
+
+               // Verify page content saved succesfully
+               $contentOfSavedPage = $this->getText( "//*[@id='content']" );
+               $this->assertContains( $wikiText, $contentOfSavedPage );
+               $this->deletePage( $newPage );
+       }
 }
index 54def35..a693511 100644 (file)
@@ -1,30 +1,30 @@
 <?php
 class SimpleSeleniumConfig {
-       
-       public static function getSettings(&$includeFiles, &$globalConfigs, &$resourceFiles) {
+
+       public static function getSettings( &$includeFiles, &$globalConfigs, &$resourceFiles ) {
                global $IP;
                $includes = array(
                        //files that needed to be included would go here
                );
                $configs = array(
-                       'wgDBprefix'        => 'mw_',
-                       'wgDBTableOptions'  => 'ENGINE=InnoDB, DEFAULT CHARSET=binary',
-                       'wgDBmysql5'        => 'false',
-                       'wgMainCacheType'   => 'CACHE_NONE',
+                       'wgDBprefix' => 'mw_',
+                       'wgDBTableOptions' => 'ENGINE=InnoDB, DEFAULT CHARSET=binary',
+                       'wgDBmysql5' => 'false',
+                       'wgMainCacheType' => 'CACHE_NONE',
                        'wgParserCacheType' => 'CACHE_NONE',
-                       'wgMemCachedServers'=> array(),
-                       'wgLanguageCode'    => 'en',
-                       'wgSitename'        => 'test_wiki',
-                       'wgDefaultSkin'     => 'chick'
+                       'wgMemCachedServers' => array(),
+                       'wgLanguageCode' => 'en',
+                       'wgSitename' => 'test_wiki',
+                       'wgDefaultSkin' => 'chick'
                );
                $resources = array(
                        'db' => "$IP/tests/selenium/data/SimpleSeleniumTestDB.sql",
                        'images' => "$IP/tests/selenium/data/SimpleSeleniumTestImages.zip"
                );
-               
+
                $includeFiles = array_merge( $includeFiles, $includes );
-               $globalConfigs = array_merge( $globalConfigs, $configs);
+               $globalConfigs = array_merge( $globalConfigs, $configs );
                $resourceFiles = array_merge( $resourceFiles, $resources );
-               return true; 
+               return true;
        }
-}
\ No newline at end of file
+}
index b87172e..14c9e6b 100644 (file)
@@ -24,7 +24,7 @@ class SimpleSeleniumTestCase extends SeleniumTestCase {
        public function testGlobalVariableForDefaultSkin() {
                $this->open( $this->getUrl() . '/index.php' );
                $bodyClass = $this->getAttribute( "//body/@class" );
-               $this-> assertContains('skin-chick', $bodyClass, 'Chick skin not set');
+               $this->assertContains( 'skin-chick', $bodyClass, 'Chick skin not set' );
        }
 
        /**
@@ -33,7 +33,7 @@ class SimpleSeleniumTestCase extends SeleniumTestCase {
        public function testDatabaseResourceLoadedCorrectly() {
                $this->open( $this->getUrl() . '/index.php/TestResources?action=purge' );
                $testString = $this->gettext( "//body//*[@id='firstHeading']" );
-               $this-> assertEquals('TestResources', $testString, 'Article that should be present in the test db was not found.');
+               $this->assertEquals( 'TestResources', $testString, 'Article that should be present in the test db was not found.' );
        }
 
 }
index 2e0c4ee..446836a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Sample test suite. 
+ * Sample test suite.
  * Two ways to configure MW for these tests
  * 1) If you are running multiple test suites, add the following in LocalSettings.php
  * require_once("tests/selenium/SimpleSeleniumConfig.php");
@@ -9,12 +9,12 @@
  * 2) Add the following to your Localsettings.php
  * $wgDefaultSkin = 'chick';
  */
-class SimpleSeleniumTestSuite extends SeleniumTestSuite
-{
+class SimpleSeleniumTestSuite extends SeleniumTestSuite {
        public function setUp() {
                $this->setLoginBeforeTests( false );
                parent::setUp();
-       } 
+       }
+
        public function addTests() {
                $testFiles = array(
                        'selenium/suites/SimpleSeleniumTestCase.php'
index 3ceb3a9..a68ea97 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.com/
  *
  * 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
  */
 
 class UserPreferencesTestCase extends SeleniumTestCase {
-
-    // Verify user information
-    public function testUserInfoDisplay() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify correct username displayed in User Preferences
-        $this->assertEquals( $this->getText( "//li[@id='pt-userpage']/a" ),
-                $this->getText( "//table[@id='mw-htmlform-info']/tbody/tr[1]/td[2]" ));
-
-        // Verify existing Signature Displayed correctly
-        $this->assertEquals( $this->selenium->getUser(),
-                $this->getTable( "mw-htmlform-signature.0.1" ) );
-    }
-
-    // Verify change password
-    public function testChangePassword() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->click( SeleniumTestConstants::LINK_START."Change password" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpPassword", "12345" );
-        $this->type( "wpNewPassword", "54321" );
-        $this->type( "wpRetype", "54321" );
-        $this->click( "//input[@value='Change password']" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->assertEquals( "Preferences", $this->getText( "firstHeading" ));
-
-        $this->click( SeleniumTestConstants::LINK_START."Change password" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpPassword", "54321" );
-        $this->type( "wpNewPassword", "12345" );
-        $this->type( "wpRetype", "12345" );
-        $this->click( "//input[@value='Change password']" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Preferences", $this->getText( "firstHeading" ));
-
-        $this->click( SeleniumTestConstants::LINK_START."Change password" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpPassword", "54321" );
-        $this->type( "wpNewPassword", "12345" );
-        $this->type( "wpRetype", "12345" );
-        $this->click( "//input[@value='Change password']" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-    }
-
-    // Verify successful preferences save
-    public function testSuccessfullSave() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "mw-input-realname", "Test User" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify  "Your preferences have been saved." message
-        $this->assertEquals( "Your preferences have been saved.",
-                $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ));
-        $this->type( "mw-input-realname", "" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-    }
-
-    // Verify change signature
-    public function testChangeSignature() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "mw-input-nickname", "TestSignature" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify change user signature
-        $this->assertEquals( "TestSignature", $this->getText( SeleniumTestConstants::LINK_START."TestSignature" ));
-        $this->type( "mw-input-nickname", "Test" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-    }
-
-    // Verify change date format
-    public function testChangeDateFormatTimeZone() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_START."Date and time" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->click( "mw-input-date-dmy" );
-        $this->select( "mw-input-timecorrection", "label=Asia/Colombo" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify Date format and time zome saved
-        $this->assertEquals( "Your preferences have been saved.",
-                $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ));
-    }
-
-    // Verify restoring all default settings
-    public function testSetAllDefault() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify restoring all default settings
-        $this->assertEquals( "Restore all default settings",
-                $this->getText( SeleniumTestConstants::LINK_START."Restore all default settings" ));
-
-        $this->click("//*[@id='preferences']/div/a");
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify 'This can not be undone' warning message displayed
-        $this->assertTrue($this->isElementPresent("//input[@value='Restore all default settings']"));
-
-        // Verify 'Restore all default settings' button available
-        $this->assertEquals("You can use this page to reset your preferences to the site defaults. This cannot be undone.",
-                $this->getText("//div[@id='bodyContent']/p"));
-
-        $this->click("//input[@value='Restore all default settings']");
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME  );
-
-        // Verify preferences saved successfully
-        $this->assertEquals("Your preferences have been saved.",
-                $this->getText("//div[@id='bodyContent']/div[4]/strong/p"));
-    }
+       // Verify user information
+       public function testUserInfoDisplay() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify correct username displayed in User Preferences
+               $this->assertEquals( $this->getText( "//li[@id='pt-userpage']/a" ),
+                       $this->getText( "//table[@id='mw-htmlform-info']/tbody/tr[1]/td[2]" ) );
+
+               // Verify existing Signature Displayed correctly
+               $this->assertEquals( $this->selenium->getUser(),
+                       $this->getTable( "mw-htmlform-signature.0.1" ) );
+       }
+
+       // Verify change password
+       public function testChangePassword() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Change password" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpPassword", "12345" );
+               $this->type( "wpNewPassword", "54321" );
+               $this->type( "wpRetype", "54321" );
+               $this->click( "//input[@value='Change password']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->assertEquals( "Preferences", $this->getText( "firstHeading" ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Change password" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpPassword", "54321" );
+               $this->type( "wpNewPassword", "12345" );
+               $this->type( "wpRetype", "12345" );
+               $this->click( "//input[@value='Change password']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Preferences", $this->getText( "firstHeading" ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Change password" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpPassword", "54321" );
+               $this->type( "wpNewPassword", "12345" );
+               $this->type( "wpRetype", "12345" );
+               $this->click( "//input[@value='Change password']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify successful preferences save
+       public function testSuccessfullSave() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "mw-input-realname", "Test User" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify  "Your preferences have been saved." message
+               $this->assertEquals( "Your preferences have been saved.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) );
+               $this->type( "mw-input-realname", "" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify change signature
+       public function testChangeSignature() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "mw-input-nickname", "TestSignature" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify change user signature
+               $this->assertEquals( "TestSignature", $this->getText( SeleniumTestConstants::LINK_START . "TestSignature" ) );
+               $this->type( "mw-input-nickname", "Test" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify change date format
+       public function testChangeDateFormatTimeZone() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . "Date and time" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->click( "mw-input-date-dmy" );
+               $this->select( "mw-input-timecorrection", "label=Asia/Colombo" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify Date format and time zome saved
+               $this->assertEquals( "Your preferences have been saved.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) );
+       }
+
+       // Verify restoring all default settings
+       public function testSetAllDefault() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify restoring all default settings
+               $this->assertEquals( "Restore all default settings",
+                       $this->getText( SeleniumTestConstants::LINK_START . "Restore all default settings" ) );
+
+               $this->click( "//*[@id='preferences']/div/a" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify 'This can not be undone' warning message displayed
+               $this->assertTrue( $this->isElementPresent( "//input[@value='Restore all default settings']" ) );
+
+               // Verify 'Restore all default settings' button available
+               $this->assertEquals( "You can use this page to reset your preferences to the site defaults. This cannot be undone.",
+                       $this->getText( "//div[@id='bodyContent']/p" ) );
+
+               $this->click( "//input[@value='Restore all default settings']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify preferences saved successfully
+               $this->assertEquals( "Your preferences have been saved.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) );
+       }
 }
 
index f1eb833..1e51d80 100644 (file)
@@ -59,7 +59,7 @@ class TestRecorder {
                if ( $success == $total ) {
                        print $this->term->color( 32 ) . "ALL TESTS PASSED!";
                } else {
-                       $failed = $total - $success ;
+                       $failed = $total - $success;
                        print $this->term->color( 31 ) . "$failed tests failed!";
                }
 
@@ -69,10 +69,10 @@ class TestRecorder {
        }
 }
 
-class DbTestPreviewer extends TestRecorder  {
-       protected $lb;      // /< Database load balancer
-       protected $db;      // /< Database connection to the main DB
-       protected $curRun;  // /< run ID number for the current run
+class DbTestPreviewer extends TestRecorder {
+       protected $lb; // /< Database load balancer
+       protected $db; // /< Database connection to the main DB
+       protected $curRun; // /< run ID number for the current run
        protected $prevRun; // /< run ID number for the previous run, if any
        protected $results; // /< Result array
 
@@ -94,9 +94,9 @@ class DbTestPreviewer extends TestRecorder  {
        function start() {
                parent::start();
 
-               if ( ! $this->db->tableExists( 'testrun', __METHOD__ )
-                       || ! $this->db->tableExists( 'testitem', __METHOD__ ) )
-               {
+               if ( !$this->db->tableExists( 'testrun', __METHOD__ )
+                       || !$this->db->tableExists( 'testitem', __METHOD__ )
+               {
                        print "WARNING> `testrun` table not found in database.\n";
                        $this->prevRun = false;
                } else {
@@ -134,8 +134,8 @@ class DbTestPreviewer extends TestRecorder  {
 
                        foreach ( $res as $row ) {
                                if ( !$this->parent->regex
-                                       || preg_match( "/{$this->parent->regex}/i", $row->ti_name ) )
-                               {
+                                       || preg_match( "/{$this->parent->regex}/i", $row->ti_name )
+                               {
                                        $prevResults[$row->ti_name] = $row->ti_success;
                                }
                        }
@@ -195,34 +195,34 @@ class DbTestPreviewer extends TestRecorder  {
        private function getTestStatusInfo( $testname, $after ) {
                // If we're looking at a test that has just been removed, then say when it first appeared.
                if ( $after == 'n' ) {
-                       $changedRun = $this->db->selectField ( 'testitem',
+                       $changedRun = $this->db->selectField( 'testitem',
                                'MIN(ti_run)',
                                array( 'ti_name' => $testname ),
                                __METHOD__ );
-                       $appear = $this->db->selectRow ( 'testrun',
+                       $appear = $this->db->selectRow( 'testrun',
                                array( 'tr_date', 'tr_mw_version' ),
                                array( 'tr_id' => $changedRun ),
                                __METHOD__ );
 
                        return "First recorded appearance: "
-                                  . date( "d-M-Y H:i:s",  strtotime ( $appear->tr_date ) )
-                                  .  ", " . $appear->tr_mw_version;
+                               . date( "d-M-Y H:i:s", strtotime( $appear->tr_date ) )
+                               . ", " . $appear->tr_mw_version;
                }
 
                // Otherwise, this test has previous recorded results.
                // See when this test last had a different result to what we're seeing now.
                $conds = array(
-                       'ti_name'    => $testname,
+                       'ti_name' => $testname,
                        'ti_success' => ( $after == 'f' ? "1" : "0" ) );
 
                if ( $this->curRun ) {
-                       $conds[] = "ti_run != " . $this->db->addQuotes ( $this->curRun );
+                       $conds[] = "ti_run != " . $this->db->addQuotes( $this->curRun );
                }
 
-               $changedRun = $this->db->selectField ( 'testitem', 'MAX(ti_run)', $conds, __METHOD__ );
+               $changedRun = $this->db->selectField( 'testitem', 'MAX(ti_run)', $conds, __METHOD__ );
 
                // If no record of ever having had a different result.
-               if ( is_null ( $changedRun ) ) {
+               if ( is_null( $changedRun ) ) {
                        if ( $after == "f" ) {
                                return "Has never passed";
                        } else {
@@ -233,27 +233,26 @@ class DbTestPreviewer extends TestRecorder  {
                // Otherwise, we're looking at a test whose status has changed.
                // (i.e. it used to work, but now doesn't; or used to fail, but is now fixed.)
                // In this situation, give as much info as we can as to when it changed status.
-               $pre  = $this->db->selectRow ( 'testrun',
+               $pre = $this->db->selectRow( 'testrun',
                        array( 'tr_date', 'tr_mw_version' ),
                        array( 'tr_id' => $changedRun ),
                        __METHOD__ );
-               $post = $this->db->selectRow ( 'testrun',
+               $post = $this->db->selectRow( 'testrun',
                        array( 'tr_date', 'tr_mw_version' ),
-                       array( "tr_id > " . $this->db->addQuotes ( $changedRun ) ),
+                       array( "tr_id > " . $this->db->addQuotes( $changedRun ) ),
                        __METHOD__,
                        array( "LIMIT" => 1, "ORDER BY" => 'tr_id' )
                );
 
                if ( $post ) {
-                       $postDate = date( "d-M-Y H:i:s",  strtotime ( $post->tr_date  ) ) . ", {$post->tr_mw_version}";
+                       $postDate = date( "d-M-Y H:i:s", strtotime( $post->tr_date ) ) . ", {$post->tr_mw_version}";
                } else {
                        $postDate = 'now';
                }
 
                return ( $after == "f" ? "Introduced" : "Fixed" ) . " between "
-                               . date( "d-M-Y H:i:s",  strtotime ( $pre->tr_date ) ) .  ", " . $pre->tr_mw_version
-                               . " and $postDate";
-
+                       . date( "d-M-Y H:i:s", strtotime( $pre->tr_date ) ) . ", " . $pre->tr_mw_version
+                       . " and $postDate";
        }
 
        /**
@@ -264,10 +263,9 @@ class DbTestPreviewer extends TestRecorder  {
                $this->lb->closeAll();
                parent::end();
        }
-
 }
 
-class DbTestRecorder extends DbTestPreviewer  {
+class DbTestRecorder extends DbTestPreviewer {
        var $version;
 
        /**
@@ -277,9 +275,9 @@ class DbTestRecorder extends DbTestPreviewer  {
        function start() {
                $this->db->begin( __METHOD__ );
 
-               if ( ! $this->db->tableExists( 'testrun' )
-                       || ! $this->db->tableExists( 'testitem' ) )
-               {
+               if ( !$this->db->tableExists( 'testrun' )
+                       || !$this->db->tableExists( 'testitem' )
+               {
                        print "WARNING> `testrun` table not found in database. Trying to create table.\n";
                        $this->db->sourceFile( $this->db->patchPath( 'patch-testrun.sql' ) );
                        echo "OK, resuming.\n";
@@ -289,18 +287,18 @@ class DbTestRecorder extends DbTestPreviewer  {
 
                $this->db->insert( 'testrun',
                        array(
-                               'tr_date'        => $this->db->timestamp(),
-                               'tr_mw_version'  => $this->version,
+                               'tr_date' => $this->db->timestamp(),
+                               'tr_mw_version' => $this->version,
                                'tr_php_version' => phpversion(),
-                               'tr_db_version'  => $this->db->getServerVersion(),
-                               'tr_uname'       => php_uname()
+                               'tr_db_version' => $this->db->getServerVersion(),
+                               'tr_uname' => php_uname()
                        ),
                        __METHOD__ );
-                       if ( $this->db->getType() === 'postgres' ) {
-                               $this->curRun = $this->db->currentSequenceValue( 'testrun_id_seq' );
-                       } else {
-                               $this->curRun = $this->db->insertId();
-                       }
+               if ( $this->db->getType() === 'postgres' ) {
+                       $this->curRun = $this->db->currentSequenceValue( 'testrun_id_seq' );
+               } else {
+                       $this->curRun = $this->db->insertId();
+               }
        }
 
        /**
@@ -314,8 +312,8 @@ class DbTestRecorder extends DbTestPreviewer  {
 
                $this->db->insert( 'testitem',
                        array(
-                               'ti_run'     => $this->curRun,
-                               'ti_name'    => $test,
+                               'ti_run' => $this->curRun,
+                               'ti_name' => $test,
                                'ti_success' => $result ? 1 : 0,
                        ),
                        __METHOD__ );
@@ -328,7 +326,8 @@ class TestFileIterator implements Iterator {
        private $parserTest; /* An instance of ParserTest (parserTests.php) or MediaWikiParserTest (phpunit) */
        private $index = 0;
        private $test;
-       private $section = null; /** String|null: current test section being analyzed */
+       private $section = null;
+       /** String|null: current test section being analyzed */
        private $sectionData = array();
        private $lineNum;
        private $eof;
@@ -395,7 +394,7 @@ class TestFileIterator implements Iterator {
                                $this->section = strtolower( $matches[1] );
 
                                if ( $this->section == 'endarticle' ) {
-                                       $this->checkSection( 'text'    );
+                                       $this->checkSection( 'text' );
                                        $this->checkSection( 'article' );
 
                                        $this->parserTest->addArticle( ParserTest::chomp( $this->sectionData['article'] ), $this->sectionData['text'], $this->lineNum );
@@ -438,8 +437,8 @@ class TestFileIterator implements Iterator {
                                }
 
                                if ( $this->section == 'end' ) {
-                                       $this->checkSection( 'test'   );
-                                       $this->checkSection( 'input'  );
+                                       $this->checkSection( 'test' );
+                                       $this->checkSection( 'input' );
                                        $this->checkSection( 'result' );
 
                                        if ( !isset( $this->sectionData['options'] ) ) {
@@ -451,7 +450,8 @@ class TestFileIterator implements Iterator {
                                        }
 
                                        if ( ( ( preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) && !$this->parserTest->runDisabled )
-                                                        || !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] ) )  ) {
+                                               || !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] ) )
+                                       ) {
                                                # disabled test
                                                $this->clearSection();
 
@@ -464,17 +464,17 @@ class TestFileIterator implements Iterator {
                                        # We are really going to run the test, run pending hooks and hooks function
                                        wfDebug( __METHOD__ . " unleashing delayed test for: {$this->sectionData['test']}" );
                                        $hooksResult = $delayedParserTest->unleash( $this->parserTest );
-                                       if( !$hooksResult ) {
+                                       if ( !$hooksResult ) {
                                                # Some hook reported an issue. Abort.
                                                return false;
                                        }
 
                                        $this->test = array(
-                                               'test'    => ParserTest::chomp( $this->sectionData['test']    ),
-                                               'input'   => ParserTest::chomp( $this->sectionData['input']   ),
-                                               'result'  => ParserTest::chomp( $this->sectionData['result']  ),
+                                               'test' => ParserTest::chomp( $this->sectionData['test'] ),
+                                               'input' => ParserTest::chomp( $this->sectionData['input'] ),
+                                               'result' => ParserTest::chomp( $this->sectionData['result'] ),
                                                'options' => ParserTest::chomp( $this->sectionData['options'] ),
-                                               'config'  => ParserTest::chomp( $this->sectionData['config']  ),
+                                               'config' => ParserTest::chomp( $this->sectionData['config'] ),
                                        );
 
                                        return true;
@@ -516,18 +516,18 @@ class TestFileIterator implements Iterator {
         * @param $token String: expected token that should have been mentionned before closing this section
         */
        private function checkSection( $token ) {
-               if( is_null( $this->section ) ) {
+               if ( is_null( $this->section ) ) {
                        throw new MWException( __METHOD__ . " can not verify a null section!\n" );
                }
 
-               if( !isset($this->sectionData[$token]) ) {
+               if ( !isset( $this->sectionData[$token] ) ) {
                        throw new MWException( sprintf(
                                "'%s' without '%s' at line %s of %s\n",
                                $this->section,
                                $token,
                                $this->lineNum,
                                $this->file
-                       ));
+                       ) );
                }
                return true;
        }
@@ -551,7 +551,7 @@ class DelayedParserTest {
         * Call to this will erase any hooks function that were pending.
         */
        public function reset() {
-               $this->hooks   = array();
+               $this->hooks = array();
                $this->fnHooks = array();
        }
 
@@ -560,23 +560,22 @@ class DelayedParserTest {
         * Should be the case if we found the parserTest is not disabled
         */
        public function unleash( &$parserTest ) {
-               if( !($parserTest instanceof ParserTest || $parserTest instanceof NewParserTest
-               ) ) {
+               if ( !( $parserTest instanceof ParserTest || $parserTest instanceof NewParserTest )     ) {
                        throw new MWException( __METHOD__ . " must be passed an instance of ParserTest or NewParserTest classes\n" );
                }
 
                # Trigger delayed hooks. Any failure will make us abort
-               foreach( $this->hooks as $hook ) {
+               foreach ( $this->hooks as $hook ) {
                        $ret = $parserTest->requireHook( $hook );
-                       if( !$ret ) {
+                       if ( !$ret ) {
                                return false;
                        }
                }
 
                # Trigger delayed function hooks. Any failure will make us abort
-               foreach( $this->fnHooks as $fnHook ) {
+               foreach ( $this->fnHooks as $fnHook ) {
                        $ret = $parserTest->requireFunctionHook( $fnHook );
-                       if( !$ret ) {
+                       if ( !$ret ) {
                                return false;
                        }
                }
@@ -592,6 +591,7 @@ class DelayedParserTest {
        public function requireHook( $hook ) {
                $this->hooks[] = $hook;
        }
+
        /**
         * Similar to ParserTest object but does not run anything
         * Use unleash() to really execute the hook function
index f59ee0f..ede30e6 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -170,11 +170,11 @@ function wfStreamThumb( array $params ) {
 
        // Check the source file storage path
        if ( !$img->exists() ) {
-               wfThumbError( 404, 'The source file for the specified thumbnail does not exist.' );
+               wfThumbError( 404, "The source file '$fileName' does not exist." );
                wfProfileOut( __METHOD__ );
                return;
        } elseif ( $img->getPath() === false ) {
-               wfThumbError( 500, 'The source file is not locally accessible.' );
+               wfThumbError( 500, "The source file '$fileName' is not locally accessible." );
                wfProfileOut( __METHOD__ );
                return;
        }
@@ -224,7 +224,7 @@ function wfStreamThumb( array $params ) {
                        $response->header( 'Location: ' .
                                wfExpandUrl( $img->getThumbUrl( $thumbName ), PROTO_CURRENT ) );
                        $response->header( 'Expires: ' .
-                               gmdate( 'D, d M Y H:i:s', time() + 7*86400 ) . ' GMT' );
+                               gmdate( 'D, d M Y H:i:s', time() + 7 * 86400 ) . ' GMT' );
                        if ( $wgVaryOnXFP ) {
                                $varyHeader[] = 'X-Forwarded-Proto';
                        }
@@ -364,7 +364,7 @@ function wfThumbError( $status, $msg ) {
                $hostname = htmlspecialchars( wfHostname() );
                $debug = "<!-- $url -->\n<!-- $hostname -->\n";
        } else {
-               $debug = "";
+               $debug = '';
        }
        echo <<<EOT
 <html><head><title>Error generating thumbnail</title></head>